> ## 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.

# Overview

> The three ways to send a message, and how to choose between them.

Every message your bot sends is [Block Kit](/block-kit/overview) JSON. There are three ways to send it, and they all accept the **same body**. You can switch between them without changing your JSON.

## Pick a path

<CardGroup cols={3}>
  <Card title="Webhook response" icon="reply" href="/sending-messages/webhook-response">
    **Reply in the same request.** No setup, but a hard 10-second limit.
  </Card>

  <Card title="Response URL" icon="clock" href="/sending-messages/response-url">
    **POST back within 45 minutes.** No keys to manage.
  </Card>

  <Card title="API key" icon="key" href="/sending-messages/api-key">
    **Send any time.** No time limit, and no event needed first.
  </Card>
</CardGroup>

## Side by side

|                           | Webhook response         | Response URL         | API key                        |
| ------------------------- | ------------------------ | -------------------- | ------------------------------ |
| **Key**                   | None — it *is* the reply | Token inside the URL | `Bearer mac_live_…`            |
| **Deadline**              | 10 seconds               | 45 minutes           | None                           |
| **Needs an event first?** | Yes                      | Yes                  | No                             |
| **Can message**           | That conversation        | That conversation    | Any of the bot's conversations |
| **Rate limit**            | —                        | 30/min per token     | 120/min per key                |
| **Messages per call**     | Up to 10                 | Up to 10             | Up to 10                       |
| **Setup**                 | None                     | None                 | Create a key                   |

## How to choose

<Steps>
  <Step title="Can you answer in under 10 seconds?">
    Return the JSON from your webhook. Done — nothing else to set up.
  </Step>

  <Step title="Will it take longer, but under 45 minutes?">
    Return an empty body first. Then POST your reply to the `response_url` when the work is done.
  </Step>

  <Step title="Longer than that, or no event to reply to?">
    Use an API key. This is the path for cron jobs, batch results, and messages you start yourself.
  </Step>
</Steps>

<Tip>
  You can mix these. A common pattern: return a `status` block right away from the webhook, then update it through the `response_url` as the job runs. See [Updating messages](/sending-messages/updating-messages).
</Tip>

## The body is always the same

This works on all three:

```json theme={null}
{
  "messages": [
    {
      "blocks": [
        { "type": "text", "text": "**Done!** Your refund is on its way." }
      ]
    }
  ]
}
```

And so does this, because we accept shortcuts:

```json theme={null}
{ "text": "**Done!** Your refund is on its way." }
```

See the [Block Kit overview](/block-kit/overview) for every shortcut we accept.

## Rules that apply to all three

* **256 KB** body limit, and at most **10 messages** per call. Bigger bodies return `413 PAYLOAD_TOO_LARGE`.
* **A human always wins.** Once a person takes over a conversation, all three paths return `409 conversation_taken_over`. The bot cannot talk over a person. That is on purpose.
* **`mid` makes retries safe.** Send the same `mid` again and we update the message instead of posting a copy. See [Updating messages](/sending-messages/updating-messages).
* **All errors look the same.** Every failure returns `{ "ok": false, "error": { "code", "message" } }`. See [Limits and errors](/block-kit/limits-and-errors).
