Skip to main content
Accepted inbound events and queued outbound deliveries are inspectable from the dashboard or the management API. A duplicate inbound 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 receivedprocessingprocessed 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

A 202 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.
Resending a failed event with the same eventId returns skipped, not a retry. Fix the payload and send it with a new eventId.

Applied, with warnings

A processed 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

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.
Rotating the API key invalidates the old one immediately — and also revokes every Dialer SDK publishable key on that integration. Update both.
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.
That is intentional. null, undefined and empty strings never overwrite existing values on upsert — this protects Ringee data from partial CRM payloads.
Expected. Transport retries reuse the eventId. Deduplicate on it with a UNIQUE constraint — see Outbound webhooks.
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.
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.