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

# SMS

> Send messages and read conversation history.

Base path: `https://api.recepta.ai/api/v1/api/sms`

All endpoints require an [API key](/api-reference/authentication) in `x-api-key`, and the permission noted on each.

<Warning>
  US SMS requires approved [A2P 10DLC registration](/phone/a2p-10dlc). Without it, carriers filter or block your messages regardless of what the API returns.
</Warning>

## Send a message

<ParamField path="POST /api/v1/api/sms/send" type="sms:send" required />

<ResponseField name="to" type="string" required>
  Recipient number. E.164 recommended — `+14155551234`.
</ResponseField>

<ResponseField name="from" type="string" required>
  One of your own provisioned numbers. Sending from a number that isn't yours returns `403`.
</ResponseField>

<ResponseField name="body" type="string" required>
  Message content.
</ResponseField>

```bash theme={null}
curl -X POST https://api.recepta.ai/api/v1/api/sms/send \
  -H "x-api-key: $RECEPTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "from": "+14155559876",
    "body": "Hi Dana, it'\''s Dan from Coral Plumbing - confirming Thursday 8-10am."
  }'
```

Returns `201` on success, `400` if a required field is missing, `403` if `from` isn't one of your numbers.

<Warning>
  You must have consent to text the recipient, and opt-outs are enforced — a suppressed number will not receive messages sent through this endpoint. Don't build around that. See [SMS](/channels/sms).
</Warning>

## List conversations

<ParamField path="GET /api/v1/api/sms" type="sms:read" required />

| Query param | Type    | Default | Notes                                 |
| ----------- | ------- | ------- | ------------------------------------- |
| `page`      | integer | `1`     | Page number                           |
| `limit`     | integer | `50`    | Items per page                        |
| `search`    | string  | —       | Matches phone number or customer name |
| `status`    | enum    | —       | `ACTIVE`, `ARCHIVED`, `CLOSED`        |

```bash theme={null}
curl "https://api.recepta.ai/api/v1/api/sms?status=ACTIVE&limit=25" \
  -H "x-api-key: $RECEPTA_API_KEY"
```

## List messages in a conversation

<ParamField path="GET /api/v1/api/sms/{conversationId}/messages" type="sms:read" required />

| Query param | Type    | Default |
| ----------- | ------- | ------- |
| `page`      | integer | `1`     |
| `limit`     | integer | `50`    |

```bash theme={null}
curl "https://api.recepta.ai/api/v1/api/sms/CONVERSATION_ID/messages" \
  -H "x-api-key: $RECEPTA_API_KEY"
```

Returns `404` if the conversation isn't in your workspace.

## Writing messages that arrive

<Columns cols={2}>
  <Card title="Identify yourself first" icon="circle-check">
    Name the person and your business in the opening line. An unidentified text from an unknown number reads as spam and gets reported as such.
  </Card>

  <Card title="Mind the clock" icon="clock">
    Send within reasonable local hours for the recipient. Your server's timezone is not a defense.
  </Card>
</Columns>

## Receiving messages

Subscribe to `sms.received` and `sms.sent` to handle inbound texts in your own systems as they arrive, rather than polling. See [Webhooks](/api-reference/webhooks).
