Delivery contract
Apply the following handling sequence:- Preserve the raw request body and the
telnyx-timestampandtelnyx-signature-ed25519headers. - Verify the signature before trusting or queuing the event.
- Record the event identifier and the product-specific correlation identifiers.
- Return a
2xxresponse promptly. Perform network calls and other long-running work asynchronously. - Process the queued event idempotently. Treat the event identifier as the deduplication key where the product envelope supplies one.
occurred_at and product resource identifiers where those fields exist; do not use arrival time as authoritative event order.
Primary URL, failover URL, timeout, and retry behavior are configured and documented by product. A failed primary delivery can be retried or sent to a configured failover URL. Do not assume one retry schedule applies to every Telnyx product.
Webhook Setup Options
Choose one of the following options based on your development stage:Option A: Local Development with ngrok (Recommended for Testing)
- Install ngrok following our ngrok setup guide.
- Start your local webhook server (see example below).
- Create a tunnel:
ngrok http 3000. - Use the provided HTTPS URL (e.g.,
https://abc123.ngrok.io/webhooks).
Option B: Quick Testing with webhook.site
- Visit webhook.site.
- Copy your unique URL.
- Use this for initial testing (note: this won’t allow you to respond to webhooks).
Option C: Production Deployment
Deploy your webhook handler to a cloud service like:- AWS Lambda with API Gateway.
- Google Cloud Functions.
- Heroku.
- DigitalOcean App Platform.
Webhook delivery characteristics
Webhook consumers must support these delivery characteristics:- Does not guarantee delivery order: Webhooks may arrive out of sequence
- Retries failed delivery: Retry timing and failover behavior depend on the product configuration
- Delivers concurrently: Multiple webhooks may arrive simultaneously
- Out-of-order webhooks: Events may not arrive in chronological order
- Simultaneous webhooks: Multiple events may be delivered at the same time
- Duplicate webhooks: The same event may be delivered more than once
Handling Duplicate Events
Duplicate webhooks can cause your application to process the same event multiple times. To prevent this:- Use idempotency keys: Include unique identifiers in your API requests (such as
command_id,idempotency_key, etc.) - Implement deduplication: Track processed webhook IDs to avoid duplicate processing
- Design idempotent operations: Ensure that processing the same event multiple times has no adverse effects
Webhook payload structure
JSON event envelopes commonly contain these identification fields. TeXML callbacks useapplication/x-www-form-urlencoded fields instead. Consult the webhook event catalog for the exact media type and payload for each callback.
- Event ID: Unique identifier for the webhook event
- Timestamp: When the event occurred
- Resource IDs: Identifiers that correlate the webhook with your resources (calls, messages, etc.)
- Event Type: Describes what action triggered the webhook
Security & Protocols
HTTP and HTTPS
- Unsecure (HTTP) URLs are allowed for webhooks.
- If HTTPS (TLS) is used, the certificate will be validated.
Event type naming
Where possible, events map to the C(R)UD operations, but this is certainly not always be applicable.- resource.created
- resource.updated
- resource.deleted
- message.created
- message.deleted
- message.delivered
- message.received
- porting_sub_request.ported
- porting_sub_request.closed
Webhook structure
The top-level structure varies by product and protocol. Voice API and Messaging use different JSON envelopes; TeXML uses form-encoded callbacks. Within a product family,event_type or an equivalent field determines the event-specific payload. Parse according to the documented media type and event schema rather than assuming a universal envelope.
Voice API top-level structure
Messaging top-level structure
Example: Receiving a Webhook
When you place an incoming call to a number associated with your Voice API Application, you will receive a callback for the incoming call. It should look something like the JSON below:Note: After pasting the above content, Kindly check and remove any new line added
| Field | Value |
| record_type | Description of the record. |
| event_type | The type of event detected by the Telnyx system |
| id | unique id for the webhook |
| occurred_at | ISO-8601 datetime of when event occured |
| call_control_id | call id used to issue commands via Voice API |
| connection_id | Voice API App ID (formerly Telnyx connection ID) used in the call. |
| call_leg_id | ID that is unique to the call and can be used to correlate webhook events |
| call_session_id | ID that is unique to the call session and can be used to correlate webhook events. Call session is a group of related call legs that logically belong to the same phone call, e.g. an inbound and outbound leg of a transferred call. |
| client_state | State received from a command |
| from | Number or SIP URI placing the call |
| to | Destination number or SIP URI of the call |
| direction | Whether the call is ‘incoming’ or ‘outgoing’ |
| state | Whether the call is in ‘bridging’ or ‘parked’ state |
Full Voice API example
Responding to a webhook
To acknowledge receipt of a webhook, return a2xx HTTP status code. Response headers and bodies are not used to process the event. Responses outside the 2xx range, including redirects, indicate failed delivery.
Retries
Treat timeout, network, and non-2xx responses as possible retry conditions. Product-specific retry and failover policies determine the attempts and destinations. The endpoint must tolerate repeated delivery even after an earlier attempt completed processing but its acknowledgment was not observed.
Best practices
Return the acknowledgment before performing complex logic or network calls. Queue the verified event, return2xx, and process it asynchronously.
Make event processing idempotent. Store processed event identifiers with a retention period appropriate to the product, and make resource updates conditional so replaying an event has no additional effect. Verify webhook signatures before recording an event as accepted. Log the event identifier, event type, delivery attempt when present, and product resource identifiers for correlation and failure analysis.
Webhook signing
Telnyx signs the webhook events it sends to clients so that the authenticity of the request can be verified. Webhook signing in API V2 uses public key encryption. Telnyx stores a public-private key pair and uses the private key to sign the payload. The public key is available to you so that you can verify the request. The public key can be viewed in the Mission Control Portal. The signature for the payload is calculated by building a string that is the combination of the timestamp of when the request was initiated, the pipe| character and the JSON payload. The signature is then Base64 encoded.
Base64 encoded) and the timestamp (in Unix format) are assigned to the request headers telnyx-signature-ed25519 and telnyx-timestamp respectively.
You can then use cryptographic libraries in your language of choice to verify the signature using the public key. Refer to the Telnyx SDKs for implementation examples in your preferred language.