Prerequisites
- An HTTPS endpoint reachable from the public internet (not
localhostor behind a firewall). - A place to securely store the signing secret shown once at creation time.
Create via the dashboard
- Open Developers → Delivery destinations → New destination.
- Choose Webhook as the type.
- Paste your endpoint URL and select the events to subscribe to.
- Click Create. Copy the signing secret — it is shown only once and cannot be retrieved later.
Create via API
Endpoint requirements
Your HTTP endpoint must:- Accept
POSTrequests over HTTPS only. Plain HTTP is rejected. - Return a
2xxstatus code within 30 seconds. Anything else (3xx, 4xx, 5xx, or timeout) is treated as a failure and retried. - Tolerate duplicate deliveries — deduplicate on the
eventIdfield, which is stable across all retry attempts. - Verify the
X-Webhook-Signatureheader on every request. See Verifying signatures.
Request headers
Every delivery includes:| Header | Example | Description |
|---|---|---|
X-Webhook-Signature | t=1717250400,v1=abc123… | HMAC-SHA256 signature + timestamp |
X-Webhook-Event | mapping.completed | The event type |
X-Webhook-Delivery | del_01HZ… | Unique delivery attempt ID |
Content-Type | application/json | Always application/json |
Payload envelope
eventId — not id — as your idempotency key, since id changes on each retry attempt.
Verifying the signature
See the full verification guide with code in Node, Python, Kotlin, and Go: Verifying signatures. Quick summary: parset= and v1= from X-Webhook-Signature, reject if the timestamp is more than ±5 minutes from your clock, then verify HMAC_SHA256(secret, "{t}.{raw_body}") in constant time.
Rotating the signing secret
Troubleshooting
4xx responses — endpoint rejecting the request
4xx responses — endpoint rejecting the request
A
4xx means your server received the request but rejected it. Common causes:- 401 / 403: Your server is checking an auth header or secret that doesn’t match. Verify you’re reading the signing secret from the right environment variable.
- 404: The path in your webhook URL doesn’t exist. Check your route configuration.
- 422 / 400: Your server parsed the body and rejected it. Confirm you are using the raw request body (not re-parsed JSON) when verifying the signature.
Mapping.Travel retries 4xx responses the same as 5xx. After 4 failed attempts the delivery is marked
DEAD. Fix the endpoint and use the Test button to send a fresh payload.5xx responses — server errors
5xx responses — server errors
A
5xx means your server accepted the request but encountered an internal error. Check your application logs for exceptions. The delivery will be retried at 1m, 5m, and 30m intervals.Network errors — no response at all
Network errors — no response at all
If Mapping.Travel cannot reach your endpoint (connection refused, DNS failure, or timeout > 30s), the delivery is retried with the same schedule. Verify:
- The URL is publicly reachable (not behind a VPN or firewall that blocks our IPs).
- Your TLS certificate is valid and not expired.
- Your server is not rate-limiting our source IPs.
Signature verification failing
Signature verification failing
Most common cause: middleware is re-parsing the JSON body before it reaches your handler, altering the bytes used to compute the signature. Use a raw-body middleware specifically for the webhook path. See Verifying signatures for framework-specific tips.