Agent skill
Trendyol Webhooks Skill
Receive and authenticate Trendyol seller order package webhooks. Use when setting up a Trendyol webhook endpoint, verifying the x-api-key header, debugging 401s, or handling package statuses like CREATED, SHIPPED, DELIVERED, CANCELLED and RETURNED.
Install this skill
npx skills add hookdeck/webhook-skills --skill trendyol-webhooks
Trendyol (the Turkish marketplace) sends a webhook to your seller endpoint when an order package changes status. Webhooks are not signed. When you create the webhook with authenticationType API_KEY, Trendyol sends the webhook's apiKey as plain text in the x-api-key header on every request, and your endpoint authenticates the request by comparing the whole header value with the key you stored.
Choose API key authentication (authenticationType API_KEY) when you create the Trendyol webhook.
Trendyol also offers BASIC_AUTHENTICATION, which Hookdeck's Trendyol source does not cover; this skill covers only API_KEY.
When to Use This Skill
- How do I receive Trendyol order package webhooks?
- How do I verify the
x-api-keyheader on a Trendyol webhook? - Does Trendyol sign webhook payloads? (No: use the shared API key)
- How do I handle
CREATED,SHIPPED,DELIVERED,CANCELLEDorRETURNEDpackages? - Why does my Trendyol webhook endpoint return 401, or why does Trendyol keep re-sending requests?
Verification (core)
const crypto = require('crypto');
// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(a, b) {
const ha = crypto.createHash('sha256').update(String(a)).digest();
const hb = crypto.createHash('sha256').update(String(b)).digest();
return crypto.timingSafeEqual(ha, hb);
}
function verifyTrendyolRequest(headers, secret = process.env.TRENDYOL_WEBHOOK_SECRET) {
if (!secret) return false; // never accept when unconfigured
const received = headers['x-api-key']; // the apiKey, sent as plain text
return typeof received === 'string' && received !== '' && safeEqual(received, secret);
}
- Header:
x-api-key: <apiKey>. Compare the whole value withTRENDYOL_WEBHOOK_SECRET; there is no prefix, HMAC or timestamp. Look the header up case-insensitively (Node lowercases it already). - Return
401for a missing or wrong key,400for a body that isn't a JSON object with acontentarray,200once handled. - Read the body raw (
express.raw({ type: '*/*' })) and authenticate before parsing it. - In Python use
hmac.compare_digeston bytes (a.encode(),b.encode()); passingstrraisesTypeErroron non-ASCII input. - A static shared credential authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Serve the endpoint over HTTPS and rotate the
apiKey(update the webhook) if it leaks.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Event Types
Trendyol sends the full order package whatever the status. The body is a page of packages, { "content": [ ... ] }; loop over content[] and dispatch on each package's status. The documentation lists the statuses in upper case but the example payload writes them in Title case ("status": "Delivered"), so compare case-insensitively.
| Status | Package is |
|---|---|
CREATED | Created from a new order |
PICKING | Being picked by the seller |
INVOICED | Invoiced |
SHIPPED | Handed to the carrier |
DELIVERED | Delivered to the customer |
UNDELIVERED | Not delivered |
CANCELLED | Cancelled |
RETURNED | Returned |
UNSUPPLIED | Marked as not supplied by the seller |
AWAITING | Awaiting |
UNPACKED | Unpacked |
AT_COLLECTION_POINT | Waiting at a collection point |
VERIFIED | Verified |
Requests are POST with a JSON body. If your endpoint fails, Trendyol re-sends every 5 minutes until it succeeds and eventually deactivates the webhook, so handlers must be idempotent.
Environment Variables
TRENDYOL_WEBHOOK_SECRET=your-webhook-api-key # the apiKey set when creating the webhook
Local Development
Trendyol can't reach localhost. Tunnel with the Hookdeck CLI (no account required):
npx hookdeck-cli listen 3000 trendyol --path /webhooks/trendyol
Use the printed URL as the webhook URL (Trendyol rejects URLs containing "Trendyol", "Dolap" or "Localhost").
Resources
- references/overview.md - What Trendyol webhooks are, statuses and payload shape
- references/setup.md - Create the webhook with an API key
- references/verification.md - Key check details, gotchas, debugging 401s
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests