Recipes← all recipesView on GitHub

Text the caller during the call

Messagingin-call SMS

Have an AI agent tool text the caller during a live voice call without exposing the phone number to the model.

Also called send a link by text during a call, in-call SMS

sms

The claim

A tool result can carry a SWML document, and that document can run send_sms. The handler in this recipe builds one with FunctionResult.send_sms. It addresses the text to caller_id_num, which the platform posts in the body of every tool call, and sends it from a number in your environment. The tool takes only an appointment argument, so the model cannot choose where the text goes.

Why it holds

Docs: the send_sms reference. The SWAIG tool webhook lists caller_id_num in the request body.

How it works

def text_confirmation(self, args, raw_data):
    to = (raw_data or {}).get("caller_id_num")
    if not to or not to.startswith("+"):
        return FunctionResult("NO_NUMBER: ... Read the details back instead.")
    return FunctionResult("The details are on their way to your phone.").send_sms(
        to_number=to, from_number=SMS_FROM, body=body, tags=["appointment"])

The function result the platform receives:

{"response": "The details are on their way to your phone.",
 "action": [{"SWML": {"version": "1.0.0", "sections": {"main": [
   {"send_sms": {"to_number": "+15557654321", "from_number": "+15551230000",
                 "body": "Ridgeline Cycles: your workshop appointment is ...",
                 "tags": ["appointment"]}}]}}}]}

send_sms is the SDK method and the wire verb, inside an action whose key is SWML. When caller_id_num is absent or does not start with +, or the appointment is empty, the handler returns a response and no action, and the platform sends nothing.

The swml/ surface does the same in a plain document: answer, then send_sms addressed to %{call.from}, then play. call.from is the caller’s number in the SWML variables reference, so that document attempts a send_sms on every call. The agent version texts only when the handler receives a non-empty appointment.

Limitations

The handler learns nothing about delivery. Per the reference, the verb sets send_sms_result to success or failed on the call; this recipe does not read it.

The handler sends nothing when caller_id_num is absent or does not start with +, and tells the model to read the details aloud instead.

What to change first

Add a phone property to the tool’s parameters and run the verifier. The first assertion fails, which is the point: once the model can supply a number, the caller no longer binds the send.