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

# Place an outbound call

> Have a voice agent call a phone number, then follow the call until it ends.

`POST /v1/projects/{projectId}/agents/{agentId}/dispatch-call` asks an agent to call one phone number. The request returns as soon as the number is being dialed, with the id of the conversation the call will be recorded under. To call a list of numbers with per-contact variables, retries and calling hours, use a [campaign](/voice/campaigns.md) instead.

## Before you start

* **The agent is published.** Outbound calls always run the agent's published version. An agent that has never been published is refused with `409 AGENT_NOT_PUBLISHED`.
* **The agent is a voice agent.** A Voice Assist agent listens to calls a person handles and cannot place calls (`422 AGENT_TYPE_NOT_DISPATCHABLE`).
* **There is a number to call from.** Clarity picks the caller ID in this order:

  1. the `from` number in your request;
  2. the outbound caller ID set for the agent in Clarity;
  3. the number routed to the agent for inbound calls;
  4. the platform's default outbound route, when your deployment has one.

  A `from` number must be registered in the project and enabled for outbound calls. Numbers and their outbound trunks are set up in Clarity.

## Dispatch the call

**1. Find the project and agent ids**

```bash theme={null}
curl https://voice-api.onclarity.com/v1/projects \
  -H "Authorization: Bearer $CLARITY_API_KEY"

curl https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/agents \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

**2. Ask the agent to call**

```bash theme={null}
curl -X POST https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/agents/$AGENT_ID/dispatch-call \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155550123",
    "from": "+14155550100",
    "on_call_ended_url": "https://hooks.example.com/clarity/call-ended"
  }'
```

**3. Keep the conversation id**

```json theme={null}
{
  "callId": "8d0f5a3e-2c41-4b7a-9f61-0e2b8c7d4a19",
  "roomName": "dispatch-1a2b3c4d",
  "status": "dialing",
  "conversationId": "0b6f6c1e-5d0a-4f43-9a51-3e2f3b7f1a10"
}
```

`conversationId` is the id you use to read the call afterwards. `status` is always `dialing`: a successful response means the call was placed, not that anyone answered.

### Request body

**to** `string` *required*

The number to call. Use E.164 format, for example `+14155550123`. An invalid number is refused with `400`.

**from** `string`

The caller ID to present. Must be a number of this project that is enabled for outbound calls, or the request is refused with `422` and nothing is dialed. Omit it to use the agent's own caller ID (see the order above).

**on\_call\_ended\_url** `string`

An `https://` URL. When the call ends, Clarity sends the call's vCon document to it with a `POST`. See [Call-ended webhook](/voice/call-ended-webhook.md).

> [!NOTE]
>
> Dispatch takes no per-call variables. If your agent's prompt uses variables such as a customer name or an order number, place the call through a [campaign](/voice/campaigns.md), whose items carry `custom_vars`.

### Errors

| Status | When | Body |
| - | - | - |
| `400` | `to` or `from` is not a valid phone number. | `{"error": "Invalid target phone number"}` |
| `404` | The agent is not in this project. | `{"error": "Agent not found"}` |
| `409` | The agent has never been published. | `{"error": "…", "code": "AGENT_NOT_PUBLISHED", "agent_id": "…"}` |
| `422` | The body fails validation: no `to`, or an `on_call_ended_url` that is not an `https` URL. | `{"error": "to: Required", "issues": [{"path": "to", "code": "invalid_type", "message": "Required"}]}` |
| `422` | The agent is a Voice Assist agent. | `{"error": "…", "code": "AGENT_TYPE_NOT_DISPATCHABLE", "agent_type": "assist", "agent_id": "…"}` |
| `422` | `from` is not an outbound-enabled number of this project. | `{"error": "from number is not an outbound-enabled number in this project", "from": "+14155550100"}` |
| `503` | No number could be resolved and the platform has no default outbound route. | `{"message": "SIP outbound not configured"}` (or `SIP outbound caller ID not configured`) |

The `503` body uses `message`, not `error`. It means the call has nowhere to go out from: give the agent an outbound caller ID in Clarity, or pass `from`.

## Follow the call

You have two options. Use the webhook when you want to react the moment a call ends; poll when you cannot receive inbound HTTPS requests.

**Webhook**

Pass `on_call_ended_url` when you dispatch. Clarity posts the call's vCon document there after the call ends. See [Call-ended webhook](/voice/call-ended-webhook.md) for the payload and the delivery rules.

The webhook is best-effort. Keep a fallback that polls conversations you have not heard back about.

**Poll**

Read the conversation until its `status` is `ended`:

```bash theme={null}
curl https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/conversations/$CONVERSATION_ID \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

```json theme={null}
{
  "id": "0b6f6c1e-5d0a-4f43-9a51-3e2f3b7f1a10",
  "status": "ended",
  "direction": "outgoing",
  "connected": true,
  "duration": 94,
  "hangup_reason": "customer_hangup",
  "conversation_summary": "The customer moved their appointment to Thursday at 10:00.",
  "summary_status": "generated",
  "ended_at": "2026-10-20T14:03:34.000Z"
}
```

The response above is trimmed. A conversation is `pending` while the call is being set up, `active` while it runs and `ended` when it finishes. `connected` tells you whether the callee joined; a call nobody answered ends with `connected: false`.

Poll every few seconds, not faster. The summary is written shortly after the call ends: while `summary_status` is `pending` it is still being produced.

To see how the phone leg itself went (its `status`, `hangup_reason` and `hangup_sip_code`), list the conversation's calls:

```bash theme={null}
curl https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/conversations/$CONVERSATION_ID/calls \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

Once the call has ended, read its transcript and recording as described in [Conversations and recordings](/voice/conversations.md).


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