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

# SMS Channel

The SMS channel lets a VIVI agent send and receive text messages over a real phone number, either local 10DLC or toll-free. Inbound messages route to the agent like any other channel; outbound sends flow through VIVI's consent middleware so every recipient is opted in before the agent can text them.

***

## Prerequisites

SMS in the United States and Canada is regulated by **the CTIA** (industry body) and **major carriers** (AT\&T, T-Mobile, Verizon). They require explicit, verifiable consent from every recipient before you send them a message.

**Acceptable ways to collect consent:**

<CardGroup cols={3}>
  <Card title="Web Form" color="#2563eb" icon="file-signature">
    A checkbox next to the phone field on your sign-up page, with disclosure text (e.g. "I agree to receive transactional texts from {brand}. Msg & data rates may apply. Reply STOP to opt out.")
  </Card>

  <Card title="In-Person (Verbal)" color="#2563eb" icon="handshake">
    The contact gives consent at point of sale or during a service interaction; staff records it in your CRM.
  </Card>

  <Card title="Reply-In (Text-to-Join)" color="#2563eb" icon="comment-dots">
    The contact texts a keyword (e.g. `JOIN`) to your number first. This is the only flow that doesn't require collection elsewhere, but is also the lowest-volume.
  </Card>
</CardGroup>

<Warning>
  VIVI will not send messages for you if consent isn't on file. The consent middleware will block the send until the recipient texts in to confirm.
</Warning>

You also need to know **what use case** you'll be texting for. Toll-free numbers and A2P-registered local numbers are reviewed by Twilio + carriers against a declared use case. "Transactional notifications" and "customer care" are the easy approvals; marketing is allowed but requires more justification.

***

## Create an SMS Channel

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/ksg-ea85c748/documentation/core-concepts/channels/images/docs-3-sms-creation.png" alt="" />
</Frame>

