lupin.Open console
Voice

Verify voice webhooks before updating call history

Understand signature checks, replay windows and call binding across Telnyx events and ElevenLabs transcripts.

Identify the sender before reading event meaning

Voice receives information from different providers with different signing schemes. Telnyx callbacks enter /v0/telnyx/webhooks; ElevenLabs post-call transcripts enter /v0/voice/elevenlabs/webhook. A JSON field saying that a call ended is only an assertion until the corresponding signature is checked. Keep the original body bytes and signature headers available to the verifier. Parsing JSON and serializing it again can change whitespace or ordering and invalidate the signed content. Do not use a generic bearer secret comparison as a replacement for the provider’s actual signature protocol.

Apply the correct signature and time policy

Telnyx documents Ed25519 verification using the public verification key and the timestamp and signature headers. ElevenLabs uses an HMAC signature over the timestamp and raw payload. Lupin’s ElevenLabs handler accepts a single timestamp, checks the signature and applies a bounded freshness policy before trusting transcription content. The checked implementation allows up to thirty minutes of age and five minutes of future skew. These are implementation details to review during upgrades, not a promise that any correctly signed historical delivery is safe to replay forever.

Bind the event to the admitted call

A valid provider signature authenticates the provider, not the customer resource named in arbitrary metadata. Lupin additionally checks agent identity, peer and conversation binding against the saved call. SIP events bind the configured provider phone identity and owned number; streaming events bind the stored media conversation and reject mismatched phone metadata. This prevents a transcript from another session from appearing under a familiar local call ID. Treat a binding mismatch as a security and routing investigation rather than broadening the query until some record happens to match.

Make duplicate processing an explicit case

Providers can deliver events concurrently, out of order and more than once. Lupin stores a transcript event identity and body hash before projecting content into call state. A duplicate should confirm the same outcome without creating another history entry; a conflicting payload should not silently replace accepted evidence. In your own event consumer, keep the provider event ID separate from the call ID because one call produces several events. Use occurred_at and terminal-state rules for ordering, and reconcile uncertain state with an authoritative provider read when necessary.

Test rejection paths with synthetic payloads

Create isolated fixtures for a valid delivery, changed body, missing signature, stale timestamp, wrong workspace binding and duplicate event. Use test-only keys and fictitious resource identifiers. The acceptance criterion is that invalid events cannot update transcripts or clear a call’s active state, while exact duplicates remain harmless. Never send production transcripts to a public request inspector. If verification configuration is missing, preserve an unavailable response and fix the configuration; accepting unsigned events during an outage destroys the trust boundary that makes later call diagnostics useful.

Check a signed but mismatched fixture

Create two synthetic calls with different conversation IDs and sign a transcript claiming the first local call while carrying the second conversation. The signature should pass and the ownership binding should fail. This fixture proves that authentic provider delivery cannot substitute for the admitted call’s identity, which a signature-only test would miss.

Sources & verification

Reviewed against current checked-in Lupin routes, shared contracts and official provider references. No live calls, OAuth authorizations, app actions or purchases were performed.

Prepared with AI assistance by Lupin editorial. How we research and maintain these guides.

Put it into practice

Give your agent the right tools.

Review the API, workspace requirements and permissions before enabling a workflow.

Explore phone Register an agent