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

# Outbound Calls

> Trigger an outbound voice call from one of your VoIP numbers.

Place an outbound call from one of your own [phone numbers](/api-reference/phone-numbers)
to a target number. You can reference a saved [agent](/api-reference/agents)
by id, or inline a one-off configuration for this call only.

## Endpoint

| Method | Path       | Description            |
| ------ | ---------- | ---------------------- |
| `POST` | `/v1/call` | Place an outbound call |

<Note>
  Outbound calling requires the `from_number` to be a number you own
  through a [VoIP connection](/api-reference/voip-connections). Demo
  numbers provisioned by ThunderPhone are inbound-only.
</Note>

## Place a call

<CodeGroup>
  ```bash Using an agent id theme={null}
  curl -X POST https://api.thunderphone.com/v1/call \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "from_number": "+15551234567",
      "to_number":   "+14155550199",
      "agent_id":    12
    }'
  ```

  ```bash Inline config (one-off) theme={null}
  curl -X POST https://api.thunderphone.com/v1/call \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "from_number": "+15551234567",
      "to_number":   "+14155550199",
      "config": {
        "prompt": "You are calling on behalf of Acme to confirm…",
        "voice":  "john",
        "product": "spark",
        "tools": []
      }
    }'
  ```

  ```python Python theme={null}
  result = requests.post(
      "https://api.thunderphone.com/v1/call",
      headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
      json={
          "from_number": "+15551234567",
          "to_number":   "+14155550199",
          "agent_id":    12,
      },
  ).json()
  ```
</CodeGroup>

### Request fields

| Field              | Type    | Required  | Description                                                         |
| ------------------ | ------- | --------- | ------------------------------------------------------------------- |
| `from_number`      | string  | yes       | E.164. Must be a number owned by this org (VoIP-backed)             |
| `to_number`        | string  | yes       | E.164 target                                                        |
| `agent_id`         | integer | see below | An [agent](/api-reference/agents) id in this org                    |
| `config`           | object  | see below | Inline config — schema matches the `call.incoming` webhook response |
| `max_hold_seconds` | integer | no        | Override the agent's hold timeout for this call only                |

Exactly **one** of:

1. `agent_id` — use the saved configuration.
2. `config` — inline a one-off configuration (same shape as a `call.incoming`
   [webhook response](/webhooks/call-incoming#response-schema)).
3. Neither — the call uses the number's configured `outbound_agent`. Fails
   with `400` if no outbound agent is set.

### Response

Returns `201 Created`:

```json theme={null}
{
  "call_id": 987654321,
  "status":  "initiated"
}
```

| Field     | Type    | Description                                                                                                                                                                                                                    |
| --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `call_id` | integer | Assigned id — use it on the [call endpoints](/api-reference/calls) to follow the call.                                                                                                                                         |
| `status`  | string  | Always `"initiated"` on success. This is the *initiation* status, not the [call state machine](/api-reference/calls#call-object); poll `GET /v1/calls/{call_id}` for the live `status` (`in_progress` → `completed`/`failed`). |

Poll [`GET /v1/calls/{call_id}`](/api-reference/calls#retrieve-a-call)
to observe state transitions:

| Live `status` | Meaning                                                                       |
| ------------- | ----------------------------------------------------------------------------- |
| `in_progress` | SIP dialing or connected                                                      |
| `completed`   | Call ended normally                                                           |
| `failed`      | Call could not be established (trial-mode, unverified number, provider error) |

### Error responses

| Status | Body `code`/`detail` hint                                          | Meaning                               |
| ------ | ------------------------------------------------------------------ | ------------------------------------- |
| `400`  | `from_number and to_number are required`                           | Missing required fields               |
| `400`  | `Provide either agent_id or config, not both`                      | Both supplied                         |
| `402`  | Insufficient balance                                               | Org balance is ≤ \$0.00. Top up first |
| `403`  | Outbound blocked (demo number, unverified VoIP, trial restriction) | See message for specifics             |
| `404`  | `from_number is not registered to this organization`               |                                       |
| `404`  | `Agent not found`                                                  | `agent_id` invalid or wrong org       |
| `502`  | Upstream SIP / LiveKit failure                                     | Transient; safe to retry              |

<Warning>
  Make sure your account has enough balance. Calls block at `<= $0.00`
  (402). See [Billing → Top up](/api-reference/billing#top-up-balance).
</Warning>

***

## Related

<CardGroup cols={2}>
  <Card title="Agents" icon="robot" href="/api-reference/agents">
    Configure the prompt, voice, and tools for outbound calls.
  </Card>

  <Card title="VoIP Connections" icon="phone-volume" href="/api-reference/voip-connections">
    Set up the VoIP provider credentials that back outbound calls.
  </Card>

  <Card title="Calls" icon="phone" href="/api-reference/calls">
    Observe the call as it runs and inspect the transcript afterward.
  </Card>

  <Card title="Billing" icon="credit-card" href="/api-reference/billing">
    Keep your prepaid balance topped up so outbound calls can place.
  </Card>
</CardGroup>
