> ## Documentation Index
> Fetch the complete documentation index at: https://docs.poly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Confirm caller ID before sending SMS

This pattern covers a very common voice + SMS flow: the agent has the caller's number from the inbound call, confirms the last four digits with the caller, and sends an SMS to that number. If the caller's number is not available (for example, in a chat session), the agent asks for it instead.

## Files involved

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
functions/start_function.py           ← stash caller_number at call start
functions/caller_number_confirmed.py  ← check presence, compare last four
config/sms_templates.yaml             ← the SMS template (alongside other templates)
topics/Send Booking Link.yaml         ← topic that triggers the flow
```

## start\_function.py

Stash the raw `caller_number` at call start so it is available throughout the conversation.

<Warning>
  **`start_function.py` may already exist**

  If your project was set up via Quick Agent Setup, `start_function.py` likely already contains initialization logic. Add the `conv.state.caller_number` line to the existing function rather than replacing the file.
</Warning>

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from _gen import *  # <AUTO GENERATED>


def start_function(conv: Conversation):
    conv.state.caller_number = conv.caller_number
    return str()
```

## caller\_number\_confirmed.py

Called when the caller has confirmed (or declined) sending the SMS. Branches on whether `caller_number` is present, then validates the last-four match before sending.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from _gen import *  # <AUTO GENERATED>


@func_description(
    "Called after the caller confirms or provides a number for us to send the SMS to. "
    "confirmed: True if they confirmed the number on file, False if they want to use a different one. "
    "provided_number: the number they provided if confirmed is False."
)
@func_parameter("confirmed", "Whether the caller confirmed the number on file")
@func_parameter("provided_number", "The number the caller provided if confirmed is False; pass an empty string if confirmed is True")
def caller_number_confirmed(conv: Conversation, confirmed: bool, provided_number: str):
    if confirmed and conv.state.caller_number:
        to_number = conv.state.caller_number
    elif provided_number:
        to_number = provided_number
    else:
        return "Ask the caller to provide the number where we should send the link."

    conv.send_sms_template(to_number=to_number, template="booking_link")
    return "Tell the caller the link has been sent and ask if there is anything else you can help with."
```

## Send Booking Link.yaml

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
enabled: true
example_queries:
  - Can you send me the booking link?
  - Can you text me a link?
  - Send me the details by text
  - I'd like a link to book online
content: |-
  The booking link is available by SMS.
actions: |-
  ## If the caller's number is available
  Tell the caller you can send the link to the number ending in the last four digits of $caller_number.
  Ask them to confirm or provide a different number.
  Use {{fn:caller_number_confirmed}} once they respond.

  ## If the caller's number is not available
  Ask the caller for the number where we should send the link.
  Use {{fn:caller_number_confirmed}} with confirmed=False and the number they provide.
```

<Warning>
  **Prose conditionals and empty variables**

  The topic actions above use a natural-language conditional on `$caller_number`. This works when the variable is populated, but can behave unreliably if the variable is always empty (for example, in chat). If you need strict branching, move the presence check into `caller_number_confirmed` and call it unconditionally from the topic action.
</Warning>

## SMS template (config/sms\_templates.yaml)

All SMS templates are defined in a single `config/sms_templates.yaml` file under the `sms_templates` key.

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
sms_templates:
  - name: booking_link
    text: "Here's your booking link: https://book.example.com"
    env_phone_numbers:
      sandbox: ""
      pre_release: ""
      live: ""
```

## Related pages

<CardGroup>
  <Card title="SMS templates" href="/adk/reference/sms">
    Reference for SMS template structure and variable substitution.
  </Card>

  <Card title="Variables" href="/adk/reference/variables">
    How `conv.state` variables are discovered and referenced.
  </Card>

  <Card title="Anti-patterns" href="/adk/concepts/anti-patterns">
    Why prose conditionals on variable presence are unreliable.
  </Card>

  <Card title="Conversation object reference" href="https://docs.poly.ai/tools/classes/conv-object">
    Full reference for `conv.caller_number`, `conv.send_sms_template`, and all other `conv` attributes.
  </Card>

  <Card title="Start function (platform)" href="https://docs.poly.ai/tools/start-function">
    When start function runs, what it can access, and how to use it for initialization.
  </Card>

  <Card title="SMS setup (platform)" href="https://docs.poly.ai/sms/introduction">
    Configuring SMS channels, sender numbers, and template structure.
  </Card>
</CardGroup>
