zoxaAI
Homepage
API ReferenceInbound Bindings

Inbound Bindings overview

How API-first inbound bindings work — registration, lookup, mutation, and deregistration.

An inbound binding is the link between a phone number on your provider (Twilio / Vobiz / Tata Smartflo) and an agent in zoxaAI. For webhook providers (Twilio / Vobiz), the number rings → the provider POSTs to zoxaAI → the dispatcher looks up the binding, verifies the signature, and bridges the call to the agent. For streaming-native Smartflo, the media stream arrives at the config's signed WSS URL and the binding is matched by dialed DID — credentials come from the saved telephony config at registration, not inline (see Smartflo setup).

Lifecycle

[POST /call type=inbound]      → upserts binding (idempotent on provider+phoneNumber)
                                  → PATCHes provider's number/app to point at our webhook
                                  → stores credentials + agent snapshot

[GET / PATCH / DELETE]          → manage the binding's lifecycle without re-provisioning
                                  (PATCH only changes the agent;
                                   DELETE deprovisions on the provider side)

[provider POSTs to /telephony/run] → dispatcher matches (provider, dialedNumber)
                                  → verifies signature with binding's creds
                                  → creates a calls row tied to the binding
                                  → returns provider XML opening the WS to the agent

Endpoints

MethodPathPurpose
POST/call type=inboundRegister / re-register (idempotent upsert).
GET/telephony/inbound/bindingsList your registrations.
GET/telephony/inbound/bindings/{id}Detail incl. credentials in debug mode.
PATCH/telephony/inbound/bindings/{id}Swap the agent without re-provisioning the provider.
DELETE/telephony/inbound/bindings/{id}Deprovision + delete.

Key design points

BehaviorRationale
(provider, phoneNumber) is the unique keyOne number can be bound to one agent. Re-POST overwrites; no duplicates.
Provider webhook URL is set at register time, not at PATCHPATCH is the cheap path for swapping agents. Use re-POST if credentials changed.
Credentials stored encrypted (Fernet) in prodDEBUG_TELEPHONY_CREDS_PLAINTEXT flag controls plaintext vs. encrypted storage. The detail endpoint always returns masked values (last 4 chars) regardless.
Inbound bindings win over dashboard telephony_phone_numbers for the same numberAPI-first explicitly takes precedence so re-registering steals routing back.

On this page