<Steps>
  <Step title="Open Channels">
    From the workspace sidebar, expand **Agents → Channels**. Hit **Add New** in the top-right to start.
  </Step>

  <Step title="Name the channel and pick SMS">
    Enter a **Channel Name** and select **SMS** from the **Type** dropdown.

    <Note>
      The channel name is both your internal-facing label *and* the`{brand}`value rendered into consent templates (e.g. "Acme Restore" → recipients see "Reply STOP to unsubscribe from Acme Restore"). Pick your trading name, not your legal entity name.
    </Note>
  </Step>

  <Step title="Fill in the SMS-specific fields">
    Selecting SMS expands the modal with:

    <CardGroup cols={2}>
      <Card title="Timezone" color="#2563eb" icon="clock">
        IANA timezone (e.g. `America/New_York`). Used for time-of-day greetings. If left blank the agent will assume UTC is the timezone.
      </Card>

      <Card title="Enable MMS" color="#2563eb" icon="image">
        Toggle on if you'll send picture messages. Restricts the number search to MMS-capable numbers.
      </Card>

      <Card title="Country" color="#2563eb" icon="earth-americas">
        **Required.** US, Canada, or Puerto Rico.
      </Card>

      <Card title="Number Type" color="#2563eb" icon="phone">
        **Required.** Enables once country is picked.
      </Card>
    </CardGroup>
  </Step>

  <Step title="Choose Local or Toll-Free">
    <Tabs>
      <Tab title="Toll-Free">
        Best for cross-state messaging, instant provisioning, and broad recipient reach. Throughput up to \~10 msg/sec after verification.

        **Approval time:** 1–5 business days (Twilio TFV review).
      </Tab>

      <Tab title="Local 10DLC">
        Best for local presence and lower per-message cost. Throughput depends on A2P brand trust score.

        **Approval time:** Brand same-day–48h; Campaign 1–5 business days.
      </Tab>
    </Tabs>

    <Info>
      If you don't see **Local**, it's off for your workspace. Please contact your Account Admin for more details.
    </Info>
  </Step>

  <Step title="Filter and pick a number">
    After picking a number type, VIVI calls Twilio's availability endpoint and shows a heads-up about compliance requirements, plus optional filters:

    * **Area code** — a specific US area code (e.g. `415`). Skip → results span the whole country.
    * **Vanity pattern** — a digit sequence the number should contain (e.g. `43556` spells `HELLO`), with placement **Anywhere**, **Start**, or **End**. Letters convert to digits automatically.

    Available numbers render as a grid below. Toll-free numbers include 800, 833, 844, 855, 866, 877, and 888 prefixes.
  </Step>

  <Step title="Reserve and save the number">
    Click a number to reserve it and a 60-second hold timer starts ("Number held for 46s — save now to secure it"). If you don't click **Save** in time, the number releases back to Twilio's pool.

    <Warning>
      Local 10DLC numbers are provisioned immediately at Twilio but **can't send a single message** until your A2P brand and campaign are approved. Toll-free numbers can technically send low-volume test traffic during TFV review, but real production volume requires the verification to land.
    </Warning>

    Click **Save**. VIVI provisions the number at Twilio, persists the channel row, and lands you on the channel detail page.
  </Step>

  <Step title="Configure consent templates">
    Switch to the **Consent** tab on the channel detail page and fill in the three required templates (see [Consent Middleware](#consent-middleware) below), then click **Save consent messages**.
  </Step>

  <Step title="Submit verification (toll-free) or register A2P (local)">
    **Toll-free:** Once saved, the **Compliance** hub shows the channel with an **Action required** badge. Submit the 3-step Toll-Free Verification form.

    **Local 10DLC:** Register your A2P brand and campaign before the number can send.

    See the [Twilio Compliance guide](twilio-compliance.md) for the field-by-field walkthrough.
  </Step>
</Steps>

***

## Consent Middleware

Every SMS channel ships with an automated consent layer, which is the CTIA-mandated response templates VIVI's middleware sends on your behalf. Open the channel's **Consent** tab; each sub-tab has a live phone preview on the right. The `{brand}` placeholder renders to the channel name at send time.

<Info>
  There's no separate "Opt-in" tab. The opt-in message is generated automatically the first time your agent tries to text a number with no consent record on file — it's derived from the channel's brand plus a CTIA-compliant default template. You only configure the three tabs below.
</Info>

<Tabs>
  <Tab title="Opt-out">
    **Sent when a user texts `STOP`, `UNSUBSCRIBE`, `END`, `CANCEL`, or `QUIT`.**

    Must confirm the unsubscribe and state that no further messages will be sent.
  </Tab>

  <Tab title="Resubscribe">
    **Sent when a user texts `START`/`YES` after a previous STOP.**

    Confirms re-subscription and must mention how to opt out again.
  </Tab>

  <Tab title="Help">
    **Sent when a user texts `HELP`/`INFO`.**

    Should describe what your brand is and provide a way to contact support.
  </Tab>
</Tabs>

***

## How Opt-in & Opt-out Work

Every (channel × phone number) pair has a consent state in the database: `UNKNOWN → WAITING_OPT_IN → OPTED_IN ⇄ OPTED_OUT`.

<Tabs>
  <Tab title="Opt-in Flow">
    <Steps>
      <Step title="Agent tries to send to a new number">
        State moves from `UNKNOWN` to `WAITING_OPT_IN`. VIVI sends the auto-generated opt-in template and queues the intended message in `sms_message_queue` with status `PENDING_OPT_IN`.
      </Step>

      <Step title="Recipient confirms">
        User replies `YES`, `START`, `UNSTOP`, or `JOIN`.
      </Step>

      <Step title="Queue drained">
        State → `OPTED_IN`. Queue status → `DRAINING`, then queued messages dispatch and status → `SENT`.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Opt-out Flow">
    <Steps>
      <Step title="User sends a STOP keyword">
        Accepted: `STOP`, `UNSUBSCRIBE`, `END`, `CANCEL`, `QUIT`.
      </Step>

      <Step title="Recipient opted out">
        State → `OPTED_OUT`. VIVI sends the opt-out confirmation (your Opt-out tab). Future outbound sends are blocked at the gate.
      </Step>

      <Step title="Resubscribing">
        User replies `START`/`YES` → state → `OPTED_IN`, and VIVI sends the resubscribe confirmation (your Resubscribe tab).
      </Step>
    </Steps>

    <Note>
      If Twilio's status callback returns error code `21610`, VIVI force-sets state to `OPTED_OUT` — this means the user used the carrier-level STOP before the middleware saw it.
    </Note>
  </Tab>
</Tabs>

***

## Compliance Summary

<CardGroup cols={2}>
  <Card title="Twilio TFV Form" color="#2563eb" icon="file-contract">
    Required for toll-free only. 3-step form, 1–5 business day review.
  </Card>

  <Card title="A2P Brand & Campaign" color="#2563eb" icon="id-badge">
    Required for local 10DLC only.
  </Card>

  <Card title="Consent Templates" color="#2563eb" icon="message-check">
    Opt-out, Resubscribe, and Help templates required for both number types.
  </Card>

  <Card title="STOP Keyword" color="#2563eb" icon="hand">
    A single opt-out keyword is required for both number types.
  </Card>

  <Card title="Double Opt-In" color="#2563eb" icon="shield-halved">
    Strongly recommended for both — reply YES to confirm.
  </Card>

  <Card title="Identifiable Brand" color="#2563eb" icon="signature">
    Strongly recommended in every message for both number types.
  </Card>
</CardGroup>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="My agent says the message was sent but the recipient didn't get it" icon="envelope-open">
    The middleware likely **queued** the message instead of sending it because the recipient isn't opted in yet. Check the `sms_message_queue` table for rows with `phoneNumber = <recipient>` and `status = PENDING_OPT_IN`. The recipient receives an opt-in prompt instead; when they reply `YES`, your message drains out automatically.
  </Accordion>

  <Accordion title="Twilio rejected my toll-free verification with 'Invalid use case summary'" icon="triangle-exclamation">
    Twilio's use case summary field has a hidden cap of **500 characters** and rejects opaquely if you exceed it. The frontend enforces this with a hard `maxLength` and a live counter. If a pre-existing row already exceeds the cap, shorten the text before saving. See [Twilio errors and use cases](twilio-errors.md#invalid-use-case-summary) for canonical text patterns that pass review.
  </Accordion>

  <Accordion title="Twilio rejected my toll-free verification with 'Verification already exists for this phone number'" icon="clone">
    A submission for this number is already `IN_REVIEW` or `TWILIO_APPROVED`, and Twilio doesn't allow duplicates. VIVI handles this automatically by dispatching a PATCH to the existing verification instead of POSTing a new one, or returns a "fields locked — review in progress" message. Older  alerts for this error self-heal next time the user saves.
  </Accordion>

  <Accordion title="I created a local number but the agent can't send" icon="ban">
    Local 10DLC numbers cannot send a single message until **both** your A2P brand and campaign are approved by Twilio and carriers. Check the **Compliance** hub — if either shows `Under review`, `SUBMIT_FAILED`, or `Action required`, that's your blocker.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Twilio Compliance Guide" color="#2563eb" icon="clipboard-check" href="twilio-compliance.md">
    A2P, Toll-Free, and status flows — field-by-field walkthrough of every form.
  </Card>

  <Card title="Twilio Errors & Use Cases" color="#2563eb" icon="bug" href="twilio-errors.md">
    Opt-in patterns, rejection reasons, and error codes.
  </Card>
</CardGroup>
