Logo
Search
Docs

Overview

What this module covers, the edit-only surface, materialization on first open, and the response envelope.

What this reference explains

This module covers phone numbers end to end on the panel API: search purchasable inventory, purchase an unassigned number, list numbers (including unassigned), retrieve configuration, and update inbound routing / fallback / webhook / SMS. Release is not covered here.

Assistant create flows may still purchase and attach a number at create time when one is provided; purchasing here is the two-step path when you buy first and assign later.

Two-step purchase

  • Step 1 — purchase. GET /phone-numbers/available searches inventory; POST /phone-numbers purchases and registers the number with no inbound target (assistant / squad / workflow all null).
  • Step 2 — assign. PUT /phone-numbers/{id} sets exactly one of vapi_assistant_id, vapi_squad_id, or vapi_workflow_id.
  • List rows include an unassigned boolean when no inbound target is set.

List & materialise

  • List rows are summaries. They are built from assistants that currently carry a number, unioned with any configuration rows that already exist (including unassigned purchases and squad- or workflow-routed numbers). A row's id may be null until that number has been opened for editing at least once — except numbers created via POST /phone-numbers, which already have a configuration row.
  • Opening a number materialises it. Retrieving a number that only exists on an assistant creates its local configuration row by reading the live voice platform. Every retrieval after that reuses the stored row.

Clearing semantics

On update, server and fallback_destination distinguish "absent" from "present but empty": omitting the key entirely leaves the block untouched, while sending it as null or {} explicitly clears the whole block. A non-empty object merges onto the current value, so a partial update (for example just {"credentialId": ""}) does not wipe out an existing url or headers.

Inbound routing is exclusive

A number routes inbound calls to exactly one target: an assistant (vapi_assistant_id), a squad (vapi_squad_id), or a workflow (vapi_workflow_id). Setting more than one of these in the same request is rejected before anything is written. Setting one of them clears the other two, both locally and on the live platform.

Identifiers

The {id} path parameter accepts the number's digits (E.164 without the leading +) or its full E.164 form (with +); once a configuration row exists, its numeric row id also resolves. There is no separate public UUID for a phone-number configuration — the phone number itself is the primary lookup key.

Response envelope

The panel envelope. sms_available (whether the SMS toggle is meaningful for this number's provider) is computed and attached only on the retrieve endpoint, not on update. The retrieve and update endpoints may also carry an internal mirror of the live platform's own phone-number resource; it is not part of the documented contract and is omitted from the examples on this page.

Feature availability

This module is gated by the phone_numbers feature. When disabled, every endpoint under /phone-numbers returns 403 with {"message":"This feature is not enabled for your account. Please contact your administrator.","feature":"phone_numbers"}.