Skip to main content
A trunk is the SIP connection that carries calls between Anyreach and a carrier. Most organizations use Anyreach-managed trunks and never touch this configuration. This page covers two advanced workflows: bringing your own carrier (BYOC) with a customer-owned trunk, and deploying an agent as a dialable SIP endpoint. Customer-owned trunks can be managed from the dashboard under Phone Numbers → Trunks, or through the API at https://api.anyreach.ai. Deploying an agent as a SIP endpoint remains API-only.
Managed trunks are provisioned for you and are read-only — they can’t be edited or deleted from the dashboard or the API.

Managed vs customer-owned trunks

Every trunk belongs to one organization. A trunk with a managed_account_id is provisioned and operated by Anyreach (for example a managed Twilio account) and is read-only over the API. A trunk with no managed_account_id is customer-owned: you control its inbound and outbound configuration. This is the BYOC path.
When to use BYOC: choose a customer-owned trunk when you must route calls through your own carrier or PBX rather than an Anyreach-managed account. Otherwise use a managed trunk.

Managing trunks from the dashboard

Open Phone Numbers → Trunks to list, create, edit, and delete your customer-owned trunks. Each trunk shows its name, type (inbound, outbound, or both), and configured caller-ID header. The editor has an Inbound section (caller-ID SIP header, noise cancellation, media encryption, allowed addresses) and an Outbound section (carrier address, SIP auth, transport, media encryption), each toggled on independently. Managed trunks appear with a Managed badge and are read-only — their edit and delete actions are disabled.
Editing outbound settings requires re-entering the SIP auth password (it is never shown back to you). Leave the password blank when editing to keep the current credentials unchanged.

Trunk CRUD (API)

All trunk endpoints live under /core/trunks and require the trunks:read or trunks:manage scope. Reads accept either scope; writes require trunks:manage. The create body takes a name and optional inbound_config and outbound_config. The organization is taken from your token, so you do not send organization_id.
The X-Anyreach-Org header is required only for user personal access tokens (pat_). Organization API keys (ak_) carry their organization implicitly.

Inbound config

inbound_config governs calls arriving from your carrier.

Reading caller ID from a SIP header

By default, Anyreach derives the caller’s number (the conversation’s user_id) from the call’s parsed From number. Some carriers instead carry the original caller number in a custom SIP header — for example X-Original-ANI when calls pass through an intermediary that rewrites the From number. Set caller_id_header to the header name (e.g. X-Original-ANI) and Anyreach will read the caller’s number from that header on inbound calls, falling back to the parsed From number when the header is absent. Leave it blank to keep the default behavior. This applies to inbound calls arriving on the trunk that owns the phone number. Configure it in the dashboard under Phone Numbers → Trunks, or by setting caller_id_header in the trunk’s inbound_config over the API.

Mapping SIP headers to custom metadata

Carriers and upstream PBXs often attach context to a call as custom X- headers — an account number, a routing tier, a ticket reference. Anyreach captures the X- headers on an inbound call and records them on the conversation’s sip field as sip.h.<lowercased-header-name>. Capture is bounded: values longer than 1024 characters are dropped, and at most 64 headers are kept (in alphabetical order). The caller number and the other standard sip.* fields are never affected by those limits. To promote specific headers into the conversation’s custom_metadata — where they are filterable, exported, and available as prompt variables — set header_metadata_mappings to a {metadata_key: header_name} map:
An inbound call carrying X-Account-Id: ACC-42 then produces custom_metadata.account_id == "ACC-42", usable in the agent’s prompt as {{ account_id }}. Headers the call did not carry are simply absent. Mappings are validated when you save the trunk:
  • Header names are matched case-insensitively and stored in lowercase.
  • Only X- headers can be mapped. To read a standard header such as P-Asserted-Identity, use caller_id_header instead.
  • Each metadata key must be a valid identifier, must not be a reserved word (if, None, …), and cannot be one the platform already uses (attempt_id, anyreach_campaign, custom_metadata, agent_metadata, conversation_metadata, state, trunk_metadata).
  • A trunk may map at most 20 headers, and values longer than 1024 characters are skipped.
Because the mapping is a property of the trunk, two carriers that name the same value differently can both normalize onto one key — the agent sees a stable account_id either way.
Header capture is applied when a trunk’s configuration is saved, so a trunk created before this feature shipped starts capturing X- headers the first time it is updated — including the update that sets header_metadata_mappings. Captured header values are stored with the conversation and appear in conversation exports; map only headers you intend to retain.

Outbound config

outbound_config defines how Anyreach connects to your carrier to place calls. address, auth_username, and auth_password are required when you supply an outbound config.

Enum values

Deploy an agent as a SIP endpoint

Instead of (or in addition to) attaching a phone number, you can expose a published agent as a dialable SIP URI. The agent then answers calls placed directly to its SIP address. The URI has the form:
1

Publish the agent

The agent must have at least one published version. Deploying an agent with no published version returns 409.
2

Deploy as SIP

Call POST /core/agents/{id}/deploy-as-sip with the agents:manage scope. The response returns the SIP URI and deployed: true. The operation is idempotent.
3

Dial the endpoint

Route calls to the returned uri from your SIP infrastructure to reach the agent.
4

Undeploy when done

Call DELETE /core/agents/{id}/deploy-as-sip (scope agents:manage) to remove the endpoint. Returns 204 and is idempotent.

SIP endpoint state on the agent

The agent GET response includes a sip_endpoint object reflecting current state, or null when state cannot be resolved.

Errors

Telephony overview

How phone numbers, trunks, and agents fit together.

Telephony API reference

Full endpoint reference for telephony resources.