import { AutoNextLink, Callout } from '../views/docs/prose';

## Messages

These endpoints let you send SMS messages and read the inbound messages received on your Guava numbers — for example, to poll your own inbox for replies.

<Callout>
  All requests require an `Authorization: Bearer YOUR_GUAVA_API_KEY` header. See the <a href="/docs/api-overview">API Overview</a> for details.
</Callout>

### Send an SMS

```
POST /v1/send-sms
```

Send a single SMS from one of your Guava numbers.

#### Request body

A JSON object with the following fields:

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `from_number` | string | Yes | One of your Guava numbers, in E.164 format. Must have SMS enabled. |
| `to_number` | string | Yes | The recipient's number, in E.164 format. |
| `message` | string | Yes | The message body to send. |

#### Response

On success, returns `201 Created`:

```json
{
  "status": "sent"
}
```

#### Errors

| Status | Description |
|--------|-------------|
| 400 | The `from_number` isn't owned by your organization, or doesn't have SMS configured. |
| 401 | Invalid authentication |
| 500 | The upstream carrier failed to accept the message. |

#### Example

```bash
curl -X POST https://app.goguava.ai/v1/send-sms \
  -H 'Authorization: Bearer YOUR_GUAVA_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"from_number": "+15551230001", "to_number": "+15551234567", "message": "Hello from Guava!"}'
```

<Callout>
  Sending SMS requires your organization to complete SMS brand and campaign registration. See <a href="/docs/outbound-and-sms-permissions">Outbound &amp; SMS Compliance</a>.
</Callout>

---

### List inbound messages

```
GET /v1/messages
```

List the inbound messages received on one of your Guava numbers, oldest first. Poll this endpoint to watch for replies.

#### Parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `to_number` | string | Yes | The Guava number whose inbox you want to read, in E.164 format. Must be owned by your organization. |
| `start` | string | No | Only return messages received at or after this time (ISO 8601, e.g. `2026-06-09T00:00:00Z`). |
| `from_number` | string | No | Only return messages sent from this number, in E.164 format. |
| `modality` | string | No | Only return messages on this channel. Currently `"sms"`. |
| `limit` | integer | No | Maximum number of messages to return, between 1 and 100. Defaults to 50. |

#### Response

A JSON object with the following fields:

| Field | Type | Description |
|-------|------|-------------|
| `messages` | array | The matching messages, oldest first. |
| `has_more` | boolean | `true` if more messages match than were returned in this response. |

Each message has the following fields:

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique ID of the message |
| `from_number` | string | The number that sent the message |
| `to_number` | string | Your Guava number that received the message |
| `content` | string | The message body |
| `received_at` | string | When the message was received, in ISO 8601 format |
| `modality` | string | The channel the message arrived on. Currently `"sms"`. |
| `direction` | string | Always `"inbound"` |

#### Pagination

Messages are returned oldest first. When `has_more` is `true`, request the next page by calling again with `start` set to the `received_at` of the **last** message you received. Because `start` is inclusive, that boundary message — and any others sharing its exact timestamp — will be returned again, so dedupe by `id`.

#### Errors

| Status | Description |
|--------|-------------|
| 400 | Invalid `start` timestamp or `limit` value |
| 401 | Invalid authentication |
| 404 | The `to_number` isn't owned by your organization |

#### Example

```bash
curl -G https://app.goguava.ai/v1/messages \
  -H 'Authorization: Bearer YOUR_GUAVA_API_KEY' \
  --data-urlencode 'to_number=+15551230001' \
  --data-urlencode 'start=2026-06-09T00:00:00Z'
```

Sample response:

```json
{
  "messages": [
    {
      "id": "6064ab9663dc4eb0",
      "from_number": "+15551234567",
      "to_number": "+15551230001",
      "content": "YES, see you then!",
      "received_at": "2026-06-09T00:12:04.518000+00:00",
      "modality": "sms",
      "direction": "inbound"
    }
  ],
  "has_more": false
}
```

<Callout>
  The `+` in a phone number must be URL-encoded as `%2B` in query strings. The `curl -G --data-urlencode` form above handles this for you.
</Callout>

<AutoNextLink currentSection="messages-api" />
