POST /v1/webhooks
Subscribe a URL to events
Subscribe a URL to events
Creates a subscription for deal.stage_changed, payment.received, document.signed, lead.created and shipment.updated. The response contains the signing secret ONCE. Not idempotent by design (the secret must not be stored for replay): list subscriptions before retrying. At most 20 subscriptions per tenant. Requires scope write:deals. Every delivery is a POST with a JSON body and the headers X-Signature: t=<unix-seconds>,v1=<hex> and X-Event-Id: <uuid>. v1 = hex(HMAC_SHA256(secret, ${t}.${rawBody})) where secret is the whsec_... value returned when the subscription was created and rawBody is the exact request body bytes (do not re-serialize the JSON). Reject the request if |now - t| > 300 s (replay protection) or if no v1 value matches (compare in constant time). During secret rotation several v1= values can be present: accept if any matches. Answer with any 2xx within 8 seconds. Other statuses, timeouts and network errors are retried with exponential backoff (1, 2, 4 ... minutes, up to 6 attempts) and then marked dead; X-Event-Id (= body.id) is stable across retries: use it to deduplicate. Only https URLs on public hosts are accepted. The body is { id, type, tenantId, createdAt, data } (plus informational fields); data carries identifiers and public fields only (no margins, no personal data). A ready-made verifier is exported by the SDK: import { verifyWebhookSignature } from "@importos/sdk/webhooks".
- Автентифікація: заголовок
Authorization: Bearer rv_live_...(API-ключі та scopes) - Потрібний scope:
write:deals
openapi.json) і подається англійською, як у самому API.Тіло запиту
| Поле | Тип | Обов’язк. | Опис |
|---|---|---|---|
url | string (uri) | так | HTTPS endpoint that receives POST requests. Private/internal hosts are rejected. |
events | "deal.stage_changed" | "payment.received" | "document.signed" | "lead.created" | "shipment.updated"[] | так | Events to receive. |
description | string | null | ні |
Відповіді
201
The subscription and its secret (shown once).
application/json · Схема: WebhookCreated
| Поле | Тип | Обов’язк. | Опис |
|---|---|---|---|
webhook | object | так | |
webhook.id | string (uuid) | так | |
webhook.url | string | так | |
webhook.description | string | null | так | |
webhook.events | string[] | так | |
webhook.enabled | boolean | так | |
webhook.secretPrefix | string | null | так | First characters of the signing secret, to tell secrets apart. The full secret is never shown again. |
webhook.failureCount | integer | так | |
webhook.lastSuccessAt | string | null | так | ISO 8601 date-time (UTC). |
webhook.lastFailureAt | string | null | так | ISO 8601 date-time (UTC). |
secret | string | так | Signing secret (whsec_...). Shown ONCE, store it now. Use it to verify X-Signature. |
400
Invalid request parameters or body (code validation_error).
application/problem+json · Схема: Problem
401
Missing, malformed, unknown, revoked or expired API key (code unauthorized).
application/problem+json · Схема: Problem
403
The API key lacks the scope required by this endpoint (code insufficient_scope).
application/problem+json · Схема: Problem
409
Subscription limit reached (webhook_limit).
application/problem+json · Схема: Problem
422
The URL is not acceptable: not https, private host, credentials in URL (webhook_url_rejected).
application/problem+json · Схема: Problem
429
Rate limit exceeded for the tenant plan (code rate_limited). Wait Retry-After seconds.
application/problem+json · Схема: Problem