# Send message

Post a message to one of your community's channels as an existing member, with text, image links or both.

- Endpoint: `POST https://api.returning.ai/v1/messages/send`
- Section: Community / Messaging
- Authentication: `Authorization: Bearer <API_KEY>` (Community API key)
- Permission: `sendMessage` (Shown in the dashboard as "Send Messages")
- Retries: Not idempotent; check Get Messages before retrying
- Guide: hand-written
- Verified: code, 2026-09-27
- Last updated: 26 Sep 2026
- Web page: https://docs.returning.ai/api-reference/messaging/send-message

## When to use this

- Your system posts market updates or announcements into a community channel.
- A bot or support account answers in a channel on your team's behalf.
- You want to share a chart or image in a channel from a public image URL.

**Instead:** Use [Reply message](https://docs.returning.ai/api-reference/messaging/reply-message.md) instead to answer one specific message.

**Live channel:** A successful call posts straight away to members of the channel. Test against a channel only your team can see.

## Authentication

- Header: `Authorization: Bearer <API_KEY>`
- Permission: `sendMessage`

Use a Community API key with `sendMessage`, and keep it on your server. The key decides the community, so never send a community ID. A personal user API key with its own send permission also works; then the message is posted as the key's owner and the channel's posting rules apply.

## Behaviour

The message appears straight away for everyone in the channel, posted as `sender`. With a Community API key the channel's posting rules aren't checked, so you can post as any member in any of your community's channels; pick `sender` with care. The sender earns the usual XP and message counts for a message, members named in `@` mentions are mentioned, and your community's message webhooks fire. `@all` mentions every member.

A text that contains a link is handled as an attachment, not as text. When the whole `message` is one URL, that file is fetched and posted as an attachment with no text. Any other text with a link fails with `400 Error processing attachments`. To share a picture with a caption, put the caption in `message` and the picture in `images`.

Images in `images` are copied to Returning.AI storage before posting. More than 10 images are posted as several messages, the first straight away and the rest just after the response.

## Request

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Authorization` | `string` | Yes | Community API key with `sendMessage`. (`Bearer <API_KEY>`) |
| `Content-Type` | `string` | Yes | Request body format. (`application/json`) |

### Body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `channelId` | `string` | Yes | The channel to post in, from List integration channels. (Channel ID) |
| `sender` | `string` | Yes | The member the message is posted as, by username or email. Required with a Community API key. With a personal user API key, leave it out to post as the key's owner. (Username or email of a member) |
| `message` | `string` | No | The message text. Mention a member with `@username`, or use `@{name}` when the username has other characters. (Required unless you send `images`) |
| `images` | `string[]` | No | Public image URLs to attach. Each image is copied and posted with the message, 10 images per message. (Required unless you send `message`) |
| `forumTopicId` | `string` | No | The topic to post in, for a forum channel. (Topic ID in that channel) |
| `recipient` | `string` | No | For a direct-message channel, with a personal user API key only. The recipient's username or email. |

### Example request

```bash
curl --request POST \
  --url https://api.returning.ai/v1/messages/send \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "channelId": "66f000000000000000000a11",
    "sender": "support@example.com",
    "message": "The gold webinar starts in 15 minutes."
  }'
```

## Response

A `200` means the message was posted. The response has no message ID; read the channel with Get Messages to find it.

### Response fields

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `status` | `string` | always | Result of the request. (`success`) |
| `message` | `string` | always | Human-readable summary. Do not branch on it. |

### Example response (200)

```json
{
  "status": "success",
  "message": "Message sent successfully"
}
```

## Errors

Validation errors use `meta`, `message`, `detail` and `solution`, with `detail` naming the field. Every other error has `message`, sometimes with `status` or `detail`. None has a machine-readable code, so branch on the HTTP status and read `message`.

### Fix the request

| Status | Code | What to do |
| --- | --- | --- |
| 400 | - | A field is missing or malformed, such as no `channelId`, neither `message` nor `images`, or an ID that isn't 24 hex characters (`detail` names the field). `Sender field is required` means you used a Community API key without `sender`. `Error processing attachments` means an image URL couldn't be fetched, or the text contains a link (see Behaviour). Nothing was posted. |
| 401 | - | The key is missing (`Invalid token`), unknown (`Invalid API key`) or expired, or it lacks `sendMessage` (`Your API key does not have permission to access this action`). Add the permission in Settings > Integration > API Keys. |
| 403 | - | Personal user API keys only: the key's owner can't post in this channel, `sender` names someone other than the key's owner, or the recipient isn't in the direct-message channel. Nothing was posted. |

### Fix the data

| Status | Code | What to do |
| --- | --- | --- |
| 404 | - | `message` says which: `Channel not found` (check `channelId` with List integration channels), `User not found` (no member has that `sender`), `Recipient not found`, or `Forum topic not found or does not belong to this channel`. Nothing was posted. |

### Retry with backoff

| Status | Code | What to do |
| --- | --- | --- |
| 500 | - | The send failed, or the key could not be checked (`Authentication failed`). The message may already be posted, so check Get Messages before you retry. |

**Retries:** This endpoint doesn't accept an `Idempotency-Key`, and every successful call posts a new message. After a timeout or a `500`, read the channel with Get Messages, filtered by `channel_id` and the sender's `email`, and send again only when the message isn't there. Over the [rate limit](https://docs.returning.ai/how-it-works.md#rate-limits), requests return `429`; wait for the window to reset, then retry.

## Next step

- [Get messages](https://docs.returning.ai/api-reference/messaging/get-messages.md): `GET /v1/messages`. Confirm the message is in the channel and get its `id`. This endpoint doesn't return one.
- [Upload chart images with Upload message images](https://docs.returning.ai/api-reference/messaging/upload-message-images.md): `POST /v1/messages/upload-image`.
