Skip to main content
All paths below are relative to /m2m/v1. Send Authorization: Bearer <key>. Tenant identity comes from the key.

Create a subscription

Requires webhooks:write and the read permissions for every event type selected.
Send this body to POST /webhooks. Save the returned secret; it is returned only on creation or rotation. GET /webhooks lists subscriptions; GET/PATCH/DELETE /webhooks/{subscriptionId} reads, updates, or removes one. PATCH accepts url, events, and active. Rotate with POST /webhooks/{subscriptionId}/rotate-secret. The envelope contains eventId, type, schemaVersion:"1.0", tenantId, occurredAt, and data. Fetch content through the scoped GET APIs. Internal system/tool turns and playground messages are excluded.

Verify signatures

Headers: X-Visito-Event-Id and X-Visito-Signature: t=<unix-seconds>,v1=<hex-hmac>. Compute HMAC-SHA256 over timestamp + "." + rawBody using the subscription secret. Compare using constant-time comparison, reject timestamps outside a five-minute tolerance, and deduplicate on eventId. Verify the raw bytes before JSON parsing.

Delivery and recovery

Delivery is at least once, with no ordering guarantee. Return any 2xx after durably accepting the event. Redirects are not followed. Destinations must be public HTTPS on port 443 with public IPv4 DNS answers; local/private/reserved addresses and IPv6-only destinations are unsupported. DNS is rechecked and the connection pinned on every attempt. Attempts have a 10-second deadline. Failures retry after 1 minute, 5 minutes, 30 minutes, 2 hours, 8 hours, and 24 hours (seven attempts total). Inspect GET /webhooks/{subscriptionId}/deliveries or GET /webhooks/{subscriptionId}/deliveries/{deliveryId} with webhooks:read. Retry an exhausted failure with POST /webhooks/{subscriptionId}/deliveries/{deliveryId}/retry; this starts a new attempt cycle with the same event ID. Metadata is retained for 30 days after completion. Revoked/expired/downscoped owning keys and disabled/deleted subscriptions cancel pending delivery. An already in-flight HTTP request may finish. Re-enabling does not replay canceled events. Updating a subscription associates it with the calling credential and requires the event read scopes again. Secret rotation takes effect immediately for future attempts. For an automatic reply integration, act only on inbound message.created events. Persist the event ID and use a stable reply Idempotency-Key to prevent duplicate replies and outbound webhook loops.