Skip to main content
An agent is a prompt plus a voice engine. Everything else — the number, the trunk, the call — is wiring around it.
voice is covered in Voice engines and Compose a voice engine. This page is about the rest.

Where each value comes from

Most fields are yours to write. These are the ones that reference something else, and the endpoint that lists the valid values: An id belonging to another account is reported as a 404, not a 403: whether a resource exists on someone else’s account is not information this API gives out.

Testing an agent

The agent rings the number, speaks one phrase and hangs up. It answers “is my trunk configured, and does this voice sound the way I expected” in a few seconds without anyone having to hold a conversation with a robot. phrase overrides what it says; the default is the agent’s own opening_message, which is what a real caller would hear first.
A test call is a real call. It rings a real phone over your own carrier, and the meter runs exactly as it does on any other call — there is no free test mode. Idempotency-Key is required for the same reason it is on POST /v1/calls.
For an actual conversation, place an ordinary call with POST /v1/calls. Human transfer is deliberately switched off during a test call, so a test cannot tell you whether a transfer destination answers.

Human transfer

When a caller asks for a person, the agent can hand the live call to one.
The model is only ever told the id and the name. Numbers are resolved server-side at dial time, so an agent that invents a destination cannot dial an arbitrary number — the worst it can do is name one that does not exist. That is why destinations are a list you authorise rather than a number the model produces.
Three rules are enforced when the agent is saved, because each of them fails on a live call otherwise, in front of a customer who has just asked for a person:
  • Destination ids must be unique.
  • default_destination_id must name an enabled destination.
  • enabled: true needs at least one enabled destination.
max_transfers_per_call stops a loop where the agent keeps re-dialling someone who is not there. With return_to_agent_on_failure, a destination that does not pick up hands the caller back to the agent rather than dropping the line.
Transfers happen over your SIP trunk, by bridging a second leg. They are unavailable on a test call and in the in-browser agent test, neither of which has a second leg to bridge.

What happened on a transfer

GET /v1/calls/{id} carries a transfers array, one entry per attempt:
ring_duration_ms is usually the fastest way to tell two very different failures apart: a long ring ending in no_answer is a person who was not at their desk, while a failure in the first second is nearly always configuration — a number your carrier will not dial, or one it does not believe you own. sip_cause is the raw Q.850 code from the carrier for the cases where that distinction is not obvious.

Changing an agent

PATCH changes only the fields you send. Two of them are replaced whole rather than merged, because merging them would be ambiguous:
  • voice — send the complete configuration.
  • human_transfer — send the complete configuration, including every destination you want to keep. This is why destinations has no default: a body of {"human_transfer": {"enabled": false}} is rejected rather than quietly emptying your destination list.