---
title: "Dispatch one ad-hoc AI-agent call to a raw number"
method: POST
path: "/voice/calls"
tags: ["Voice"]
---

# Dispatch one ad-hoc AI-agent call to a raw number

`POST /voice/calls`

## Request

- Base URL: `https://be.graph8.com/api/v1`
- URL: `https://be.graph8.com/api/v1/voice/calls`
- Auth: HTTP bearer

Dispatch a single AI-agent call to an arbitrary number right now.

No dialer session or contact list required - this wraps voice's
``POST /api/call/start`` (`voice/graph8_livekit/routers/call.py:19`),
the one-off "call this number" primitive that previously had no public
surface at all. Places a REAL call and is billable upstream (voice
checks the org's subscription and concurrent-call cap before
dispatching). Send an ``Idempotency-Key`` header to make a retry
safe - every POST on this API already honors it via the app-wide
``IdempotencyMiddleware``, so no extra field is needed here.

Org is pinned server-side; phone numbers are normalized to E.164 by
voice itself (a malformed number 400s with an actionable message).

## Headers

- `Authorization` string, nullable
- `X-Target-Org-Id` string, nullable

## Request body

- VoiceCallStartRequest: Body for dispatching one AI-agent call to an arbitrary number. No dialer session or contact list required - this is the "call this one number right now" primitive (`voice/graph8_livekit/routers/call.py:19`). Places a REAL call and is billable; send an ``Idempotency-Key`` header to make a retry safe (honored automatically by the Developer API's idempotency middleware on every POST - no extra body field needed).
  - `to_phone` string, required: Number to call. Normalized server-side.
  - `from_phone` string, required: Caller ID. Must be one of the org's numbers.
  - `agent_id` string, nullable: Voice agent UUID. Use GET /voice/agents to look up.
  - `entity_type` 'agent' | 'twin', nullable: "agent" or "twin". Optional.
  - `agent_name` string, nullable: Legacy V1 agent-name fallback.
  - `first_name` string, nullable: Contact first name, for the agent's context.
  - `last_name` string, nullable: Contact last name, for the agent's context.
  - `email` string, nullable: Contact email, for the agent's context.
  - `contact_id` string, nullable: CDP contact id, if this call is tied to a known contact.
  - `timezone` string: IANA timezone for the callee.
  - `campaign_id` string, nullable: Optional campaign id for attribution.
  - `studio_campaign_id` string, nullable: Optional Campaign Builder (Studio) campaign UUID.
  - `dry_run` boolean: If true, the call is validated but not actually dispatched.
  - `event_id` integer, nullable: Appointments event-type id the agent can offer to book. Omit if this call has no booking flow.
  - `callback_url` string, nullable: Webhook notified with the call result on completion. Optional.

## Response `201`

Successful Response

- ApiResponseVoiceCallStartResponse
  - `data` VoiceCallStartResponse, required: Echo of voice's ``AgentDispatchResponse``.
    - `status` string, required
    - `message` string, required
    - `room_name` string, required
  - `pagination` PaginationMeta
    - `page` integer, required: Current page number (1-indexed)
    - `limit` integer, required: Items per page
    - `total` integer, required: Total number of items
    - `has_next` boolean, required: Whether there are more pages
    - `next_cursor` string, nullable: Opaque cursor for the next page; null when there are no more items. Pass it back as the `cursor` query param to fetch the following page without computing page numbers.
    - `total_available` integer, nullable: Search endpoints only: how many records really match, when known. Can be larger than `total`, which is capped at the 10,000 results that can be paged. For company search this is a distinct-company estimate. Null when unknown; absent outside search.
    - `total_is_lower_bound` boolean, nullable: Search endpoints only: true when more records match than `total` shows (the result set is larger than the 10,000 results that can be paged). Absent outside search.
    - `notes` string[], nullable: Search endpoints only: plain-language notes about the result, e.g. that more records match than can be paged, or that a reversed `between` range was put in order.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/graph8/apis/graph8-developer-api.md) · [All operations](https://skmtc.dev/graph8/apis/graph8-developer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/graph8/apis/graph8-developer-api/revisions/2e7cfa0ca921?raw)
