Skip to main content
Webhooks allow your application to receive real-time notifications about call events from the OpenAI Realtime API. When events occur (incoming calls, call endings, etc.), OpenAI sends HTTP POST requests to your configured webhook endpoint.

Endpoint

POST /api/v1/openai/webhook
This endpoint handles all webhook events from OpenAI’s SIP calling infrastructure.

Authentication

Webhook requests are verified using the OpenAI SDK’s webhook verification system with HMAC signature validation.

Configuration

Set your webhook secret in environment variables:
OPENAI_WEBHOOK_SECRET=your_webhook_secret_here
OPENAI_API_KEY=your_openai_api_key_here

Verification Process

The webhook endpoint verifies each incoming request:
  1. Extracts the raw request body and headers
  2. Uses OpenAI SDK’s client.webhooks.unwrap() method
  3. Validates the signature using your webhook secret
  4. Returns 401 Unauthorized if verification fails
client = OpenAI(api_key=settings.openai_api_key.get_secret_value())

event = client.webhooks.unwrap(
    raw_body,
    headers=headers,
    secret=settings.openai_webhook_secret.get_secret_value(),
)

Event Types

The webhook handles three event types:
Event TypeDescription
realtime.call.incomingTriggered when a new call arrives
realtime.call.endedTriggered when a call ends normally
realtime.call.hangupTriggered when a call is hung up
realtime.call.hungupAlternative hangup event

Webhook Processing

1. Webhook Verification

All requests must pass signature verification using your webhook secret.

2. Deduplication

The system maintains a cache of seen webhook IDs to prevent duplicate processing:
  • Webhook IDs are stored for 30 minutes
  • Cache is cleaned up every 30 minutes
  • Duplicate webhooks return 200 OK with {"ok": true, "deduped": true}

3. Event Routing

After verification and deduplication, events are routed to appropriate handlers based on event type.

Response Format

All webhook responses return 200 OK with a JSON body:
ok
boolean
required
Indicates whether the webhook was processed successfully
accepted
boolean
Present for realtime.call.incoming events. true if the call was accepted
rejected
string
Present when a call is rejected. Possible values:
  • capacity - System at capacity
  • tenant_resolve_failed - Could not identify tenant
  • tenant_not_configured - Tenant not set up
  • instructions_missing - No instructions configured
  • tenant_config_parse_error - Invalid tenant configuration
deduped
boolean
true if this webhook was already processed
ignored
boolean
true if the webhook was ignored
reason
string
Reason for ignoring the webhook:
  • missing_webhook_id
  • missing_call_id
  • unsupported_event_type
tenant_id
string
The resolved tenant ID (for accepted calls)
fallback
boolean
true if fallback instructions were used due to database error
error
string
Error message if processing failed

Error Handling

Verification Failures

Invalid signatures return 401 Unauthorized:
{
  "detail": "Invalid signature"
}

Invalid Requests

Malformed webhooks return 400 Bad Request:
{
  "detail": "Invalid webhook request"
}

Graceful Degradation

The system handles various error conditions:
  • Database errors: Falls back to baseline instructions to keep service available
  • Missing call IDs: Returns success but ignores the webhook
  • Unknown event types: Returns success but logs warning

Security Best Practices

  1. Keep secrets secure: Store OPENAI_WEBHOOK_SECRET in environment variables, never in code
  2. Validate all webhooks: The system automatically verifies all incoming requests
  3. Monitor for duplicates: Built-in deduplication prevents replay attacks
  4. Use HTTPS: Always expose your webhook endpoint over HTTPS in production

Testing Webhooks

Test your webhook endpoint:
curl -X POST https://your-domain.com/api/v1/openai/webhook \
  -H "Content-Type: application/json" \
  -H "openai-webhook-signature: your_signature" \
  -d '{"type": "realtime.call.incoming", "data": {...}}'
Webhook signatures must be generated using your webhook secret. Use the OpenAI SDK’s signing utilities for testing.

Next Steps

Incoming Calls

Handle incoming call events with capacity gating

Call Events

Process call ended and hangup events

Build docs developers (and LLMs) love