# SMS

> Programmable SMS through any provider. Declarative provider manifests, delivery receipts, and 2-way conversations that run your flows.

Send and receive SMS through **the provider you already have**. There are
hundreds of SMS providers worldwide — global CPaaS names, regional aggregators,
DLT-regulated Indian routes — and the gateway treats each one as a small
declarative manifest: an HTTP endpoint, an auth style, a field mapping, and a
receipt parser. Enable a provider, paste its credentials, and the platform
handles queueing, retries, failover, rate pacing, and status tracking.

Inbound texts do more than land in a log. A reply to one of your numbers opens
a conversation that runs **the same visual flow builder your voice IVR and web
chat use** — greet with an AI text agent, collect context, and queue to a human
agent's desktop when needed. The agent replies from the same chat rail they use
for web chat; the visitor gets it as an SMS.

## When to use it

  - **Notifications & alerts** — Order updates, OTP-style notices, appointment reminders — one API,
    delivered through whichever provider is cheapest or required in each
    country.
  - **2-way customer conversations** — A customer texts your number; your flow answers with an AI agent and
    escalates to a human in the contact-center desktop when needed.
  - **Provider redundancy** — Per-prefix routing ladders: route +91 through your DLT route with a global
    fallback, and fail over automatically when a provider errors.
  - **Local aggregators** — Wire a bespoke provider yourself: the generic HTTP provider covers simple
    one-endpoint APIs from configuration, and custom manifests let you define
    a full provider (auth, receipts, inbound) without waiting on us.

## How it works

1. **Providers are manifests.** Twilio, Vonage, Plivo, Bird, MSG91, Textlocal
   and AWS SNS ship built in; each is a declarative spec (auth, send template,
   response parser, receipt/inbound parsers, error map). Adding a provider is
   adding a manifest — the console's credential form, capability badges and
   webhook URLs all derive from it.
2. **Sends are durable.** `POST /api/sms/v1/messages` (or the console) enqueues
   the message; a delivery pump picks the provider ladder for the destination,
   paces per-provider rate limits, retries with backoff, and fails over to the
   next provider on retryable errors. Status moves forward only:
   `queued → sent → delivered / undelivered / failed`.
3. **Receipts and inbound are hosted webhooks.** Each provider account gets a
   pair of unguessable URLs to paste into the provider console. Delivery
   receipts update message status and fire `sms.message.*` webhooks to your
   endpoints; inbound messages open 2-way conversation threads.
4. **Campaigns are paced blasts.** Upload a CSV (first column `phone`; other
   columns become `{slots}` in the message template), set a rate, and the
   campaign drains through the same pipeline — routing ladders, provider rate
   limits and delivery receipts included. Recipients who ever texted STOP are
   skipped automatically.
5. **STOP / START are handled for you.** A whole-message STOP-family keyword
   on any inbound number records an opt-out that blocks every further send to
   that recipient (campaign and transactional) and fires an
   `sms.optout.created` webhook; START lifts it. The Opt-outs tab shows and
   manages the list.
6. **Bring your own provider.** Admins can upload a custom provider manifest
   (the same declarative contract the built-ins use — auth style, send
   template, response parsing, receipt/inbound mappings) under an `x-…` id.
   It appears in the provider picker like any shipped provider; the send host
   must be literal https and passes the platform's egress checks on save and
   on every send.
7. **Conversations ride the chat engine.** An inbound thread becomes a
   headless chat conversation bound to the vector flow you attach to the
   number — AI text agents, skill queues, human agents, transcripts and
   `chat.*` events all included.

## API

```bash
# Mint an smk_ key in the console (SMS → API keys), then:
curl -X POST https://portal.clutchcall.dev/api/sms/v1/messages \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"to": "+14155550100", "text": "Your order shipped."}'
# → 202 {"id":"...","status":"queued","encoding":"gsm7","segments":1}

curl https://portal.clutchcall.dev/api/sms/v1/messages/<id> \
  -H "Authorization: Bearer smk_..."
```

Webhook events (register an endpoint under the `sms` vertical):
`sms.message.sent`, `sms.message.delivered`, `sms.message.undelivered`,
`sms.message.failed`, `sms.message.received`, `sms.optout.created`,
`sms.campaign.completed`.

## Honest limits

- MMS media on inbound messages is stored as provider URLs, not fetched.
- Providers without delivery-receipt webhooks (e.g. AWS SNS in this shape)
  stop at `sent`.
- Campaign templates substitute `{column}` slots from your CSV; there is no
  visual flow designer for campaigns yet — conversational flows belong to the
  inbound vector, not the blast.
