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

# Messages

> Send, reply, forward, batch, search, raw.

# Messages

All message routes live under an inbox: `/v0/emails/inboxes/:inbox_id/emails…`.

## Send

`POST …/emails/send` with `Idempotency-Key` header support:

```json theme={null}
{ "to": ["u@e.com"], "cc": [], "bcc": [], "subject": "Hi", "text": "…",
  "html": "<p>…</p>", "reply_to": [], "attachments": [{ "filename": "a.pdf", "content": "<base64>" }],
  "headers": {}, "labels": ["campaign"], "track_opens": true }
```

Attachments take `content` (base64, 6 MB total request cap) or `url`
(fetched, 30 MB cap) — stored on R2. `track_opens` injects a 1px pixel;
first open adds the `opened` label and fires `email.opened` once.
Sends are allow/block-list gated (403 `rejected` + `email.rejected` event).

## Conversation

* `POST …/emails/:id/reply` and `/reply-all` — recipients/subject/threading
  derived from the source email.
* `POST …/emails/:id/forward` — new thread, `Fwd:` subject, body merged.
* `GET …/emails/search?q=` — substring + tokenized-body search.
* `POST …/batch-get` `{ email_ids[] }`, `POST …/batch-update` with
  `add_labels` / `remove_labels` (single string or array).
* `PATCH …/:id` relabels one message; `DELETE` removes it and recomputes the thread.
* `GET …/:id/raw` returns the RFC822 source (`message/rfc822`).

Message objects carry `labels`, `preview`, `extracted_text` (quoted replies
stripped), `attachments[]` metadata, `in_reply_to`, `references`, `headers`.
