> For the complete documentation index, see [llms.txt](https://docs.amigo.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amigo.ai/developer-guide/platform-api/conversations/sms.md).

# SMS

The SMS endpoints let you send outbound text (SMS) and media (MMS) messages through a configured SMS use case and track their delivery lifecycle.

{% hint style="info" %}
SMS send and consent routes belong to the separately authenticated Channel Manager API and are not published in the Platform API OpenAPI document. This page documents that separate channel contract; Platform workspace operations elsewhere in the guide use embedded OpenAPI references.
{% endhint %}

## Send SMS

`POST /v1/sms/`

Sends a single SMS or MMS message through the messaging service associated with the specified SMS use case. Requires the `sms:send` scope on the target setup.

Before sending, the platform validates that:

* The SMS use case exists and has not been deleted
* At least one phone number is assigned to the use case's sender pool
* The pool has an SMS-capable number (text-only sends) or an MMS-capable number (sends with media attachments)
* For US long-code numbers, a verified A2P 10DLC campaign is associated with the use case
* For US/CA toll-free or US long-code sender pools, the recipient has a recorded opt-in for the use case (sent via `POST /v1/sms/opt-in`) and has not opted out
* For US A2P and toll-free sends with a text body, the message content is consistent with the registered use case (A2P campaign and/or toll-free verification); content that does not match is rejected

The sender number is selected automatically from the use case's sender pool based on configured routing policies (sticky sender, area code geomatch). The chosen sender is not known at send time - it is resolved asynchronously and reported via the status callback.

### Request Body (multipart form)

| Field               | Type          | Required | Description                                                                                                                                                                                           |
| ------------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `use_case_id`       | string (UUID) | Yes      | ID of the SMS use case to send through                                                                                                                                                                |
| `to_phone_number`   | string        | Yes      | Destination phone number in E.164 format                                                                                                                                                              |
| `message`           | string        | No       | Message body, 1-1600 characters                                                                                                                                                                       |
| `media_attachments` | file\[]       | No       | Up to 10 media files; presence of any makes the message an MMS. Each file must be 1 byte to 600 KB with a unique, valid filename, and the total message size (body + attachments) must be under 5 MB. |

At least one of `message` or `media_attachments` is required (422 otherwise).

### Response (201)

| Field              | Type                      | Description                                                                         |
| ------------------ | ------------------------- | ----------------------------------------------------------------------------------- |
| `id`               | string (UUID)             | Unique identifier for the outbound SMS message                                      |
| `use_case_id`      | string (UUID)             | SMS use case this message was sent through                                          |
| `message_sid`      | string                    | External message identifier used for delivery tracking                              |
| `from_number`      | string or null            | Sender phone number, null until resolved by the messaging service                   |
| `to_number`        | string                    | Destination phone number                                                            |
| `body`             | string or null            | Message body that was sent, null for media-only messages                            |
| `num_segments`     | integer or null           | Number of message segments, null until carrier handoff                              |
| `status`           | string                    | Current delivery status: `pending`, `sent`, `delivered`, `failed`, or `undelivered` |
| `attachment_names` | string\[]                 | Filenames of any media attachments sent with the message                            |
| `handed_off_at`    | string (datetime) or null | When the message was handed off to the carrier                                      |
| `delivered_at`     | string (datetime) or null | When the carrier confirmed delivery                                                 |
| `errored_at`       | string (datetime) or null | When a delivery error occurred                                                      |
| `error_code`       | integer or null           | Error code on failed or undelivered messages                                        |
| `created_at`       | string (datetime)         | When the message record was created                                                 |
| `updated_at`       | string (datetime)         | When the message record was last updated                                            |

### Error Responses

| Status | Condition                                                                                                 |
| ------ | --------------------------------------------------------------------------------------------------------- |
| 401    | Missing, expired, or invalid bearer token                                                                 |
| 403    | Token lacks the required scope or access to this use case's setup                                         |
| 404    | SMS use case not found or has been deleted                                                                |
| 422    | Neither `message` nor `media_attachments` provided                                                        |
| 422    | No phone number assigned to the use case                                                                  |
| 422    | No SMS-capable number in the pool (text-only send) or no MMS-capable number (send with media)             |
| 422    | No verified A2P campaign for a US long-code sender pool                                                   |
| 422    | No recorded opt-in for the recipient on a US/CA toll-free or US long-code sender pool                     |
| 422    | Message content does not match the registered use case                                                    |
| 422    | Invalid attachment (missing/duplicate/invalid filename, empty or over 600 KB, or total size 5 MB or more) |
| 422    | Invalid destination phone number (not a real number or is a landline)                                     |
| 422    | Destination phone number has opted out of receiving messages                                              |
| 422    | Destination region not permitted for the messaging service                                                |
| 422    | The brand registration behind the use case is suspended                                                   |

## Delivery Status Lifecycle

After a message is sent, its status is updated automatically as delivery progresses:

```
pending → sent     (handed off to carrier - handed_off_at is set)
        → failed   (rejected before carrier handoff - errored_at and error_code are set)

sent    → delivered     (carrier confirmed receipt - delivered_at is set)
        → undelivered   (carrier confirmed non-delivery - errored_at and error_code are set)
```

The `from_number` field is populated once the messaging service selects a sender from the pool, which happens asynchronously after the send request returns.

On carriers without delivery receipt support (some international routes), the lifecycle stops at `sent` - `delivered_at` stays null, and `handed_off_at` is the only post-send signal.

## Status Callback Handling

Delivery status updates flow back from the messaging provider through a status webhook that the platform configures automatically on each outbound message - no setup is required on your side. Webhook signatures are validated before processing, so forged status updates are rejected, and updates for unknown message identifiers are acknowledged and ignored.

Status updates are idempotent - duplicate callbacks for the same status transition are safely ignored. Late-arriving status updates that would regress a terminal state (for example, a `sent` callback arriving after `delivered`) are also dropped. The result is that the `status`, `delivered_at`, and `error_code` fields on a message record only ever move forward through the delivery lifecycle.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/developer-guide/platform-api/conversations/sms.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
