Look up the caller and branch inside the call flow
Voicedata-driven call routing (CRM lookup)
Have the call itself fetch the caller's record from your API, branch on a field of the reply, and still reach a human when the lookup fails.
Also called CRM lookup during a call, screen pop routing, route by customer tier, database-driven IVR
swmlcall-fabricserverless
The claim
Routing on data usually means a server of yours in the call path: SignalWire fetches a document from you, you call your database, you answer. The request method removes that hop. The hosted document calls your API itself, and the next verb reads the answer.
Why it holds
Three parts. request sends the caller’s number to your endpoint and, with save_variables true, parses the JSON reply into variables. switch then branches on request_response.tier, one of those parsed fields. Around both, a cond checks request_result, so a CRM that is slow or down sends the call to the main line instead of dropping it.
The request reference describes save_variables as “Store parsed JSON response as variables” and gives request_result as “Either success or failed”. It references a saved field as ${request_response.<field>}. switch.variable takes the name on its own, the way the IVR recipes pass prompt_value.
Two defaults are worth changing. timeout and connect_timeout are both 0, meaning no timeout, so a hung CRM would hold the call open. This document sets five and three seconds and then handles the failure.
cond takes an array, and add_verb takes a dictionary, so add_verb("cond", [...]) returns False and adds nothing. The array is appended to the document instead. get_document() hands back the live document, so the hangup added after it still lands last. Every other verb goes through add_verb, which validates it against the bundled schema as it is added.
The whole document is hosted as a Call Flow, the same relayml and flow_data pair build-an-ivr-without-a-server uses, so nothing of yours is in the call.
Limitations
The verifier proves the document and the requests. Whether the platform substitutes %{call.from} into the body and resolves request_response.tier at runtime is live behaviour, described in the request reference and not asserted here.
Your endpoint is in the call path even though your call server is not. Its latency is the caller’s silence, which is what the two timeouts bound.
The record is fetched once, at the start. A branch that needs fresh data later in the call makes a second request; each one overwrites request_response.
What to change first
Delete save_variables and run the verifier. The document still validates, because the field is optional, and the assertion fails. On a real call the switch would find no request_response.tier and take its default, so every caller reaches the main line and nothing errors.