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

# SMS and phone numbers

> Buy a phone number, bind it to your agent, register it for US messaging, and text with end users over SMS and MMS

After this guide, end users can text a phone number your organization owns and get answers from your [agent](/concepts/agents), and your code can text them first. The number is bought and managed from `lua channels`; it always carries voice as well, so the same setup is the first half of [Voice calls](/channels/voice-calls).

*Verified against lua-cli 3.33.0.*

**Before you begin**

* A project created with `lua init`, signed in with `lua auth configure`, with `orgId` in its project config.
* A [voice](/concepts/voice) defined with `defineVoice`, registered on `LuaAgent.voices`, and pushed with `lua push voice`. Binding a number refuses to proceed without one, because every number answers calls too.
* For a US number: the legal entity, EIN, address, and opt-in details your carrier registration needs.

<Steps>
  <Step title="Terminal: purchase an SMS-capable number">
    Open the channel menu and choose **Manage phone numbers**, then **Purchase a number**. Answer `Y` to `Allow customers to text this number too? (otherwise voice-only)`; `N` buys a voice-only number that never receives SMS.

    ```bash theme={null}
    lua channels
    ```

    The purchase flow asks for a country (ISO code, default `US`) and an optional digit pattern, lists up to 50 numbers with country, type, and modality (`voice + SMS` or `voice only`), and confirms with `charges may apply` before buying. The separate **Search available numbers** item also shows monthly cost. Modality is fixed at purchase.
  </Step>

  <Step title="Terminal: bind the number to your agent">
    After the purchase the menu offers `Bind <number> to agent <agentId> now?` and asks which voice answers inbound calls. Accept, or come back later with **Bind a number to this agent**.

    A number belongs to one agent at a time; binding it elsewhere fails with `Phone number <n> is already bound to agent <id>. Unbind it from that agent first.` Unbinding keeps the number in the organization; **Release a number** gives it up for good.
  </Step>

  <Step title="Optional: Register a US number for messaging">
    US carriers require a registered identity behind application traffic. Registration is done over the REST API or in the admin dashboard ; there is no CLI command.

    <Tabs>
      <Tab title="Local number (10DLC)">
        Register a brand with `POST /developer/orgs/<orgId>/10dlc/brand`: `entity_type` (`SOLE_PROPRIETOR`, `PRIVATE_PROFIT`, `PUBLIC_PROFIT`, `NON_PROFIT`, or `GOVERNMENT`), `display_name`, `company_name`, `ein`, `vertical`, `phone`, `email`, and a postal address. Sole proprietors add `first_name`, `last_name`, and `mobile_phone`; public companies add `stock_symbol`, `stock_exchange`, and `verification_email`. Then register a campaign with `POST …/10dlc/campaign`: `usecase` (for example `CUSTOMER_CARE`), a `description`, one to five sample messages, the opt-in, opt-out, and help messages, `message_flow_details` with `pricing_disclosure: true`, and `tc_agreed: true`. Link the number with `POST …/phone-numbers/<msisdn>/10dlc/link` (digits only, no `+`), passing `campaignId` when the organization has more than one campaign; the response lists non-blocking `warnings`.

        Brand status is `UNVERIFIED`, `VERIFIED`, `VETTED_VERIFIED`, `ACTIVE`, `INACTIVE`, `SUSPENDED`, or `DELETED`; campaign status is `ACTIVE`, `EXPIRED`, `DEACTIVATED`, `SUSPENDED`, or `DELETED`. `POST …/10dlc/brand/sync` and `…/campaign/sync` refresh them from the registry.
      </Tab>

      <Tab title="Toll-free number">
        SMS on a US toll-free number is enabled by a toll-free registration: `POST /developer/orgs/<orgId>/phone-numbers/<msisdn>/tfn` with `business` (name, address, `company_website`, contact, `entity_type`, `tax_id_type`, `tax_id_issuing_country`), `use_case`, `message_content` (one sample), `opt_in` (`workflow`, screenshot `images`, optional keywords and confirmation and help messages), `estimated_monthly_volume` (one of `10`, `100`, `1,000`, … `10,000,000+`), and `additional_information`. Omit `status` to save a `DRAFT`; send `status: "SUBMITTED"` to submit. `PATCH …/tfn-registrations/<id>` edits a draft or submits it.

        The number moves through `DRAFT`, `PENDING_REVIEW`, and `CARRIERS_REVIEW` to `REGISTERED`, `REJECTED`, `UPDATES_REQUIRED`, or `BLOCKED`; `GET …/tfn` syncs the status and `GET …/tfn-registrations/<id>/events` returns the review history.
      </Tab>
    </Tabs>

    Creating a brand, campaign, or toll-free registration and linking a number need the `telephony:provision` scope; editing a record or submitting a draft with `PATCH` needs `telephony:write`, and unlinking needs `telephony:manage`.&#x20;
  </Step>

  <Step title="Verify">
    Text the number from your phone. The reply is the agent's answer, prefixed with the registered brand name and followed by `Reply STOP to opt out, HELP for help.` and, on US numbers, `Msg & data rates may apply. Msg frequency varies.` Both are added once, even if the model wrote them itself. Confirm the turn with `lua logs --type agent_response`.
  </Step>
