Skip to main content

Webhook Ingest

Public-facing webhook endpoint that receives real-time call event notifications from Ultravox. Authentication is performed via URL path parameters (agency ID and webhook secret) rather than JWT tokens. Events are logged and queued for asynchronous processing by process-webhook-queue.

Endpoint

PropertyValue
Function Namewebhook-ingest
HTTP MethodPOST
AuthenticationURL-path-based: agency_id and webhook_secret embedded in the URL path. No JWT authentication.
Required RoleNone (external webhook caller authenticated by secret)

URL Format

POST /functions/v1/webhook-ingest/{agency_id}/{webhook_secret}

The agency_id and webhook_secret are extracted from the URL path segments. This URL is provided to the Ultravox webhook configuration and is returned by the get-integration-status endpoint.

Request

Headers

No specific headers are required beyond standard HTTP headers. No Authorization header is needed.

URL Parameters

FieldTypeRequiredDescription
agency_idstring (UUID)YesThe agency's unique identifier (extracted from URL path)
webhook_secretstringYesThe agency's webhook secret for authentication (extracted from URL path)

Body

The request body is a JSON payload conforming to the Ultravox webhook event format:

FieldTypeRequiredDescription
eventstringYesEvent type: call.started, call.joined, or call.ended
callobjectYesCall data object
call.callIdstringYesUltravox call identifier
call.createdstring (ISO 8601)YesWhen the call was created
call.joinedstring (ISO 8601)NoWhen the call was joined
call.endedstring (ISO 8601)NoWhen the call ended
call.endReasonstringNoReason the call ended
call.agentIdstringNoUltravox agent identifier
call.agentobjectNoAgent details (agentId, name)
call.metadataobjectNoArbitrary metadata attached to the call
call.shortSummarystringNoBrief call summary (available on call.ended)
call.summarystringNoFull call summary (available on call.ended)
{
"event": "call.ended",
"call": {
"callId": "ultravox-call-uuid",
"created": "2025-03-15T10:00:00Z",
"joined": "2025-03-15T10:00:05Z",
"ended": "2025-03-15T10:15:30Z",
"endReason": "hangup",
"agentId": "agent-uuid-123",
"agent": {
"agentId": "agent-uuid-123",
"name": "Sales Bot Alpha"
},
"shortSummary": "Customer inquired about pricing for enterprise plan."
}
}

Response

Success (204)

Returns an empty body with HTTP 204 (No Content) on successful queuing. This follows webhook best practice of returning quickly without a response body.

Error Responses

StatusCondition
400Missing agency_id or webhook_secret in the URL path
400Invalid payload structure (missing event or call.callId)
401Agency not found or webhook secret does not match (verified via get_agency_by_webhook_credentials RPC)
405HTTP method is not POST
500Failed to queue the webhook event, or unexpected server error

Behavior

  1. Reject non-POST requests with 405.
  2. Extract credentials from the URL path: parses agency_id and webhook_secret from path segments.
  3. Validate payload structure: Ensures event and call.callId are present.
  4. Verify credentials: Calls get_agency_by_webhook_credentials RPC to validate that the agency_id exists and the webhook_secret matches.
  5. Log the webhook: Inserts a record into the webhook_logs table with the agency ID, event type, full payload, and source IP (from x-forwarded-for header).
  6. Queue for processing: Calls insert_webhook_event RPC to add the event to the webhook processing queue.
  7. Return 204: Responds immediately with no body, ensuring fast webhook acknowledgment.

Database Tables / RPCs

Table / RPCOperationDescription
get_agency_by_webhook_credentials (RPC)ReadValidates the agency ID and webhook secret pair
webhook_logsWrite (Insert)Logs every incoming webhook event with metadata
insert_webhook_event (RPC)WriteQueues the event for asynchronous processing

External APIs

None. This function is the receiver of external webhook calls, not a caller.