---
title: "Place an outbound call with a text-to-speech / IVR flow"
method: POST
path: "/calls"
tags: ["Calls"]
---

# Place an outbound call with a text-to-speech / IVR flow

`POST /calls`

## Request

- Base URL: `https://api.commpeak.com/portal`
- URL: `https://api.commpeak.com/portal/calls`
- Auth: API key in header `Authorization`

place an outbound call that speaks text to the callee, plays hosted audio, and can collect keypad input and branch on it

## Request body

- CallRequest: An outbound call and the script to run once the callee answers. `flow` steps execute in order unless a `gather` branches to a step `id`. Text is synthesized to speech upstream, so no audio files need to be hosted, though a `playback` step can play one that is.
  - `recipient_phone` string, required: Number to call, E.164 (no leading "+").
  - `sender` string, required: Caller ID presented to the callee, E.164 (no leading "+"). Must be a verified caller ID of the account unless all caller IDs are allowed for it (see `GET /portal/allowed_caller_ids`).
  - `voice` string, nullable: Default voice model id for every `say` step (see `GET /portal/calls/voices`). Defaults to `en_US-amy-medium` upstream.
  - `flow` CallFlowStep[], required: Steps to execute once the callee answers, in order. A `gather` carrying `on_digit` jumps to the step with that `id` instead of continuing.
    - `action` string, required: Step type: `say`, `playback`, `gather`, `dial` or `hangup`.
    - `id` string, nullable: Label for this step, up to 40 characters of letters, digits, "-" or "_". `gather` branch targets refer to it; ids must be unique within a flow.
    - `text` string, nullable: `say`: text to speak (up to 1000 characters).
    - `voice` string, nullable: `say`: voice model id for this step only.
    - `num_digits` integer, nullable: `gather`: number of digits to collect (1-32, default 1).
    - `timeout` integer, nullable: `gather`: seconds to wait for input (1-120, default 10). `dial`: seconds to wait for the bridged leg to answer (1-600, default 30).
    - `callback_url` string, nullable: `gather`: URL the collected digits are POSTed to.
    - `finish_on_key` string, nullable: `gather`: key that ends input early (digit, `*` or `#`).
    - `on_digit` object, nullable: `gather`: maps the digits collected to the `id` of the step to jump to. Omit it, or collect digits with no entry here, to continue with the next step as usual.
    - `on_timeout` string, nullable: `gather`: `id` of the step to jump to when nothing is entered. Omit to continue with the next step.
    - `url` string, nullable: `playback`: URL of a WAV or MP3 file to play. Fetched once and cached; WAV is recommended, MP3 requires `mod_shout` on the switch.
    - `recipient_phone` string, nullable: `dial`: number to bridge to, E.164 (no leading "+").
    - `caller_id` string, nullable: `dial`: caller ID presented on the bridged leg; defaults to the call's `sender`.
  - `status_callback_url` string, nullable: URL notified when the call finishes. See docs/voice-call-backend.md for the payload.

## Response `201`

Successful Response

- CallResponse: Acceptance receipt for `POST /portal/calls`. `call_status` is the state at acceptance time — the terminal state arrives on `status_callback_url`.
  - `status` boolean, required: Whether the call request was accepted.
  - `call_uuid` string, nullable: Identifier of the call; also sent on every callback.
  - `call_status` string, nullable: Call state at acceptance, e.g. `queued`.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/commpeak/apis/commpeak-portal-api.md) - [All operations](https://skmtc.dev/commpeak/apis/commpeak-portal-api/llms.txt) - [OpenAPI document](https://skmtc.dev/commpeak/apis/commpeak-portal-api/revisions/df57b0c16367?raw)
