Threads API

List conversation threads and retrieve thread details with messages.

GET /v1/mailboxes/:id/threads

GET/v1/mailboxes/:id/threads

List threads for a mailbox, sorted by most recent message. Returns the last 50 threads.

response — 200 OK
{
  "threads": [
    {
      "id": "c3d4e5f6-789a-4bcd-ef01-333333333333",
      "mailboxId": "a1b2c3d4-5678-4def-abcd-111111111111",
      "subject": "Project update",
      "messageCount": 3,
      "lastMessageAt": "2026-03-11T14:00:00.000Z",
      "participants": ["myagent@robotomail.co", "recipient@example.com"],
      "createdAt": "2026-03-11T12:00:00.000Z"
    }
  ],
  "metadata": {
    "overLimitCount": 3,
    "upgrade": {
      "browserUrl": "https://robotomail.com/billing",
      "apiEndpoint": { "method": "POST", "path": "/v1/billing/upgrade" },
      "hint": "POST /v1/billing/upgrade for a programmatic checkout URL, or visit browserUrl to sign in and upgrade"
    },
    "limitHint": {
      "current": 80,
      "limit": 100,
      "percentage": 80,
      "reset_date": "2026-05-01T00:00:00.000Z",
      "status": "near"
    }
  }
}

Inbound-limit gating. Threads are ordered by their newest visible message, and per-thread messageCount / lastMessageAt reflect visible messages only — so hidden activity never leaks through the ordering or counters. Threads whose every message is over-limit are excluded entirely and counted in metadata.overLimitCount (the number of hidden messages, not threads). The field is 0 under normal operation. Upgrading the plan or the first-of-month reset unlocks every gated message in place. See 402 INBOUND_LIMIT_EXCEEDED.

Metadata envelope

  • overLimitCount — number of hidden messages across the mailbox (0 under normal operation).
  • upgrade — always present. Carries browserUrl, apiEndpoint, and a hint string for ending the quota block.
  • limitHint — appears once monthly inbound usage reaches 50%. Snake-case shape (current, limit, percentage, reset_date, status) matching the inbound_usage block on webhook / SSE payloads. status is one of approaching, near, or limit_reached.

GET /v1/mailboxes/:id/threads/:threadId

GET/v1/mailboxes/:id/threads/:threadId

Get a thread with all its messages, ordered chronologically (oldest first).

response — 200 OK
{
  "thread": {
    "id": "c3d4e5f6-789a-4bcd-ef01-333333333333",
    "subject": "Project update",
    "messageCount": 3,
    "participants": ["myagent@robotomail.co", "recipient@example.com"],
    "messages": [
      {
        "id": "b2c3d4e5-6789-4abc-def0-222222222222",
        "direction": "OUTBOUND",
        "subject": "Project update",
        "bodyText": "Here is the latest...",
        "status": "DELIVERED",
        "createdAt": "2026-03-11T12:00:00.000Z"
      },
      {
        "id": "d4e5f6a7-89ab-4cde-f012-444444444444",
        "direction": "INBOUND",
        "subject": "Re: Project update",
        "bodyText": "Thanks for the update...",
        "status": "RECEIVED",
        "createdAt": "2026-03-11T13:00:00.000Z"
      }
    ]
  }
}

See Threading for how messages are grouped into threads.

Inbound-limit gating. Over-limit messages are filtered from messages, and messageCount / lastMessageAt reflect visible messages only. If every message in the thread is over-limit, the endpoint returns 404 instead of an empty-thread husk. Upgrading the plan or the first-of-month reset unlocks every gated message in place — a subsequent call returns them with full content. See 402 INBOUND_LIMIT_EXCEEDED.