# Channels and messages

> Read channels and messages, send and edit messages, and add reactions.

Read channels and messages, send and edit the bot's own messages, and add reactions.

## Get channel

`GET /v1/channels/{channel_id}`

A [channel](#channel-object) the bot can see.

## Get channel messages

`GET /v1/channels/{channel_id}/messages`

Needs `messages.read`. Returns [messages](#message-object), newest first.

| Query | Type | Notes |
| --- | --- | --- |
| `limit` | integer | 1 to 100 |
| `before` | message id | Messages before this one |
| `after` | message id | Messages after this one |

History follows the **Read message history** permission, as it does for people. Without it the bot only reads what was sent while it was connected, and the response has the header `X-History-Hidden: 1`.

## Get channel message

`GET /v1/channels/{channel_id}/messages/{message_id}`

One message. Needs `messages.read`.

## Create message

`POST /v1/channels/{channel_id}/messages`

Needs `messages.send` and the Send messages permission. Answers `201` with the message.

```json
{
  "content": "Team A leads 3 to 1",
  "reply_to": "<message id>",
  "nonce": "score-update-0042",
  "embeds": [{
    "title": "Score", "description": "Team A leads", "url": "https://example.com/match/42", "color": "#3355ff",
    "fields": [{ "name": "Team A", "value": "3", "inline": true }, { "name": "Team B", "value": "1", "inline": true }],
    "footer": { "text": "Final round" }, "timestamp": "2026-10-01T10:00:00Z"
  }],
  "allowed_mentions": { "parse": ["users"] }
}
```

| Field | Notes |
| --- | --- |
| `content` | Up to 2,000 characters. Send `content`, at least one embed, or both |
| `reply_to` | The id of the message to reply to |
| `nonce` | 16 to 64 letters, digits or `-`. Sending the same nonce and message again returns the first message instead of posting twice. The same nonce with a different message answers `409 nonce_conflict` |
| `embeds` | Up to 10. Needs Embed links |
| `allowed_mentions` | Which mentions notify anyone, as on Discord: `parse`, `users`, `roles` (up to 100 ids each). Without it, every mention the bot is allowed to make notifies |

### Embed limits

Title 256 characters, description 4,096, up to 25 fields (name 256, value 1,024), footer 2,048, author name 256, and 6,000 characters in total. `color` is `#rrggbb` or a number. Links must be `http` or `https`. Images, thumbnails and video aren't supported yet and are dropped. Embed text shows as plain text, and links go through Lamma's leaving-Lamma warning.

### Mentions

Use `<@user id>`, `<@&role id>`, `@everyone` and `@here`, with the same permission checks as for people.

## Edit message

`PATCH /v1/channels/{channel_id}/messages/{message_id}`

Edits one of the bot's own messages. Needs `messages.send`. Takes the same fields as creating one.

## Delete message

`DELETE /v1/channels/{channel_id}/messages/{message_id}`

Deletes one of the bot's own messages and answers `204`. Bots can't delete other people's messages in v1.

## Add reaction

`PUT /v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me`

Needs `reactions`. Answers `204`. `{emoji}` is a URL-encoded emoji, such as `%F0%9F%91%8D` for 👍.

## Remove reaction

`DELETE /v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me`

Removes the bot's own reaction. Answers `204`.

## Channel object

| Field | Type | Notes |
| --- | --- | --- |
| `id` | string | |
| `guild_id` | string | |
| `name` | string | |
| `kind` | string | `text`, `voice` and others. Not a number as on Discord |
| `topic` | string or null | |
| `position` | integer | |
| `category_id` | string or null | |
| `slowmode_seconds` | integer | |
| `permissions` | array of strings | What the bot may do in this channel |

## Message object

| Field | Type | Notes |
| --- | --- | --- |
| `id` | string | |
| `channel_id` | string | |
| `guild_id` | string | |
| `author` | object | A [user object](https://lammapp.sa/developers/api-reference#user-object) |
| `content` | string | Empty when `content_available` is `false` |
| `content_available` | boolean | `false` when the text was withheld because the app lacks `message_content` |
| `embeds` | array | |
| `attachments` | array | |
| `poll` | object or null | |
| `mentions` | object | `{ users, roles, everyone }` |
| `reactions` | array | `[{ emoji, count, me }]` |
| `reply_to` | string or null | |
| `interaction` | object or null | `{ id, name, user_id }` when the message answers a slash command |
| `pinned` | boolean | |
| `created_at` | integer | Unix milliseconds |
| `edited_at` | integer or null | Unix milliseconds |
