# SMS

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

## Send SMS

`POST /v1/sms/`

Sends a single SMS message through the messaging service associated with the specified SMS use case.

Before sending, the platform validates that:

* The SMS use case exists and is active
* At least one phone number is assigned to the use case's sender pool
* For US long-code numbers, a verified A2P 10DLC campaign is associated with the use case

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

| 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        | Yes      | Message body, 1-1600 characters          |

### 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                    | Message body that was sent                                                          |
| `num_segments`  | integer or null           | Number of message segments, null until carrier handoff                              |
| `status`        | string                    | Current delivery status: `pending`, `sent`, `delivered`, `failed`, or `undelivered` |
| `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                                                             |
| ------ | --------------------------------------------------------------------- |
| 404    | SMS use case not found or has been deleted                            |
| 422    | No phone number assigned to the use case                              |
| 422    | No verified A2P campaign for a US long-code sender pool               |
| 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 Webhook

`POST /v1/webhook/twilio/sms-status`

This webhook receives delivery status updates from the messaging provider. It is configured automatically on each outbound message.

The webhook validates the request signature using the subaccount credentials before processing. Invalid signatures receive a 403 response. Unknown message identifiers are silently acknowledged with 204.

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.

| Response | Meaning                                            |
| -------- | -------------------------------------------------- |
| 204      | Status processed successfully, or silently ignored |
| 403      | Request signature validation failed                |


---

# Agent Instructions: 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:

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

The question should be specific, self-contained, and written in natural language.
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.
