Receive conversation events

This guide walks through configuring a webhook and handling the two event types the platform delivers: conversation.initiating (when a call is answered) and conversation.completed (when a call ends).

You'll need an API key with convai:read and convai:write, and a publicly accessible HTTPS endpoint to receive webhook deliveries.

1. Configure a webhook

Create a webhook by posting to /webhooks. The platform will POST to your url whenever the specified event fires. Use request_headers to pass a shared secret so your endpoint can verify deliveries.

curl -X POST https://api.simwood.com/convai/v1/webhooks \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "conversation.completed",
    "url": "https://example.com/hooks/calls",
    "request_headers": {
      "X-Webhook-Secret": "your-shared-secret"
    }
  }'

To also receive initiating events, create a second webhook:

curl -X POST https://api.simwood.com/convai/v1/webhooks \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "conversation.initiating",
    "url": "https://example.com/hooks/calls",
    "request_headers": {
      "X-Webhook-Secret": "your-shared-secret"
    }
  }'

These webhooks fire for every conversation on your account. To scope them to a single agent, add "agent_id": "<agent-uuid>" to either request body.

2. Handle conversation.initiating

The initiating event fires when an inbound call arrives, before it is answered. The caller hears ringing while the platform waits for your response. You have up to the webhook's configured timeout_ms (default: 5 seconds) to reply — use this window to look up caller-specific data and return it as overrides for this call.

Your endpoint receives:

{
  "type": "conversation.initiating",
  "timestamp": 1719820800,
  "data": {
    "conversation_id": "conv-uuid-...",
    "agent_id": "agent-uuid-..."
  }
}

Respond with any combination of the following fields to override the agent's default configuration for this call:

{
  "dynamic_variables": {
    "customer_name": "Jane Smith",
    "account_status": "premium",
    "outstanding_balance": "£42.00"
  },
  "conversation_config_override": {
    "text_only": false
  }
}
Field Type Description
dynamic_variables object Key-value pairs injected into the agent's prompt as {{dynamic_variables.<key>}}
conversation_config_override object Overrides to the agent's conversation configuration for this call

Omit a field to use the agent's default. An empty 200 response is valid if you have no overrides.

If your endpoint does not respond within timeout_ms, the agent answers with its default configuration. Keep your handler fast — a simple database lookup or cache read is ideal; avoid anything that may block.

3. Handle conversation.completed

The completed event fires when the call ends and the transcript is ready. Your endpoint receives the full conversation record:

{
  "type": "conversation.completed",
  "timestamp": 1719820943,
  "data": {
    "conversation_id": "conv-uuid-...",
    "agent_id": "agent-uuid-...",
    "status": "done",
    "metadata": {
      "start_time_unix_secs": 1719820800,
      "call_duration_secs": 143
    },
    "transcript": [
      { "role": "agent", "message": "Hello, thanks for calling. How can I help you today?", "time_in_call_secs": 0.0 },
      { "role": "user",  "message": "I'd like to check my account balance.",               "time_in_call_secs": 3.4 },
      { "role": "agent", "message": "Your current balance is £42.00.",                      "time_in_call_secs": 6.1 }
    ],
    "analysis": {
      "data_collection_results": {
        "issue_resolved": true,
        "customer_intent": "check account balance"
      },
      "call_successful": "success",
      "transcript_summary": "Caller asked for their account balance. Agent provided it."
    }
  }
}

Respond with 2xx to acknowledge. The platform retries on non-2xx responses with exponential backoff.

4. Check webhook health

After a few calls, confirm deliveries are landing:

curl https://api.simwood.com/convai/v1/webhooks/<webhook-id> \
  -H "Authorization: Bearer sk_live_..."

The response includes a health field (healthy, degraded, or failing) and consecutive_failures. A failing webhook has its deliveries suspended until it recovers — investigate your endpoint if the health degrades.

WebhooksWebhook scope, delivery, retry behaviour, and the full event payload reference.ConversationsThe full conversation record and what each field means.