Skip to main content
Everything you can do under Account → Webhooks in the Dashboard, you can also do from the API at https://api.cloudtalk.io/v1/webhooks. Endpoints created in the API and in the Dashboard are the same endpoints: each place sees and manages the other’s. Use it to provision webhooks from your own onboarding flow, keep endpoint configuration in code, or let an integration register its own endpoint.
Webhooks are available on the Essential plan and higher. Requests authenticate with an API key, like the rest of the CloudTalk API. API keys can only be created by Admins, the same role that manages webhooks in the Dashboard.

Quick start

1

Pick the event types

List what you can subscribe to:
Add ?include=schema to get the JSON Schema of every event’s body.
2

Create the endpoint and store its secret

Store secret in your handler’s configuration and verify signatures on every delivery. You can read it again later with Get the signing secret.
3

Send a test event

The answer is 202 with a deliveryId. The test payload has the real structure of the event with placeholder values.
4

Check that it arrived

You get the payload that was sent and every attempt, with the HTTP status your server answered and the first 4 KB of its response. When no HTTP response came back (connection refused, TLS failure, timeout), the attempt shows status code 0 and a fixed message instead of a body. A delivery shows up from its first attempt, usually within seconds of the test.

Operations

List operations return { "data": [...], "pagination": { "limit": 20, "next": "..." }, "requestId": "..." }. Set ?limit= (default 20, at most 100) and pass pagination.next as ?cursor= to get the next page; next is null on the last page.

Endpoints

URL. It must be https:// and point at a public host whose name ends in a public top-level domain (.com, .io, .co.uk and so on). Private, loopback and other non-public addresses, internal host names and non-ASCII host names are rejected with 422 WEBHOOKS.INVALID_URL; send an internationalized domain in its punycode (xn--) form. The URL comes back as stored, which may differ slightly from what you sent: the host lowercased, a bare host with a trailing /. Event types. eventTypes lists the types the endpoint receives. Omit it, or send null, to receive every event type, including ones added later. An empty list is rejected. Responses list the types sorted. Status. Every endpoint reports one of: Updating. PATCH changes only the fields you send: url, description, eventTypes, enabled. null is accepted only for eventTypes (every event type). Deleting is permanent: the endpoint, its signing secret and its delivery history are removed, and delivery stops immediately. Limit. A company can have up to 50 endpoints, Dashboard-created ones included. Creating one more answers 409 WEBHOOKS.ENDPOINT_LIMIT_REACHED.

Safe retries with Idempotency-Key

A network error on POST /webhooks/endpoints leaves you not knowing whether the endpoint was created. Send an Idempotency-Key header (any text up to 255 characters) and retry with the same key and the same body:
  • the endpoint already exists: you get it back with 201 and its secret, even if the company has meanwhile reached the 50-endpoint limit;
  • the same key with a different body: 422 IDEMPOTENCY.KEY_REUSED (a key names one create);
  • after the endpoint is deleted, the same key creates a new one.

Signing secrets

Rotate the signing secret returns the new secret and previousSecretExpiresAt. Until that time, 24 hours after the rotation, every delivery is signed with both the old and the new secret, so you can roll the new one out to your handlers without dropping events. After it, only the new secret signs. The create response is the only time the secret is part of the endpoint object.

Test events and the delivery log

  • A test event must be a type the endpoint receives (422 WEBHOOKS.EVENT_TYPE_NOT_SUBSCRIBED otherwise), and the endpoint must be enabled (409 WEBHOOKS.ENDPOINT_DISABLED).
  • deliveryId is the same value as the svix-id header on the request your endpoint received, so you can look up a delivery straight from your own logs.
  • Delivery status is succeeded, retrying (an attempt failed and another is scheduled at nextAttemptAt), failed (no retry left), pending or canceled. Filter the list with ?status=succeeded or ?status=failed, ?eventType= (comma-separated) and ?since= / ?until= (RFC 3339).
  • Payloads are kept for 30 days. Older deliveries still appear, with payload: null.
  • Retry a delivery works only for a delivery the endpoint actually received.

Limits and errors

  • The webhooks API allows 60 requests per minute per company. This is its own budget: it does not consume the core API’s 60 requests per minute, and core API calls do not consume it. Over it you get 429 from the gateway with X-CloudTalkAPI-Limit, X-CloudTalkAPI-Remaining and X-CloudTalkAPI-ResetTime, and no error body.
  • Test events and retries together allow 10 per minute per company. Their responses carry X-CloudTalkAPI-Send-Limit, X-CloudTalkAPI-Send-Remaining and X-CloudTalkAPI-Send-ResetTime (a Unix timestamp, like the API-wide X-CloudTalkAPI-ResetTime); over the limit you get 429 RATE_LIMIT.EXCEEDED with Retry-After (seconds).
  • Request bodies must be sent as Content-Type: application/json, otherwise 415 UNSUPPORTED_MEDIA_TYPE.
  • Paths are case-sensitive: /webhooks/endpoints, not /Webhooks/Endpoints.
  • A request that takes longer than 10 seconds answers 504 WEBHOOKS.UPSTREAM_TIMEOUT; it is safe to retry (with the same Idempotency-Key for a create).
Errors share one shape:
Branch on code; message is for people and can change. Quote requestId when you contact support.