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

# Post a message (API key)

> Send Block Kit to any of your bot's conversations, at any time.

Append one or more bot messages to a conversation your bot owns. No event needed and no time limit, so this is the path for cron follow-ups, batch results, and anything you start yourself.

## Authorization

**Authorization** `string` *required*

`Bearer mac_live_…`

## Path parameters

**conversation\_id** `string` *required*

Take it from any webhook event's `conversation_id`. It must belong to the bot your key belongs to.

## Body

`application/json`. Any [Block Kit shape](https://docs.my-aichatbot.com/block-kit/overview.md#shortcuts) we accept, up to 256 KB and 10 messages.

**messages** `array`

One to ten messages. Each has `blocks` (1 to 25) and optional `mid` and `metadata`. Shortcuts such as `{ "text": "…" }` are expanded for you.

**mid** `string`

Your own id for the message, matching `^[a-zA-Z0-9_.:-]{1,64}$`. Send it again and the message is **replaced** instead of duplicated. See [Updating messages](https://docs.my-aichatbot.com/sending-messages/updating-messages.md).

> [!NOTE]
>
> A [`page` block](https://docs.my-aichatbot.com/block-kit/blocks/page) publishes a hosted Page in the same call when the conversation is an internal one. A [`page_preview`](https://docs.my-aichatbot.com/block-kit/blocks/page-preview) block links a Page you already have.

## Response

**ok** `boolean`

`true` on success.

**messages** `array`

One handle per message in your body, in order.

**properties**

**message\_id** `string`

The stored message.

**mid** `string | null`

The `mid` you sent, if any.

**updated** `boolean`

`true` when the `mid` matched an existing message and replaced it.

```bash curl theme={null}
curl -X POST \
  "https://app.my-aichatbot.com/api/v1/conversations/$CONVERSATION_ID/messages" \
  -H "Authorization: Bearer $MAC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mid": "nightly-summary",
    "blocks": [
      { "type": "text", "text": "Overnight sync finished — **412 records** updated." }
    ]
  }'
```

```javascript Node.js theme={null}
const res = await fetch(
  `https://app.my-aichatbot.com/api/v1/conversations/${conversationId}/messages`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.MAC_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      mid: 'nightly-summary',
      blocks: [
        { type: 'text', text: 'Overnight sync finished — **412 records** updated.' }
      ]
    })
  }
)

const { messages } = await res.json()
```

```python Python theme={null}
import os, requests

res = requests.post(
    f"https://app.my-aichatbot.com/api/v1/conversations/{conversation_id}/messages",
    headers={"Authorization": f"Bearer {os.environ['MAC_KEY']}"},
    json={
        "mid": "nightly-summary",
        "blocks": [
            {"type": "text", "text": "Overnight sync finished — **412 records** updated."}
        ],
    },
)

messages = res.json()["messages"]
```

```json 200 OK theme={null}
{
  "ok": true,
  "messages": [
    { "message_id": "0f8c…", "mid": "nightly-summary", "updated": false }
  ]
}
```

```json 404 Not your conversation theme={null}
{
  "ok": false,
  "error": {
    "code": "conversation_not_found",
    "message": "Unknown conversation for this bot."
  }
}
```

## Errors

| Status | Code | Meaning |
| - | - | - |
| `401` | `invalid_api_key` | Missing, broken, or revoked. Must match `Bearer mac_live_…`. |
| `402` | `MESSAGE_CAP_REACHED` | The workspace's monthly message limit is used up. |
| `404` | `conversation_not_found` | Unknown conversation, **or** it belongs to a different bot. |
| `409` | `conversation_taken_over` | A person has taken over. The bot is locked out. |
| `413` | `PAYLOAD_TOO_LARGE` | Body over 256 KB. |
| `422` | `EMPTY_BODY` | Nothing to post. |
| `422` | `FRAMEWORK_DEFAULT_BODY` | You posted `Accepted`, `OK`, or similar. |
| `422` | `BLOCK_VALIDATION_FAILED` | Bad Block Kit. The `issues` list shows each problem. |
| `429` | `rate_limited` | Over 120 writes per minute for this key. Wait for `retry_after` seconds. |
| `429` | `UPDATE_LIMIT_REACHED` | One `mid` was updated more than 60 times. |
| `500` | `PERSIST_FAILED` | We could not store the message. Retry with the same `mid`. |

> [!NOTE]
>
> A conversation that belongs to another bot returns `404`, not `403`. It looks the same as an id that does not exist, on purpose, so a key cannot be used to hunt for other bots' conversations.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.