Skip to main content
Ringee pushes the events selected on your Custom Integration to its configured HTTP(S) endpoint. Every delivery is HMAC-signed and retried up to 10 times until your endpoint acknowledges it. Calls generate terminal events only. Human and AI Voice Agent calls use the same delivery pipeline, envelope, subscriptions and retry policy.

Configure the endpoint

In Integrations → Custom Integrations → Configure → Settings:
  1. Set outbound URL to your public HTTPS endpoint.
  2. Select the events you want under the outbound event selector.
  3. Click Test webhook to send a test.ping.
The endpoint must be reachable from the public internet and must not require your own auth token — Ringee authenticates by signing the body, not by sending credentials. Disable JWT verification on the route and verify the signature instead.

Delivery format

Identify the source

Outbound events can include these shared data fields: Actor enrichment is best-effort. Ringee still delivers the event if the user or agent can no longer be resolved, so treat data.user and data.agent as optional. data.externalId follows every call-linked event from the same AI Voice Agent call, including terminal, outcome, callback, meeting and recording events.
Set metadata.external_id when you start an AI Voice Agent call. You can then join every related webhook to your own record without parsing arbitrary metadata.

Verify the signature

Read the request body as raw text first. Parsing the JSON before verifying — or re-serializing it — changes the bytes and the signature will never match.
The signature is HMAC_SHA256(signingSecret, "<timestamp>.<rawBody>"), hex-encoded.
1

Parse the header

Ringee-Signature has the form t=<unixSeconds>,v1=<hexDigest>. Extract both parts.
2

Check the timestamp

Confirm t matches the Ringee-Timestamp header, and reject anything more than 5 minutes old. This blocks replay attacks.
3

Recompute and compare

Compute the HMAC over `${timestamp}.${rawBody}` with your whsec_… secret and compare in constant time.
4

Reject failures with 401

A missing header or a bad signature is a 401. Never store or process an unverified event.
The Edge Function that receives Ringee webhooks must have verify_jwt = false. Ringee does not send a Supabase JWT — the HMAC signature is the authentication.

Respond correctly

200 { "received": true } and 204 No Content are both valid acknowledgements.

Idempotency

The same eventId can arrive more than once — that is by design, not a bug. Transport retries reuse the exact stored payload and eventId. Store received events in a table with a UNIQUE constraint on the event id:
Insert the eventId before processing. If the insert conflicts, the event is a duplicate: return 200 and do nothing else.

Retries

After the final attempt the delivery is marked failed and Ringee sends email and device push notifications to the integration owner or organization admins. Alerts are throttled per integration for six hours. Deliveries are also failed immediately if the integration has been disabled or deleted. The queued delivery worker runs every 5 seconds and claims up to 100 due deliveries. It sends independent deliveries in parallel, so neither the queue cadence nor creation time establishes ordering.
Inspect the delivery status, cumulative attempt count and last error in the dashboard, or via GET /api/integrations/custom/:id/outbound-logs. See Logs and errors.

Event ordering

Deliveries are independent rows sent in parallel waves — order is not guaranteed. Design for this:
  • call.outcome.updated can arrive before call.completed. Upsert the activity by callId from either event.
  • call.outcome.updated includes data.call when the telephony row can still be resolved, so it can create or update the activity by itself.
  • recording.ready can arrive seconds or minutes after the call ended.
  • meeting.created and call.outcome.updated both fire when an outcome is meeting_booked.
  • A subscribed AI Voice Agent call can produce call.completed or call.failed, then call.outcome.updated, and later callback, meeting or recording events. Do not wait for a fixed sequence.

Next steps

Event reference

Every outbound payload, field by field

Build an integration

Mapping, loop prevention and a test checklist