/m2m/v1. Send Authorization: Bearer <key>. Tenant identity comes from the key.
Workspace admins can also create and manage webhooks in the dashboard using their normal login, without an API key. Capture Data action webhooks are configured separately under Actions.
Create a subscription
Requireswebhooks:write and the read permissions for every event type selected.
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. Create also accepts an optional name; PATCH accepts name, 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). InspectGET /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.
Authorization and dashboard management
API-created subscriptions are credential-bound: revoked, expired, or downscoped owning keys cancel pending delivery. Older records without an authorization mode retain this behavior. Updating a credential-bound subscription through the API associates it with the calling credential and requires the event read scopes again. Dashboard-created subscriptions are tenant-managed. Delivery does not depend on the creator’s session, continuing membership, or an API key. Current workspace admins manage them. API clients may mutate these subscriptions with the required webhook scopes plus event-read permissions for all affected events; this preserves tenant management and does not attach the calling credential. Ordinary request bodies cannot choose or change authorization mode. Admins can explicitly Transfer to dashboard management after confirming that later credential revocation will no longer stop delivery. Endpoint, secret, event IDs, and delivery records are preserved; actor and timestamp are audited. Canceled deliveries are not replayed. Reverse transfer is not available. Disabling or deleting either type cancels queued deliveries. An already in-flight HTTP request may finish. Re-enabling does not replay canceled events. Secret rotation takes effect immediately for future attempts. The dashboard provides attempt logs, configuration activity, and synthetic test events. Tests use the version 1.0 envelope with additivetest:true, target one subscription through normal delivery, and create no business records. They require an active endpoint, tenant enrollment, and a ready worker, with a one-test-per-endpoint-per-minute limit. See the illustrated guide.
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.
Tickets and escalations
tickets:read discovers both types; tickets:write manages general tickets. conversations:handoffs:create initiates escalation; escalation management retains conversations:handoffs:write and assignment retains conversations:assignment:write. Context reads and sending permissions remain separate. Existing credentials and OAuth grants retain their exact scopes; explicitly grant new access. See the contract and agent workflow.
ticket.created and ticket.updated require tickets:read. They contain IDs, type, revision and change action, without transcripts or notes. Deduplicate event IDs, handle out-of-order delivery and reread the item. Existing retries, revocation and recovery apply.
Commerce ticket opt-in
SetincludeCommerce=true when creating or updating a subscription to receive Commerce-backed ticket.created and ticket.updated events. Default false preserves existing clients. Events contain IDs/revision/cycle/mode, never full purchase evidence or fabricated conversation IDs. Opt-in, scope revocation and current Stripe mode are rechecked before delivery. Existing retry, recovery and duplicate-delivery semantics apply.