Overview
The custom integration feature allows you to send call transcripts from your own backend system or third-party service to Cekura via webhooks. This provides flexibility to integrate any voice platform while maintaining full control over your conversation data.How It Works
- Configure your agent in Cekura and select “Custom” as the provider
- Cekura provides you with a webhook URL
- After each call ends, send the call data to the webhook URL
- Cekura listens for call data for 5 minutes after the call ends
- View evaluation results in the Cekura dashboard
Setup
In Cekura Dashboard
- Create or edit an agent in the Cekura dashboard
- Set the transcript provider to “Custom”
- Copy the webhook URL provided by Cekura
- Note your API key for authentication
One webhook URL per project: Cekura provides a single webhook URL per project. If you need separate webhook destinations for different environments (e.g., development vs. production), create separate projects in Cekura — each project gets its own webhook URL and API key. This is the recommended approach for environment isolation.
Webhook Implementation Requirements
Your system should send call transcripts to the Cekura webhook with the following specifications: HTTP Method:POST
Headers:
Payload Format
Your webhook POST request should send a JSON payload with the following structure:Top Level Structure
agent_id is required unless every call object in calls includes a run_id field. If you already have a Cekura Run ID for each call before sending the webhook — for example, when using SIP integrations where run IDs are available from SIP headers — you can omit agent_id entirely and include run_id on each call object instead. In this case, Cekura will trust the provided run IDs and match transcripts directly to the existing runs.Call Object Structure
Each call in thecalls array should include:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for this call from your system (max 255 chars) |
startedAt | string | Yes | Call start time in ISO 8601 format |
endedAt | string | Yes | Call end time in ISO 8601 format |
messages | array | No | List of transcript messages (see below) |
to_phone_number | string | No | Phone number that received the call (must start with + followed by digits, max 15 chars). Example: ‘+14155551234’ |
from_phone_number | string | No | Phone number that initiated the call (must start with + followed by digits, max 15 chars). Example: ‘+18005551234’ |
metadata | object | No | Optional metadata as key-value pairs for additional call information |
endedReason | string | No | Reason call ended (default: “unknown”, e.g., “assistant-ended-call”, “customer-hungup”) |
run_id | string | Conditionally required | Cekura Run ID for this call. Required on each call when agent_id is omitted at the top level. Intended for SIP integrations where run IDs are pre-known from SIP headers. |
Message Object Structure
Each message in themessages array should include:
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Yes | Message role: “bot”, “user”, “system”, “function_call”, or “function_call_result” |
content | string | Yes | The message content or function description |
start_time | number | No | Start time in milliseconds from epoch |
end_time | number | No | End time in milliseconds from epoch |
data | object | No | Additional data for function calls |
Complete Example
Here’s a complete example payload with two calls:SIP / Pre-known Run ID Example
If you are using a SIP integration and already have Cekura Run IDs available from SIP headers before sending the webhook, you can omitagent_id at the top level and include run_id on each call instead. Cekura will trust the provided run IDs and attach the transcripts directly to the matching runs — no agent lookup needed.
When using
run_id per call, every call in the calls array must include a run_id. Mixing calls with and without run_id in the same payload (when agent_id is absent) is not supported.Important Considerations
For successful webhook integration, ensure:- Timing: Send the call data within 5 minutes after the call ends
- Authentication: Include the
X-CEKURA-API-KEYheader with your API key - Phone Numbers: Phone numbers must start with + followed by digits (max 15 chars, e.g., ‘+14155551234’). The
to_phone_numbershould match the scenario’s inbound number for testing - Timestamps: Use ISO 8601 format for
startedAtandendedAt - Message Timing: Use milliseconds from epoch for message
start_timeandend_time(optional fields) - Agent ID: Use the correct agent ID from your Cekura dashboard. If you have a Cekura Run ID available ahead of time (e.g. from SIP headers), you can omit
agent_idand includerun_idon each call object instead — Cekura will match transcripts directly to the existing runs - Unique Call IDs: Each call should have a unique identifier (max 255 chars)
- Metadata: Use the
metadatafield to pass additional key-value pairs for call information
Troubleshooting
If your webhook integration isn’t working as expected:No calls appear in Cekura
- Verify the webhook URL is correct
- Check that the
X-CEKURA-API-KEYheader is included and correct - Ensure the payload format matches the specification
- Confirm the
agent_idis correct - Verify the call data was sent within 5 minutes after the call ended
Authentication issues
- Double-check your API key is correct
- Ensure the header name is exactly
X-CEKURA-API-KEY(case-sensitive) - Verify the API key has proper permissions
Calls not matching scenarios
- Confirm the
to_phone_numberin the payload matches the scenario’s inbound number - Ensure phone numbers start with + followed by digits (max 15 chars)
- Check that the call ID is unique and under 255 characters
- Verify timestamps are in ISO 8601 format
Invalid payload errors
- Validate your JSON payload structure
- Ensure all required fields are present (
id,startedAt,endedAt) - Verify the
agent_idis an integer, not a string (required unless each call includes arun_id) - Check that phone numbers follow the correct format (+ followed by digits, max 15 chars)
- Ensure
messagesis an array with dictionaries containing role and content fields
Next Steps
- Learn about custom metrics
- Explore predefined metrics
- Set up instruction following metric