# Sending messages

> Send your SuperCool agent a message with POST /v1/messages. Attach files, follow up on work in progress, answer the agent's questions and route webhooks.

Source: https://supercool.com/docs/api/messages

Everything starts with `POST /v1/messages`. You talk to the agent the way you would in the SuperCool app: say what you want, attach what it needs, and follow up.

## Send a message

```bash
curl https://api.supercool.com/v1/messages \
  -H "Authorization: Bearer $SUPERCOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: launch-video-2026-09-30" \
  -d '{"message": "Research my top 5 competitors (candle shops in Austin) and make a one-page PDF summary"}'
```

| Field | Type | Description |
|---|---|---|
| `message` | string | What you want, in plain language. Up to 20,000 characters. For longer text, attach it as a file. |
| `files` | array | Small files inline: up to 5, each a public `url` or `base64` bytes. See [Attach files](#attach-files). |
| `upload_ids` | array | Large files you uploaded first: up to 10. See [Files & uploads](https://supercool.com/docs/api/files#uploads). |
| `webhook_endpoint_id` | string | Send this message's webhook events to one registered endpoint. See [Webhooks](https://supercool.com/docs/api/webhooks#per-message). |

You need a `message`, `files` or `upload_ids`. An empty request gets [`400 empty_message`](https://supercool.com/docs/api/errors#empty_message).

Always send an `Idempotency-Key`: one fresh value per logical request, reused on retries. See [Idempotency & retries](https://supercool.com/docs/api/idempotency).

## What comes back

The call returns within about 30 seconds with the [message object](https://supercool.com/docs/api/reference#object-message) and HTTP `201`:

- **A quick answer** comes back finished: `"status": "completed"`, `"final": true`, the answer in `reply`, and any files the agent handed over in `files`.
- **Longer work** comes back as `"status": "processing"`: the agent replied ("On it…") and started one or more **jobs**. Each job is one piece of work running in a chat (`work_id`), with its own `status` and a `link` to that chat in the app.

```json
{
  "id": "msg_3f9a1c2e7b8d4e5f6a7b8c9d",
  "object": "message",
  "status": "processing",
  "reason": null,
  "question": null,
  "final": false,
  "reply": "I'll research the five closest competitors and put it in a one-page PDF.",
  "jobs": [
    {
      "job_id": "exe_9b2c4d6e8f0a1b3c5d7e9f1a2b4c6d8e",
      "kind": "execution",
      "role": "execution",
      "work_id": "5d0c3e2a-8f1b-4c6d-9e7f-1a2b3c4d5e6f",
      "title": "Austin candle shop competitors",
      "status": "running",
      "final": false,
      "link": "https://supercool.com/chat/5d0c3e2a-8f1b-4c6d-9e7f-1a2b3c4d5e6f",
      "files": []
    }
  ],
  "files": [],
  "notes": [],
  "credits_used": 0,
  "created_at": "2026-09-30T14:02:03.118000Z",
  "updated_at": "2026-09-30T14:02:12.950000Z"
}
```

Keep the message `id` (`msg_…`). You use it to [get the result](https://supercool.com/docs/api/results). Message ids are always generated by SuperCool.

Messages belong to the API key that sent them: another key gets `404 not_found` for them. The work itself (the chats) belongs to your account and is visible to every key through [`/v1/work`](https://supercool.com/docs/api/work).

## Attach files

For small files, put them in `files`. Each entry has either a `url` (a public `https` link SuperCool downloads) or `base64` (the bytes), plus an optional `name` and `content_type`:

```json
{
  "message": "Turn these product photos into a 3-slide carousel for Instagram",
  "files": [
    { "url": "https://example.com/photos/candle-1.jpg" },
    { "name": "candle-2.png", "content_type": "image/png", "base64": "iVBORw0KGgoAAAANSUhEUgAA..." }
  ]
}
```

- Up to **5 files**, each up to **10 MB**, **25 MB** in total. Only the first 5 are taken.
- Executables are refused.
- A file that can't be fetched doesn't fail the message. The agent gets the rest, and the problem is listed in the message's `notes` (for example `"candle-1.jpg: couldn't be fetched (timeout)"`).

For anything bigger (footage, long PDFs, audio), use an [upload](https://supercool.com/docs/api/files#uploads): up to 500 MB per file and 10 files per message.

## Follow-ups {#follow-ups}

Send another message and the agent continues the conversation, with the same memory it has in the app. Refer to earlier work naturally:

```json
{ "message": "Love it. Make a 9:16 version with captions, and a 1:1 cut for the feed" }
```

If the work is still running, a follow-up can join it instead of starting something new. The follow-up's message then lists that job with `"role": "follow_up"`, and its status follows the running work. If the agent starts new work, you get new jobs.

Every message is its own object with its own `id` and status. To track the combined result, follow the latest message, or read the chat with [`GET /v1/work/{work_id}`](https://supercool.com/docs/api/work).

## When the agent asks a question {#questions}

Sometimes the agent needs a decision before it can go on ("vertical or square?"). The message then ends as `"status": "needs_input"` with the question in `question`:

```json
{
  "id": "msg_3f9a1c2e7b8d4e5f6a7b8c9d",
  "status": "needs_input",
  "question": "Should the ad be vertical (9:16) for Reels, or square (1:1) for the feed?",
  "final": true
}
```

Answer by sending a new message. The agent picks up where it left off:

```json
{ "message": "Vertical, for Reels" }
```

## Out of credits, busy, and other outcomes

Talking to the agent is free. Work uses credits. With no credits, the message is still accepted (HTTP `201`) and comes back `"status": "blocked"`, `"reason": "out_of_credits"`. That's a normal outcome, not an error. See [Credits & pricing](https://supercool.com/docs/api/credits#out-of-credits).

Up to **5 jobs can run at once** per account. Messages always get through, but new work may not start: see [At capacity](#at-capacity).

Every status and reason is explained in [Getting results](https://supercool.com/docs/api/results#statuses).

## At capacity {#at-capacity}

Up to 5 jobs can run at once on your account. A message is never refused for this: stopping work ("stop the ad") or following up on running work always gets through. But if the agent tries to **start** new work while 5 jobs are already running, that start is refused:

- The message comes back normally (`201`) with a job of `kind: "refusal"` (`job_id` like `ref_…`), `status: "blocked"`, `reason: "too_many_running"` and `final: true`.
- The message's `status` follows the usual rules: `blocked` if that was its only job, `partial` if another of its jobs completed.
- The message has a `running` array listing the work that's running now:

```json
{
  "id": "msg_7a1d0c9e8b2f4a6c5d3e1f0b",
  "status": "blocked",
  "reason": "too_many_running",
  "final": true,
  "jobs": [{ "job_id": "ref_3c9e1a7b5d2f", "kind": "refusal", "status": "blocked", "reason": "too_many_running", "final": true }],
  "running": [
    { "job_id": "exe_9b2c4d6e8f0a1b3c5d7e9f1a2b4c6d8e", "message_id": "msg_3f9a1c2e7b8d4e5f6a7b8c9d", "work_id": "5d0c3e2a-8f1b-4c6d-9e7f-1a2b3c4d5e6f" }
  ]
}
```

Wait for one of the running jobs to finish (follow its message, or a webhook), then send the request again. Queued work that is waiting for credits also doesn't resume while 5 jobs are running. It stays queued and resumes once there's room, as long as that's within its 24-hour window.

## Route this message's webhooks {#routing}

By default a message's [webhook events](https://supercool.com/docs/api/webhooks) go to every endpoint on your account that wants them. To send one message's events to a single endpoint instead (say, one per customer or environment), pass its id:

```json
{ "message": "...", "webhook_endpoint_id": "whe_4c1d2e3f4a5b6c7d8e9f" }
```

It must be an endpoint registered on your account (`POST /v1/webhooks`). Unknown ids get `404 not_found`.

## Limits

| Limit | Value |
|---|---|
| Message text | 20,000 characters |
| Inline files | 5 per message, 10 MB each, 25 MB total |
| Uploads | 10 per message, 500 MB each, 1 GB total |
| Messages | 120 per hour and 1,000 per day, per account |
| Running jobs | 5 per account (new work waits; see [At capacity](#at-capacity)) |

See [Rate limits & errors](https://supercool.com/docs/api/errors#rate-limits) for everything else.
