> ## Documentation Index
> Fetch the complete documentation index at: https://docs.verbeo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /calls — Create a phone call (v1)

> Place an outbound phone call with an AI voice agent over your LiveKit SIP number. Pass dynamic variables to personalize each call.

<Note>
  This is **version 1** of the endpoint. It is unchanged and keeps working. For a new integration, use [version 2](/api-reference/calls/create), which answers the same envelope as every other resource.
</Note>

The Calls API places outbound phone calls programmatically. You provide a destination number and one of your workspace phone numbers; Verbeo dials the destination over that number's LiveKit SIP trunk and connects your AI agent. You can pass dynamic variables that are injected into the agent's system prompt at call time, so you can personalize each call without creating separate agents.

<Warning>
  This endpoint requires a **private** API key (prefix `vbr_`). Public keys (`vbr_pub_`) are not accepted and return a `401` error.
</Warning>

## Endpoint

```
POST https://api.verbeo.ai/calls
```

## Request body

<ParamField body="toNumber" type="string" required>
  Destination phone number in E.164 format (e.g., `"+1234567890"`).
</ParamField>

<ParamField body="fromNumber" type="string" required>
  The phone number to call from, in E.164 format. Must be an active phone number in your workspace.
</ParamField>

<ParamField body="agentId" type="string">
  UUID of the agent that will handle the call. **Optional** — if omitted, Verbeo uses the outbound agent configured on the `fromNumber`. If neither is set, the request returns `400`.
</ParamField>

<ParamField body="dynamicVariables" type="object">
  Key-value pairs that are substituted into the agent's system prompt at call time. Reference them in the prompt as `{{variable_name}}`. Values must be strings.

  ```json theme={null}
  {
    "customer_name": "Jane Smith",
    "order_id": "ORD-98765"
  }
  ```
</ParamField>

<Note>
  The response returns **immediately** once the call is created — it does not wait for the destination to answer. The agent places the call in the background; track the outcome with the `call_started` / `call_ended` / `call_analyzed` [webhooks](/guides/webhooks).
</Note>

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.verbeo.ai/calls" \
    -H "Authorization: Bearer vbr_your_private_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "toNumber": "+1234567890",
      "fromNumber": "+1987654321",
      "agentId": "550e8400-e29b-41d4-a716-446655440000",
      "dynamicVariables": {
        "customer_name": "Jane Smith",
        "order_id": "ORD-98765",
        "account_tier": "premium"
      }
    }'
  ```

  ```bash Use the number's outbound agent theme={null}
  curl -X POST "https://api.verbeo.ai/calls" \
    -H "Authorization: Bearer vbr_your_private_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "toNumber": "+1234567890",
      "fromNumber": "+1987654321"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.verbeo.ai/calls", {
    method: "POST",
    headers: {
      Authorization: "Bearer vbr_your_private_api_key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      toNumber: "+1234567890",
      fromNumber: "+1987654321",
      agentId: "550e8400-e29b-41d4-a716-446655440000",
      dynamicVariables: {
        customer_name: "Jane Smith",
        order_id: "ORD-98765",
      },
    }),
  });
  const call = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.verbeo.ai/calls",
      headers={
          "Authorization": "Bearer vbr_your_private_api_key",
          "Content-Type": "application/json",
      },
      json={
          "toNumber": "+1234567890",
          "fromNumber": "+1987654321",
          "agentId": "550e8400-e29b-41d4-a716-446655440000",
          "dynamicVariables": {
              "customer_name": "Jane Smith",
              "order_id": "ORD-98765",
          },
      },
  )
  call = response.json()
  ```
</CodeGroup>

## Response

The request returns `201 Created` as soon as the call is created.

<ResponseField name="success" type="boolean" required>
  `true` when the call was created.
</ResponseField>

<ResponseField name="callId" type="string" required>
  Verbeo UUID for this call. Use it to retrieve call details and correlate webhook events.
</ResponseField>

<ResponseField name="status" type="string" required>
  Call status. `"queued"` — the call has been created and is being placed.
</ResponseField>

<ResponseField name="toNumber" type="string" required>
  The destination phone number as provided.
</ResponseField>

<ResponseField name="fromNumber" type="string" required>
  The phone number the call was placed from.
</ResponseField>

<ResponseField name="agentId" type="string" required>
  UUID of the agent handling the call (the resolved agent, whether you passed it or it came from the phone number).
</ResponseField>

<ResponseField name="agentName" type="string" required>
  Display name of the agent.
</ResponseField>

<ResponseField name="message" type="string" required>
  Human-readable confirmation message.
</ResponseField>

### Example response

```json theme={null}
{
  "success": true,
  "callId": "772g0622-g41d-63f6-c938-668877662222",
  "status": "queued",
  "toNumber": "+1234567890",
  "fromNumber": "+1987654321",
  "agentId": "550e8400-e29b-41d4-a716-446655440000",
  "agentName": "Customer Support Agent",
  "message": "Outbound call created"
}
```

## Error responses

| Status | Error | Description |
| - | - | - |
| `400` | Missing required fields | `toNumber` or `fromNumber` was not provided |
| `400` | No agent specified | No `agentId` was passed and the `fromNumber` has no outbound agent configured |
| `401` | Unauthorized | API key is invalid, expired, or is a public key |
| `402` | Insufficient balance | Your balance is below the amount needed to start a call — add funds on the **Billing** page |
| `403` | Account paused | Billing is paused — contact [support@verbeo.ai](mailto:support@verbeo.ai) |
| `404` | Not found | The specified agent or phone number does not exist in your workspace |
| `429` | Concurrency limit reached | You have reached the maximum number of simultaneous calls for your plan — wait for active calls to complete or upgrade |
| `502` | Failed to initiate call | The telephony provider could not place the call |

<Tip>
  To personalize calls at scale, define placeholder tokens like `{{customer_name}}` in your agent's system prompt and pass the actual values through `dynamicVariables` on each call. The agent sees the resolved values during the conversation.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.