Skip to main content
The webhook subscriptions API lets each organization register one or more HTTPS endpoints that receive signed, retried webhook deliveries for mapping events. This is the API behind the Developers → Webhooks page in the app. For a conceptual overview see Webhooks Overview. For signature verification see Verifying signatures. For delivery semantics see Retries and delivery.
All endpoints require a bearer token in the Authorization header. The two new event types (MAPPING_ERROR_RESOLVED, INVENTORY_DUPLICATE_RESOLVED) require a Pro or above plan.

POST /api/v1/webhook-subscriptions

Create a subscription. Returns the freshly generated signing secret exactly once — store it before responding.

Request body

name
string
Human-readable label.
webhookUrl
string
required
HTTPS endpoint that will receive deliveries. Must use https://, must resolve to a non-private IP outside of dev.
events
string[]
required
Array of event types this subscription should receive. One or more of:
  • MAPPING_COMPLETED — all plans
  • MAPPING_ERROR_RESOLVED — Pro and above
  • INVENTORY_DUPLICATE_RESOLVED — Pro and above
apiKeyName
string
Header name attached to every request (e.g., X-API-Key).
apiKeyValue
string
Value for apiKeyName. Stored encrypted at rest.
additionalHeaders
object
Extra headers as a key-value map.
status
string
default:"ACTIVE"
ACTIVE or INACTIVE. Inactive subscriptions don’t receive deliveries.

Response

id
string
Subscription UUID.
signingSecret
string
Only returned on this initial response. Store it now; we won’t show it again. Used for HMAC verification — see Verifying signatures.
signingSecretMasked
string
Masked form for UI display (e.g., whsec_••••5d4d). Returned on every read.
events
string[]
Echoed event subscriptions.
status
string
ACTIVE or INACTIVE.
deactivatedReason
string
PLAN_DOWNGRADE if auto-disabled by a plan downgrade. Otherwise null.

Example

curl -X POST https://api.mapping.travel/api/v1/webhook-subscriptions \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Inventory ops",
    "webhookUrl": "https://yourapp.com/webhooks/mapping",
    "events": ["MAPPING_ERROR_RESOLVED", "INVENTORY_DUPLICATE_RESOLVED"],
    "status": "ACTIVE"
  }'
{
  "id": "sub_…",
  "organizationId": "org_…",
  "name": "Inventory ops",
  "webhookUrl": "https://yourapp.com/webhooks/mapping",
  "events": ["MAPPING_ERROR_RESOLVED", "INVENTORY_DUPLICATE_RESOLVED"],
  "status": "ACTIVE",
  "deactivatedReason": null,
  "signingSecret": "whsec_e1c5d3a0…",
  "signingSecretMasked": "whsec_••••3a0e",
  "createdAt": "2026-06-02T00:00:00Z",
  "updatedAt": "2026-06-02T00:00:00Z"
}

GET /api/v1/webhook-subscriptions

List subscriptions for the organization. signingSecret is never returned — only signingSecretMasked.
activeOnly
boolean
default:"false"
When true, only ACTIVE subscriptions are returned.
curl "https://api.mapping.travel/api/v1/webhook-subscriptions?activeOnly=true" \
  -H "Authorization: Bearer <token>"

GET /api/v1/webhook-subscriptions/

Retrieve one subscription. signingSecret is masked.

PUT /api/v1/webhook-subscriptions/

Replace the subscription. Same body schema as create. Returns 403 if any event in events is not permitted for the org’s current plan.

DELETE /api/v1/webhook-subscriptions/

Permanently delete the subscription and its delivery history. Returns 204 No Content.

POST /api/v1/webhook-subscriptions//rotate-secret

Generate a new signing secret and invalidate the old one. Returns the new secret once.
curl -X POST https://api.mapping.travel/api/v1/webhook-subscriptions/<id>/rotate-secret \
  -H "Authorization: Bearer <token>"
{
  "id": "sub_…",
  "signingSecret": "whsec_<new value>"
}

GET /api/v1/webhook-subscriptions//deliveries

Recent delivery attempts for inspection and debugging.
limit
integer
default:"50"
Max rows. Capped at 200.

Response

deliveries
object[]

POST /api/v1/webhook-subscriptions//test

Enqueue a synthetic webhook.test event for the subscription. Useful to confirm your endpoint receives and verifies signed payloads end-to-end.
curl -X POST https://api.mapping.travel/api/v1/webhook-subscriptions/<id>/test \
  -H "Authorization: Bearer <token>"
{ "deliveryId": "del_…" }
The synthetic event flows through the same scheduler + retry pipeline as real events. Check /deliveries for the result within ~30 seconds.

Error codes

StatusCodeWhen
400BAD_REQUESTInvalid URL, no events, quota exceeded, etc.
401UNAUTHORIZEDMissing or invalid bearer token.
403FORBIDDENAt least one requested event requires a plan upgrade. Body includes the offending event names.
404NOT_FOUNDSubscription doesn’t exist or belongs to a different org.

Operational guards

  • Quota: 10 active subscriptions per organization.
  • URL safety: https:// only; loopback and RFC 1918 hosts are rejected outside dev.
  • Payload cap: 64 KB. Larger payloads get { truncated: true, dataRef } and the data is queryable via API.
  • Backpressure: when PENDING deliveries for one org exceeds 10,000, new events for that org are dropped silently and an hourly audit entry records the drop.