</Steps>

## Channel behavior

| Capability                               | Supported                                                                                                                                                                                                                                                                 |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Inbound text                             | Yes; `Lua.request.channel` is `sms`                                                                                                                                                                                                                                       |
| Inbound media (MMS)                      | Yes; `Lua.request.channel` is `mms`; the agent receives the caption, or a placeholder such as `[Image: <url>]`                                                                                                                                                            |
| Outbound media and formatting components | No; replies are plain text, `:::` blocks appear verbatim, reactions are stripped                                                                                                                                                                                          |
| Proactive sends                          | Yes; `Channels.send({ channel: 'sms', to: { phoneNumber } })` to any E.164 number, from the agent's bound number                                                                                                                                                          |
| Opt-out keywords                         | `STOP`, `STOPALL`, `UNSUBSCRIBE`, `CANCEL`, `END`, `QUIT`, `OPT OUT`, `OPTOUT`, `REMOVE` as the whole message; `START` or `UNSTOP` re-subscribes; `HELP` or `INFO` gets a templated help reply with the brand name, an optional support line, and the US rates disclosure |
| Brand prefix                             | From the 10DLC brand, the toll-free registration, or the channel's fallback brand name                                                                                                                                                                                    |

An opted-out subscriber's texts are dropped without a reply, and `Channels.send` to them throws `Recipient has opted out of SMS from this sender`. Opt-out is per campaign when the number is linked to one, otherwise per number. Every inbound text records a last interaction, so `user.send(…)` can reach the end user over SMS later; see [Send proactive messages](/build/send-proactive-messages).

## Limits

| Limit                                      | Value                                                                              |
| ------------------------------------------ | ---------------------------------------------------------------------------------- |
| Numbers returned per search                | 50                                                                                 |
| Agents a number can be bound to            | 1                                                                                  |
| 10DLC brand `display_name`, `company_name` | 100 characters; `ein` 50                                                           |
| 10DLC campaign `description`               | 40 to 4,096 characters; samples 20 to 1,024, up to five                            |
| Toll-free `message_content`                | 1,000 characters; `additional_information` 350; confirmation and help messages 160 |

## Troubleshooting

<AccordionGroup>
  <Accordion title="This agent has no LuaVoice.">
    Binding needs an active voice because the number also takes calls. Add a `defineVoice` voice to `LuaAgent.voices`, run `lua push voice`, then rerun `lua channels`.
  </Accordion>

  <Accordion title="No phone/SMS channel configured">
    The phone channel `Channels.send` resolved has no number on it. When no number is bound at all, the error is `Cannot send to sms without an existing conversation` instead. Bind a number bought with texting allowed; a voice-only number is attempted and rejected by the carrier, not by this check.
  </Accordion>

  <Accordion title="Replies arrive without a brand prefix">
    No 10DLC brand, toll-free registration, or fallback brand name resolved for the sending number. Finish the registration, or set the fallback brand name in the admin dashboard .
  </Accordion>
</AccordionGroup>

## Next steps

<Columns cols={2}>
  <Card title="Voice calls" href="/channels/voice-calls">Answer and place calls on the same number.</Card>
  <Card title="Send proactive messages" href="/build/send-proactive-messages">Reach end users first over SMS and other channels.</Card>
  <Card title="About channels" href="/concepts/channels">Inbound and outbound channel vocabularies.</Card>
  <Card title="Channels reference" href="/reference/sdk/channels">`Channels.send` parameters and delivery status.</Card>
</Columns>
