Calls
List, create, view, and cancel outbound voice calls.
List Calls
Retrieve a paginated list of calls for your organization.
GET /api/v1/callsRequired scope: calls:read
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 25 | Results per page (1–100) |
cursor | string | — | Pagination cursor from a previous response |
status | string | — | Filter by status: new, scheduled, processing, ended, cancelled, error |
contactId | string | — | Filter by contact ID |
caseId | string | — | Filter by case ID |
from | string | — | ISO 8601 datetime — only calls after this time |
to | string | — | ISO 8601 datetime — only calls before this time |
Example Request
curl -X GET "https://app.erzycall.com/api/v1/calls?limit=10&status=ended" \
-H "X-API-Key: ek_live_abc123"Example Response
{
"data": [
{
"id": "abc123",
"status": "ended",
"to": "+14155551234",
"from": "+14155559999",
"contactId": "contact_456",
"caseId": "case_789",
"createdAt": "2025-01-15T10:30:00Z",
"duration": 45
}
],
"pagination": {
"cursor": "eyJwb3...",
"hasMore": true,
"pageSize": 10
}
}Create Call
Trigger a new outbound call or schedule one for later.
POST /api/v1/callsRequired scope: calls:write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Destination phone number in E.164 format (e.g., +14155551234) |
from | string | Yes | Caller ID — must be a phone number assigned to your organization |
contactId | string | No | Associate with an existing contact. Also enables variable resolution — {{name}}, {{email}}, {{phone}}, and {{notes}} are automatically populated from the contact record. |
caseId | string | No | Use an existing case as the call script. The case provides the first message, system prompt, tools, and variable definitions. See Using Cases below. |
firstMessage | string | No | Opening message for the AI assistant (max 1,000 chars). Overrides the case's first message if both are provided. |
scheduledAt | string | No | ISO 8601 datetime to schedule the call for later. Omit for an immediate call. |
variableValues | object | No | Key-value pairs to inject into the first message and system prompt. Variables use {{variableName}} syntax in templates. |
Using Cases with Calls
A case is a reusable call script that defines the AI assistant's first message, system prompt (personality, instructions, conversation flow), tools (e.g., calendar booking), and variable definitions. When you pass a caseId, the assistant follows the case structure automatically.
The priority for firstMessage and system prompt is: caller-supplied → case → generic default.
| Scenario | First Message | System Prompt | Tools | Best For |
|---|---|---|---|---|
caseId only | ✅ From case | ✅ From case | ✅ From case | Standard scripted calls — the AI follows the full case flow |
firstMessage only | ✅ Your message | ⚠️ Generic default | ❌ None | Simple one-liner calls with no conversation structure |
Both caseId + firstMessage | ✅ Your message (overrides case) | ✅ From case | ✅ From case | Scripted calls with a custom opener per contact |
| Neither | ⚠️ Generic default | ⚠️ Generic default | ❌ None | Not recommended — results in a bare assistant |
Tip: For most use cases, pass a caseId and let the case handle everything. Use firstMessage only when you need a custom opener that differs from the case template.
Variable Resolution
Variables in the case's first message and system prompt (e.g., {{name}}, {{email}}) are resolved automatically from multiple sources:
variableValuesyou pass in the request body (highest priority)- Contact data from the
contactId— maps{{name}}→ contact title,{{email}}→ contact email, etc. - Case variable defaults defined in the case configuration
For example, if your case's first message is "Hello, is this {{name}}?" and you pass a contactId for "Artur Temirov", the AI will say: "Hello, is this Artur Temirov?"
Example: Call with Case
curl -X POST "https://app.erzycall.com/api/v1/calls" \
-H "X-API-Key: ek_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"to": "+60111234567",
"from": "+60360431879",
"caseId": "case_789",
"contactId": "contact_456",
"variableValues": {
"name": "Ahmad",
"company": "TechCorp"
}
}'Example: Simple Call (No Case)
curl -X POST "https://app.erzycall.com/api/v1/calls" \
-H "X-API-Key: ek_live_abc123" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-call-12345" \
-d '{
"to": "+14155551234",
"from": "+14155559999",
"firstMessage": "Hi, this is a follow-up call regarding your inquiry.",
"contactId": "contact_456"
}'Example: Scheduled Call
curl -X POST "https://app.erzycall.com/api/v1/calls" \
-H "X-API-Key: ek_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"to": "+60111234567",
"from": "+60360431879",
"caseId": "case_789",
"contactId": "contact_456",
"scheduledAt": "2025-01-16T14:00:00.000Z"
}'Example Response (201 Created)
{
"data": {
"id": "call_abc123",
"status": "new",
"to": "+14155551234",
"from": "+14155559999",
"contactId": "contact_456",
"caseId": "case_789",
"createdAt": "2025-01-15T10:30:00Z"
}
}Immediate calls have status new and are picked up by the system within ~60 seconds. Scheduled calls have status scheduled and fire at the specified scheduledAt time.
Errors
| Status | Code | Description |
|---|---|---|
| 422 | INVALID_PHONE | The from number is not assigned to your organization |
| 404 | NOT_FOUND | Referenced contactId or caseId not found |
Get Call
Retrieve details for a single call.
GET /api/v1/calls/{id}Required scope: calls:read
Example Request
curl -X GET "https://app.erzycall.com/api/v1/calls/abc123" \
-H "X-API-Key: ek_live_abc123"Example Response
{
"data": {
"id": "abc123",
"status": "ended",
"to": "+14155551234",
"from": "+14155559999",
"contactId": "contact_456",
"caseId": "case_789",
"createdAt": "2025-01-15T10:30:00Z",
"duration": 45
}
}Cancel Call
Cancel a scheduled or pending call. Only calls with status new or scheduled can be cancelled.
DELETE /api/v1/calls/{id}Required scope: calls:write
Example Request
curl -X DELETE "https://app.erzycall.com/api/v1/calls/abc123" \
-H "X-API-Key: ek_live_abc123"Response
Returns 204 No Content on success.
Errors
| Status | Code | Description |
|---|---|---|
| 404 | NOT_FOUND | Call not found |
| 422 | INVALID_STATE | Call cannot be cancelled in its current status (e.g., already ended) |