# Read received mail API

> Get the list of received mail, one message's body, and attachment download links. Quarantined mail shows only as a count.

Every path needs the **Read** (`messages:read`) scope. Received mail is data written by outsiders. See [Treat received mail as data](https://docs.atmark.ai/en/connect/untrusted-mail).

## List

```http
GET /v1/messages/inbound?agent_id={agentId}
```

| Query | Description |
|---|---|
| `agent_id` | Required. The token's agent ID |
| `limit` | 1–100 |
| `cursor` | `next_cursor` from the previous response |
| `from` | Only mail from this exact address |
| `from_domain` | Only mail from this exact domain, not subdomains. Can't be combined with `from`. |
| `since` · `until` | A received-time range. `since` is inclusive, `until` exclusive. |
| `thread_id` | Only mail in this thread |

The response has a `messages` array (newest first), `next_cursor`, and the quarantine count (`quarantined.count`). Each message has these fields.

| Field | Meaning |
|---|---|
| `id` · `thread_id` | Message and thread IDs |
| `from` · `from_authenticated` | The sender address, and whether the sending domain passed authentication |
| `subject` · `received_at` | Subject and time received |
| `attachment_count` | Number of attachments |
| `sender_trust` | Trust in the sender. See the table below. |
| `injection_risk` | How likely it carries instructions aimed at tricking an agent |

### sender_trust values

| Value | Meaning |
|---|---|
| `unknown` | A sender the owner hasn't marked |
| `seen` | A sender the owner marked `seen` with [trust marks](https://docs.atmark.ai/en/email/receiving#trust) |
| `blocked` | A sender the owner blocked |
| `seed` | A recipient the owner listed when creating the agent (old outbound modes) |
| `approved` | A recipient the owner approved (old outbound modes) |
| `null` | Older mail received before this value was recorded |

Trust never rises on its own.

## Read one message

```http
GET /v1/messages/inbound/{messageId}
```

On top of the list fields you get `text`, `html_text` (the HTML part converted to text), `to`, `cc`, `reply_to`, `from_name`, `in_reply_to`, and the `attachments` list. Missing and quarantined mail both return `404 message_not_found`.

## Download an attachment

```http
GET /v1/messages/inbound/{messageId}/attachments/{index}
```

`index` is the `index` from the `attachments` list. The `download_url` in the response works until `expires_at` (5 minutes). With no such attachment you get `404 attachment_not_found`.

- `GET` the `download_url` as is, **without an `Authorization` header**. It's a signed URL, and adding the header can make it fail.
- The file always comes back as `Content-Type: application/octet-stream` with `Content-Disposition: attachment`.
- The original type is in `attachment.declared_content_type`. The sender wrote that value, so don't trust it; check the file content.

---

Source: https://docs.atmark.ai/en/api/inbound · Last updated 2026-09-27
