# GET /v1/inbound/{id}

Read a received message

The message with its envelope, parties, headers, text, HTML and attachment descriptors; the attachment bytes and the raw message are downloads of their own. Once the stream’s content window has passed, the content fields are null and contentAvailable is false.

Takes a server key (`sk_…`, or `sk_test_…` on a test server) as a bearer token. TypeScript: `sendora.inbound.get(inboundMessageId)`. Python: `sendora.inbound.get(inbound_message_id)`.

## Parameters

- `id` (path, required, string (uuid)): The inbound message id.

## Responses

### 200 The received message with everything but the attachment bytes.

- `inboundMessageId` (string (uuid), required)
- `streamId` (string (uuid), required): The inbound stream that received it.
- `receivedAt` (string (date-time), required): When the message was accepted from the sending server.
- `envelopeRecipient` (string, required): The address of yours the message was sent to.
- `mailboxHash` (string or null, required): The text after the plus sign in that address, when the sender used one.
- `sizeBytes` (integer, required)
- `attachmentCount` (integer, required)
- `hasText` (boolean, required)
- `hasHtml` (boolean, required)
- `parseIssue` (string or null, required): What the parser met; null when the message parsed clean. A hard issue empties the parsed parts, and the raw message stays: `no_headers`, `header_block_too_large`, `too_many_headers`, `too_many_parts`, `nesting_too_deep`, `missing_boundary`, `decoded_too_large`, `parse_timeout`, `parser_error`. A soft issue keeps them and says what was changed or dropped: `truncated_multipart`, `too_many_attachments`, `unknown_transfer_encoding`, `undecodable_container`, `filename_sanitised`, `control_chars_stripped`, `multiple_from`, `duplicate_header`, `malformed_header_dropped`, `address_list_truncated`, `header_value_truncated`. A message with several names the hard one, or the first soft one in this order.
- `authentication` (object, required): What Sendora found when it checked the message; unchecked until the checks have run.
  - `spf` ("pass" | "fail" | "softfail" | "neutral" | "none" | "temperror" | "permerror" | "unchecked", required): SPF for the address in MAIL FROM.
  - `spfHelo` ("pass" | "fail" | "softfail" | "neutral" | "none" | "temperror" | "permerror" | "unchecked", required): SPF for the name the sending server gave in HELO.
  - `dkim` ("pass" | "fail" | "none" | "temperror" | "permerror" | "unchecked", required)
  - `dmarc` ("pass" | "fail" | "none" | "temperror" | "permerror" | "unchecked", required)
  - `dmarcPolicy` ("none" | "quarantine" | "reject" or null, required): What the sender’s domain asks for; told only when DMARC failed.
  - `arc` ("none" | "pass" | "fail" | "unchecked", required)
  - `checkedAt` (string (date-time) or null, required): When the checks ran; null until they have.
- `contentAvailable` (boolean, required): False once the stream’s content window has passed; only the reference remains.
- `contentExpiresAt` (string (date-time), required): When the content goes.
- `from` (object or null, required): The From header; null without it or once the content is gone.
  - `address` (string, required)
  - `name` (string or null, required)
- `subject` (string or null, required)
- `date` (string (date-time) or null, required): The sender’s Date header as ISO 8601, when it was a real moment.
- `envelope` (object or null, required): Null once the content is gone.
  - `sender` (string or null, required): The MAIL FROM address; null for a bounce.
- `replyTo` (array of object, required)
  - `address` (string, required)
  - `name` (string or null, required)
- `to` (array of object, required): Up to 100 entries; toCount is the whole number.
  - `address` (string, required)
  - `name` (string or null, required)
- `toCount` (integer, required)
- `cc` (array of object, required): Up to 100 entries; ccCount is the whole number.
  - `address` (string, required)
  - `name` (string or null, required)
- `ccCount` (integer, required)
- `messageIdHeader` (string or null, required)
- `inReplyTo` (string or null, required)
- `references` (array of string, required)
- `headers` (array of object or null, required): Every header in order; null once the content is gone.
  - `name` (string, required)
  - `value` (string, required)
- `text` (string or null, required): The plain-text body; null without one or once the content is gone.
- `html` (string or null, required): The HTML body as received; null without one or once the content is gone.
- `attachments` (array of object, required)
  - `attachmentId` (string (uuid), required)
  - `position` (integer, required): Its place among the message’s attachments, from 0.
  - `name` (string or null, required): The filename, sanitised; null once the content is gone.
  - `contentType` (string or null, required): The type the sender declared; every download is served as application/octet-stream.
  - `contentId` (string or null, required): The Content-ID an HTML body refers to with cid:.
  - `size` (integer, required): Bytes.
  - `inline` (boolean, required): True for a part shown in the body rather than offered as a file.

Example:

```json
{
  "inboundMessageId": "4d1f8b2e-9c3a-4e7b-8f21-6a5d0c9e7b31",
  "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "receivedAt": "2026-09-19T08:00:02.000Z",
  "envelopeRecipient": "7c9e6679742540de944be07fc1f90ae7@inbound.sendora.se",
  "mailboxHash": null,
  "sizeBytes": 48213,
  "attachmentCount": 1,
  "hasText": true,
  "hasHtml": false,
  "parseIssue": null,
  "authentication": {
    "spf": "pass",
    "spfHelo": "pass",
    "dkim": "pass",
    "dmarc": "pass",
    "dmarcPolicy": null,
    "arc": "none",
    "checkedAt": "2026-09-19T08:00:03.000Z"
  },
  "contentAvailable": true,
  "contentExpiresAt": "2026-10-19T08:00:02.000Z",
  "from": {
    "address": "anna@example.com",
    "name": "Anna Andersson"
  },
  "subject": "A question about my order",
  "date": "2026-09-19T08:00:00.000Z",
  "envelope": {
    "sender": "anna@example.com"
  },
  "replyTo": [],
  "to": [
    {
      "address": "7c9e6679742540de944be07fc1f90ae7@inbound.sendora.se",
      "name": null
    }
  ],
  "toCount": 1,
  "cc": [],
  "ccCount": 0,
  "messageIdHeader": "<question-1@example.com>",
  "inReplyTo": null,
  "references": [],
  "headers": [
    {
      "name": "From",
      "value": "Anna Andersson <anna@example.com>"
    },
    {
      "name": "Subject",
      "value": "A question about my order"
    }
  ],
  "text": "Hi!\n",
  "html": null,
  "attachments": [
    {
      "attachmentId": "9b7e2c41-3f6d-4a8e-b2c5-1d0f7e6a9c58",
      "position": 0,
      "name": "invoice.pdf",
      "contentType": "application/pdf",
      "contentId": null,
      "size": 46102,
      "inline": false
    }
  ]
}
```

## Errors

Every error answers `error`, the code, and `message`, a sentence for a person. A code that adds fields is shown in full below the table.

| Code | Status | Meaning |
| --- | --- | --- |
| `unauthorized` | 401 | The key is missing, malformed or revoked. |
| `wrong_token_kind` | 403 | The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes. |
| `not_found` | 404 | No such inbound message of this server. |
| `content_unreadable` | 409 | The stored content of this received message cannot be opened. Sendora has been told. |
