Create webhook subscription
Create a webhook subscription.
Webhooks
/api/v1/scent/webhooksThe response’s secret is shown EXACTLY ONCE — store it immediately. Up to 5 active
subscriptions per partner (BUSINESS_WEBHOOK_SUBSCRIPTION_LIMIT above that). See the
Webhooks guide for the full HMAC verification walkthrough.
Body parameters
urlstring (uri)RequiredMust be a public HTTPS URL — private/loopback/link-local addresses are rejected (SSRF guard), re-checked on every delivery attempt.
eventTypesarray of string (enum)RequiredheadersobjectOptional partner-defined outbound headers (name→value), added to every delivery ALONGSIDE the always-on HMAC signature. WRITE-ONLY — never returned by any read. At most 10 entries; each name up to 128 characters and each value up to 2048 characters, no CR/LF in either. Content-Type, Host, Content-Length, and the fleet’s own X-Linra-Signature/ X-Linra-Timestamp header names are reserved and rejected.
Response
subscription.idstring (uuid)subscription.urlstring (uri)subscription.eventTypesarray of stringsubscription.isActivebooleansubscription.lastDeliveryAtstring (date-time)subscription.lastDeliveryStatusstring (enum)Null until the first delivery attempt. DeadLettered means every retry was exhausted — see the Webhooks guide for the retry schedule.
subscription.createdAtstring (date-time)secretstringShown exactly once — store it now. Used as the HMAC signing key.
Other responses
400Request validation failed (VALIDATION_ERRORS, with details.errors), or the webhook URL is not allowed — not a valid absolute https URL, its host does not resolve, or it resolves to a private/non-routable address (VALIDATION_WEBHOOK_URL_UNSAFE, details.reason says which).401No bearer token (UNAUTHORIZED_MISSING_TOKEN), an invalid token (UNAUTHORIZED_INVALID_TOKEN) or an expired one (UNAUTHORIZED_TOKEN_EXPIRED — mint a new token). UPSTREAM_AUTH_FAILED is different: a dependent service refused the Gateway itself. That is a server-side fault — retry later and do NOT re-mint your token. See the Errors guide.403The route is not available to your credential (FORBIDDEN).404No API route matches this path (NOT_FOUND_ROUTE). A missing resource on a real route returns that service’s own NOT_FOUND_* code instead.415The request body is not sent as application/json (UNSUPPORTED_MEDIA_TYPE).422Active-subscription cap exceeded.429Too many requests — see the Rate limits guide. Retry after the Retry-After header (seconds).502A dependent service returned an invalid response (BAD_GATEWAY). Retry with backoff.503The service is temporarily unavailable (SERVICE_UNAVAILABLE). Retry with backoff.504A dependent service did not respond in time (GATEWAY_TIMEOUT). Retry with backoff.curl --request POST \ --url https://api-omni.linra.net/api/v1/scent/webhooks \ --header 'Authorization: Bearer $TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "url": "https://your-integration.example.com/webhooks/linra", "eventTypes": [ "order.completed" ], "headers": { "Authorization": "Bearer your-own-inbound-token" } }'const res = await fetch('https://api-omni.linra.net/api/v1/scent/webhooks', { method: 'POST', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ url: 'https://your-integration.example.com/webhooks/linra', eventTypes: [ 'order.completed' ], headers: { Authorization: 'Bearer your-own-inbound-token' } }),});const { payload } = await res.json();var response = await httpClient.PostAsJsonAsync( "https://api-omni.linra.net/api/v1/scent/webhooks", new { url = "https://your-integration.example.com/webhooks/linra", eventTypes = new[] { "order.completed" }, headers = new { Authorization = "Bearer your-own-inbound-token" } });
var envelope = await response.Content.ReadFromJsonAsync<ApiResponse<WebhookSubscriptionCreatedResponse>>();Response
{ "state": "SUCCESS", "payload": { "subscription": { "id": "5b1e3a1c-9d2e-4f3a-8b1c-9f0a2e3d4c5b", "url": "https://your-integration.example.com/webhooks/linra", "eventTypes": [ "string" ], "isActive": true, "lastDeliveryAt": "2026-08-22T09:14:03Z", "lastDeliveryStatus": "Success", "createdAt": "2026-08-22T09:14:03Z" }, "secret": "string" }, "details": null}
