:::endpoint GET /v1/me/mail/messages/{id}

The whole exchange the message sits in, oldest first, bodies and all. One call
rather than one per message: unfolding a reply has to be instant, and a five
message thread would otherwise be five round trips and a spinner where the words
should be.

:::warning This marks the conversation as read
Every message in it, and it also records who read it. There is no way to fetch a
body without that happening. See [Reading mail](/docs/api/mail/overview).
:::

## Request

```bash
curl https://api.proppertrading.com/v1/me/mail/messages/1552 \
  -H "Authorization: Bearer ptat_9f2c1a44_3b8e7d2f5c9a1b4e6d8f0a2c4e6b8d1f"
```

## Response

```json
{
    "data": {
        "id": 1552,
        "object": "mail_conversation",
        "thread_id": 611,
        "address_id": 32,
        "subject": "Payout request",
        "folder": "inbox",
        "labels": [{ "id": 10, "name": "Payouts", "color": "blue" }],
        "assignee": { "id": 41, "name": "Han Aarts" },
        "answered": {
            "id": 41,
            "name": "Han Aarts",
            "at": "2026-08-19T14:02:11.000000Z"
        },
        "notes": [
            {
                "id": 88,
                "object": "mail_note",
                "body": "Called them back, waiting on the bank statement.",
                "author": "Han Aarts",
                "author_id": 41,
                "is_mine": false,
                "can_edit": false,
                "created_at": "2026-08-20T14:02:11.000000Z",
                "edited": false
            }
        ],
        "elsewhere": { "trash": 1 },
        "hidden": 0,
        "base_url": "https://acmefunded.com",
        "messages": [
            {
                "id": 1552,
                "object": "mail_message",
                "address_id": 32,
                "direction": "inbound",
                "from_email": "jamie@example.com",
                "from_name": "Jamie Rivera",
                "to_recipients": [
                    { "email": "support@mail.acmefunded.com", "name": null }
                ],
                "cc_recipients": [],
                "subject": "Payout request",
                "folder": "inbox",
                "is_starred": false,
                "message_at": "2026-08-19T13:30:36.000000Z",
                "spam_score": 0.4,
                "html": "<p>Hi, I passed the evaluation last week.</p>",
                "quoted": "",
                "text": "Hi, I passed the evaluation last week.",
                "preview": "Hi, I passed the evaluation last week.",
                "has_attachments": true,
                "attachments": [
                    {
                        "id": 110,
                        "name": "statement-july.pdf",
                        "content_type": "application/pdf",
                        "size_bytes": 84213
                    }
                ],
                "was_unread": true,
                "readers": []
            }
        ]
    },
    "meta": { "request_id": "req_01kz4bkr1aj1gv63d8fv3133ey" }
}
```

| Field                | Description                                                                                                             |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `subject`            | The subject the exchange started under, not the latest "Re: Re:" of it                                                  |
| `elsewhere`          | Messages of this conversation in folders this view does not reach, by folder                                            |
| `hidden`             | Older messages left out. A conversation is capped at 30                                                                 |
| `base_url`           | What a web view resolves the relative image links in `html` against                                                     |
| `html`               | The message itself, sanitised, without the exchange it carries                                                          |
| `quoted`             | The exchange it carries, sanitised. Empty when there is none to fold away                                               |
| `text`               | The same half as `html`, in plain words. Not the raw text part of the mail, which still has the whole exchange under it |
| `was_unread`         | Whether this one was still unread when the conversation was opened. Unfold those, collapse the rest                     |
| `readers`            | Who has had this message in front of them, and when                                                                     |
| `attachments[].name` | What the sender called the file. Their word, so do not put it into a path without cleaning it first                     |
| `content_type`       | What the sender said the file is. Also their word. The download answers `application/octet-stream` regardless           |
| `size_bytes`         | The stored size, in bytes                                                                                               |

Inline images are not listed under `attachments`. They are already in `html`,
and listing the same picture twice reads as two pictures.

## Rendering the body

`html` is sanitised and safe to render. Put it in a web view with JavaScript
disabled and the base URL set to `base_url`, and keep your token out of that
view. `quoted` is the thread the message carries underneath it; fold it away.

`html`, `quoted` and `text` are three views of one split and always agree, so
render either `html` or `text` and put `quoted` behind a control. Where the
split falls is worked out from the markup, because that is where a mail client
says which part of a reply it wrote itself. Not every client says so and not
every one that does says it the same way, so `quoted` is empty for a message
whose quote could not be found with certainty, and the whole of it arrives in
`html` and `text`. Nothing is ever dropped: the two halves put back together
are the message that came in.

Remote images load. This is a shared business mailbox where the pictures are
invoices and signatures, so a notice above every one of them would be a tap
between reading and being able to read.

## Notes

`notes` is the team's own remarks on this conversation, oldest first. They are
never sent and never seen by whoever wrote in.

They come down here rather than from an endpoint of their own, because a remark
that arrives after somebody has started typing their reply is a remark that did
not do its job. Writing, changing and removing them is
[add a note](/docs/api/mail/note-create) and the two pages after it, which also
describe every field on one.

## Errors

| Status | Code                    | Meaning                                                                                                      |
| ------ | ----------------------- | ------------------------------------------------------------------------------------------------------------ |
| 403    | `insufficient_scope`    | This device does not hold `mail:read`                                                                        |
| 403    | `mailbox_not_permitted` | The account may not open a mailbox at all                                                                    |
| 404    | `resource_not_found`    | No such message in a mailbox you can read. A message in another mailbox, or another firm's, answers the same |