---
title: "List messages in an inbox"
method: GET
path: "/inboxes/{id}/messages"
tags: ["messages"]
---

# List messages in an inbox

`GET /inboxes/{id}/messages`

## Request

- Base URL: `https://dash.mailsocket.app/api/v1`
- URL: `https://dash.mailsocket.app/api/v1/inboxes/{id}/messages`
- Auth: HTTP bearer

Returns message summaries for one inbox, newest first, with cursor
pagination. The optional `has_otp`, `subject_contains` and `from`
filters are ANDed together; invalid values are ignored gracefully
(never a 500). The pagination cursor is bound to the exact filter set,
so a cursor minted under one filter cannot be replayed under another.

## Path parameters

- `id` string, required

## Query parameters

- `limit` integer
- `cursor` string
- `has_otp` boolean
- `subject_contains` string
- `from` string
- `read` 'true' | 'false' | 'all'
- `q` string

## Response `200`

A page of message summaries.

- MessageSummaryListResponse
  - `data` MessageSummary[], required
    - `id` string, required
    - `inbox_id` string, required
    - `from` string, required: The From header.
    - `to` string[], required
    - `cc` string[], required
    - `subject` string, required
    - `received_at` string, date-time, required
    - `status` 'received' | 'parsing' | 'parsed' | 'failed', required
    - `otp` string, nullable
    - `otp_confidence` number, nullable
    - `magic_link` string, nullable
    - `links` string[], nullable
    - `detected_otp` string, nullable
    - `otp_context` string, nullable: A short (≤160 character) plain-text snippet around the extracted `otp`, e.g. "Your verification code is 123456. It expires in 10 minutes." HTML is stripped, whitespace collapsed, and the window is bounded so the full body is never exposed. Null when there is no OTP or its location cannot be found. Best-effort, additive.
    - `otp_candidates` object[], nullable: Ranked plausible codes beyond the primary `otp` (the also-rans an agent can use to disambiguate), scored with the same logic as the primary extraction. Each item is `{code, confidence}`. Null/empty when there is only one plausible code or none.
      - `code` string, required
      - `confidence` number, required
    - `provider_hint` string, nullable: Best-effort label of the sending service derived from the From header domain (e.g. "github", "google", "stripe") via a small static map. Null when the domain is unknown. Convenience only; not authoritative, no network lookup.
    - `read` boolean: Whether the message has been marked read (`read_at IS NOT NULL`).
    - `metadata` object, required: The owning inbox's `metadata` (`{}` when unset), echoed on every authenticated read. Never present on the public-messages payload.
  - `pagination` Pagination, required
    - `next_cursor` string, nullable, required: Opaque cursor for the next page, or null when there is none.
    - `has_more` boolean, required

## Other responses

- `401`: Missing or invalid API key.
- `403`: Account is not permitted to use the API.
- `404`: Resource not found (unknown or not owned).
- `422`: Request validation failed (malformed body or invalid parameter).
- `429`: Rate limit exceeded.

---

[API](https://skmtc.dev/mailsocket/apis/mailsocket-api.md) · [All operations](https://skmtc.dev/mailsocket/apis/mailsocket-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mailsocket/apis/mailsocket-api/revisions/e579500dfb7e?raw)
