eventId is returned as skipped without creating another row, and the immediate test.ping action is not stored as a delivery.
Where to look
In the dashboard: Integrations → Custom Integrations → Configure, then the inbound and outbound log tabs.
Log endpoints
Both require an admin dashboard session and return newest-first arrays.limit defaults to 50 and is capped at 200. To load the next page, pass the last returned row’s id as cursor.
Inbound rows contain id, integrationId, eventType, externalEventId, status, receivedAt, processedAt, errorMessage and rawPayload. Their normal lifecycle is received → processing → processed or failed.
Outbound rows contain id, integrationId, eventType, subjectId, destinationUrl, payload, signature, status, attemptCount, lastError, nextAttemptAt, sentAt, dedupeKey, createdAt and updatedAt. Status is pending, sending, sent or failed.
Outbound logging is one aggregate row per delivery, not one row per attempt.
attemptCount counts failed attempts and lastError stores only the most
recent failure. HTTP status and latency are returned by Test webhook, but
are not persisted for each queued attempt.Inbound errors
Rejected before Ringee records anything
A bad key or an incomplete envelope is answered synchronously, and nothing reaches the inbound log. Every envelope problem is reported in one message, joined by; :
Recorded, then rejected
A202 with "status": "failed" means the event was authenticated and stored, then rejected while being applied. It is in the inbound log with the reason in errorMessage, and nothing was written: validation runs before the first record is touched.
Applied, with warnings
Aprocessed response can carry a warnings array — an unknown field name, a phone number read with an assumed country, an ownerEmail matching nobody. The event applied; something in it did not. See Inbound events.
Warnings are returned in the response only. They are not stored on the inbound
log row, so capture them when you send.
Outbound delivery failures
A delivery is retried when your endpoint returns a non-2xx status, times out after 15 seconds, or is unreachable.
After 10 failed attempts the delivery is marked
failed. Ringee sends email and device push notifications to the integration owner or organization admins, throttled to at most one alert per integration every six hours.
Common causes
Signature verification always fails
Signature verification always fails
You parsed the body before verifying. Read the raw text and HMAC exactly those bytes — a
JSON.parse followed by JSON.stringify produces different bytes and a different digest.Also confirm you are hashing `${timestamp}.${rawBody}`, not the body alone, and that you are using the whsec_ signing secret rather than the cik_live_ API key.Everything returns 401 after a rotation
Everything returns 401 after a rotation
Rotating the API key invalidates the old one immediately — and also revokes every Dialer SDK publishable key on that integration. Update both.
Contacts are duplicated in Ringee
Contacts are duplicated in Ringee
You are sending a different
externalId for the same record, or omitting it. Dedup runs on externalId first, then phoneNumber. Keep externalId stable for the lifetime of the record.Fields are not being cleared
Fields are not being cleared
That is intentional.
null, undefined and empty strings never overwrite existing values on upsert — this protects Ringee data from partial CRM payloads.Your endpoint receives the same event twice
Your endpoint receives the same event twice
Expected. Transport retries reuse the
eventId. Deduplicate on it with a
UNIQUE constraint — see Outbound
webhooks.An AI Voice Agent event is not linked to your record
An AI Voice Agent event is not linked to your record
Send your record id as
metadata.external_id or metadata.externalId when you
start the call. Ringee exposes it as data.externalId on every call-linked
outbound event. data.agent.id identifies the Ringee AI Voice Agent, not your
CRM record.Recordings never arrive
Recordings never arrive
recording.ready is a separate opt-in event that can arrive minutes after call.completed. Confirm it is selected in the outbound event list, and that recording is enabled for the workspace.Self-hosted debugging
When running Ringee yourself, deliveries are drained by the Temporal orchestrator (apps/orchestrator). If outbound events queue up but never send, check that the orchestrator is running and connected to Temporal — see How it works.
