---
title: "Update Phone Number"
method: PATCH
path: "/v1/agent/phone-numbers/{phone_number_id}"
tags: ["Phone Numbers"]
---

# Update Phone Number

`PATCH /v1/agent/phone-numbers/{phone_number_id}`

## Request

- Base URL: `https://api.fish.audio`
- URL: `https://api.fish.audio/v1/agent/phone-numbers/{phone_number_id}`
- Auth: HTTP bearer

Change the label and/or repoint the number at another agent — the
deployment-pipeline move (rebind from the staging agent to the production
one). Send `agent_id: null` to unbind; unbound numbers ring busy. The
agent must live in the number's workspace. Rebinding is a routing-table
update resolved on the next inbound call; nothing about the number itself
is reprovisioned.

Managed `twilio` numbers also accept `transfer_caller_id`, which picks
the number a transfer target sees (cold and warm alike), and
`retry_caller_id_sync` to re-apply it after a failed synchronization. Read
`caller_id_sync_status` on the response. Imported `sip` numbers return 409
for either field because their carrier owns the setting.

Every field here is a number setting, not agent config: changes apply
from the next call without publishing, and publishing or rolling back the
agent never changes them. Cold-transfer caller ID applies once
`caller_id_sync_status` is `synced`.

## Path parameters

- `phone_number_id` string, required

## Request body

- PublicPhoneNumberUpdatePayload
  - `label` string, nullable
  - `agent_id` string, nullable: Agent that answers this number's inbound calls. Explicit null unbinds; omit the field to keep the current binding.
  - `transfer_caller_id` 'agent_number' | 'original_caller', nullable: Managed `twilio` numbers only: the caller ID a transfer target sees, `agent_number` (this number) or `original_caller` (the caller's own number). Applies to cold and warm transfers. It is a number setting, not agent config: no publish is needed and agent rollbacks leave it alone. Warm transfers follow it from the next call, cold transfers once `caller_id_sync_status` is `synced`. The deprecated boolean `cold_transfer_use_original_caller` is still accepted in its place.
  - `retry_caller_id_sync` boolean: Re-apply the current caller ID policy after a failed synchronization.

## Response `200`

Request fulfilled, document follows

- object
  - `phone_number_id` string, required
  - `workspace_id` string, required
  - `phone_number` string, required: E.164, e.g. +14155550123.
  - `provider` 'livekit' | 'twilio' | 'sip' | 'whatsapp', required
  - `label` string
  - `agent_id` string, nullable, required: Inbound calls route to this agent; unbound numbers ring busy.
  - `transfer_caller_id` 'agent_number' | 'original_caller', nullable: Managed `twilio` numbers: the caller ID a transfer target sees, on cold and warm transfers alike. `agent_number` shows this number, `original_caller` shows the caller's own number (a warm transfer falls back to this number when the caller withholds theirs). `null` for imported `sip` numbers, whose carrier decides.
  - `cold_transfer_use_original_caller` boolean, nullable: Deprecated, read `transfer_caller_id`. True when it is `original_caller`.
  - `cold_transfer_use_original_caller_effective` boolean, nullable: Deprecated, read `caller_id_sync_status`. Whether the carrier has confirmed the original caller policy for cold transfers, `null` while unknown.
  - `caller_id_sync_status` 'synced' | 'pending' | 'error' | 'carrier_managed': `synced` once the carrier confirmed the policy, `pending` while it is being applied, `error` when the last attempt failed (send `retry_caller_id_sync`), `carrier_managed` for imported `sip` numbers.
  - `caller_id_sync_error` string: Why the last synchronization failed; empty otherwise.
  - `status` 'provisioning' | 'active' | 'error' | 'released', required
  - `status_detail` string: What failed when status is `error`; empty otherwise.
  - `supports_outbound` boolean: Whether the number can place calls (outbound and warm-transfer consult legs): managed `twilio` always, imported `sip` only when a termination was configured.
  - `termination_uri` string, nullable: Imported `sip` numbers: the customer trunk's termination host.
  - `inbound_auth_username` string, nullable: Imported `sip` numbers: the inbound digest username. Passwords are never echoed.
  - `inbound_allowed_addresses` string[]: Imported `sip` numbers: allowed source IPs/CIDRs.
  - `termination_transport` string, nullable: Imported `sip` numbers: termination transport.
  - `termination_auth_username` string, nullable: Imported `sip` numbers: the termination digest username. Passwords are never echoed.
  - `termination_headers` object: Imported `sip` numbers: custom SIP headers added to every outbound INVITE through the termination.
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required

## Other responses

- `401`: No permission -- see authorization schemes
- `404`: Nothing matches the given URI
- `409`: Request conflict
- `422`
- `503`: The server cannot process the request due to a high load

## Changes

- **2026-11-03** `42ac421f7a12`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/fish/apis/fishaudio-openapi/changes/v1/agent/phone-numbers/:phone_number_id/patch.md)

---

[API](https://skmtc.dev/fish/apis/fishaudio-openapi.md) - [All operations](https://skmtc.dev/fish/apis/fishaudio-openapi/llms.txt) - [OpenAPI document](https://skmtc.dev/fish/apis/fishaudio-openapi/revisions/42ac421f7a12?raw)
