---
title: "Get inbox thread"
method: GET
path: "/v3/inbox/threads/{id}"
tags: ["Inbox"]
---

# Get inbox thread

`GET /v3/inbox/threads/{id}`

<small>_Requires the `inbox:read` scope (or a broader one that includes it)._</small>

Returns a single thread including the ordered message history.

## Path parameters

- `id` integer, required

## Response `200`

Inbox thread

- object — Full inbox thread with the contact, channel-specific account ids, sequence, category, meeting-intent flag, and the ordered list of messages.
  - `id` integer, required
  - `channel` 'unknown' | 'email' | 'linkedIn', required
  - `isRead` boolean — Whether the thread is marked as read by the current user.
  - `contact` object, required — Contact party on the other end of an inbox thread. Two shapes are possible, distinguished by the `isDeleted` flag: - **Live contact** (`isDeleted: false`) — `id` and `ownerId` reference the live contact record; `fullName`, `email`, `linkedInProfileUrl`, `phone`, `companyName`, `title` come from the live record (any may still be `null` if the corresponding field is unset on the contact, e.g. `email` is `null` for a LinkedIn-only contact). - **Deleted contact** (`isDeleted: true`) — the underlying contact record has been removed, so `id` and `ownerId` are `null`. The remaining identifying fields (`fullName`, `email`, `linkedInProfileUrl`, `phone`, `companyName`, `title`) are populated from the snapshot stored on the thread when it was created — typically enough for the user to recognise *who* the thread was with even though the contact no longer exists in their workspace.
    - `id` integer, nullable — Contact id. `null` when the contact has been deleted.
    - `ownerId` integer, nullable — User id of the contact's owner. `null` when the contact has been deleted.
    - `fullName` string, nullable — Display name. May still be populated from the thread snapshot when the contact has been deleted.
    - `email` string, nullable — Contact email address. `null` for LinkedIn-only contacts.
    - `linkedInProfileUrl` string, nullable — LinkedIn profile URL. `null` for email-only contacts.
    - `phone` string, nullable
    - `companyName` string, nullable
    - `title` string, nullable
    - `isDeleted` boolean, required — `true` when the underlying contact record has been deleted from the workspace. In that case `id` and `ownerId` are `null` and the remaining identifying fields reflect the snapshot stored on the thread when the message arrived; `false` when the contact is still present and `id` / `ownerId` reference the live record.
  - `emailAccountId` integer, nullable — Email account that owns this thread. `null` for non-email threads.
  - `linkedInAccountId` integer, nullable — LinkedIn account that owns this thread. `null` for non-LinkedIn threads.
  - `sequence` object, nullable — Minimal sequence reference attached to an inbox thread.
    - `id` integer, required
    - `name` string, required
  - `messages` union[], required
    - union — Polymorphic message variant within an inbox thread, discriminated by `channel`. Email messages carry recipient and subject metadata; LinkedIn messages carry only the shared base fields.
      - object — Email message within an inbox thread.
        - `channel` 'email', required — Discriminator — always `email` for this variant.
        - `messageId` string, nullable — Unique identifier of the message within the thread. Use this value as `replyToMessageId` when sending a reply to a specific message.
        - `date` string, date-time
        - `body` string, nullable — Message body. May contain HTML.
        - `fromName` string, nullable
        - `isOutbound` boolean — True when the message was sent from this account; false when received.
        - `status` object, nullable — Per-message status. Populated for outbound messages that surfaced a delivery error; absent (`null`) on healthy inbound or successfully delivered outbound messages.
          - `state` 'ok' | 'needsAttention' — Message state, parallel to the thread state.
          - `code` 'linkedInAccountNotEnabled' | 'linkedInInvalidCookie' | 'linkedInSendingLimitExceeded' | 'linkedInMessageSendingDisabled' | 'linkedInSalesNavigatorSubscriptionMissing' | 'linkedInMessageTooLong' | 'linkedInRenderFailed' | 'linkedInUnknown' | 'linkedInProfileNotConnected', nullable — Specific delivery error that put the message into `needsAttention`. `null` for healthy messages.
          - `occurredAt` string, date-time, nullable — Timestamp of the most recent status transition.
        - `aiSentType` 'aiGenerated' | 'aiGeneratedEdited' | 'autoSent', nullable — For a sent message, identifies that it was generated by AI. `null` when the message was not AI-generated.
        - `subject` string, nullable
        - `fromAddress` string, nullable
        - `to` string[], nullable
        - `cc` string[], nullable
        - `bcc` string[], nullable
      - object — LinkedIn message within an inbox thread.
        - `channel` 'linkedIn', required — Discriminator — always `linkedIn` for this variant.
        - `messageId` string, nullable — Unique identifier of the message within the thread.
        - `date` string, date-time
        - `body` string, nullable
        - `fromName` string, nullable
        - `isOutbound` boolean
        - `status` object, nullable — Per-message status. Populated for outbound messages that surfaced a delivery error; absent (`null`) on healthy inbound or successfully delivered outbound messages.
          - `state` 'ok' | 'needsAttention' — Message state, parallel to the thread state.
          - `code` 'linkedInAccountNotEnabled' | 'linkedInInvalidCookie' | 'linkedInSendingLimitExceeded' | 'linkedInMessageSendingDisabled' | 'linkedInSalesNavigatorSubscriptionMissing' | 'linkedInMessageTooLong' | 'linkedInRenderFailed' | 'linkedInUnknown' | 'linkedInProfileNotConnected', nullable — Specific delivery error that put the message into `needsAttention`. `null` for healthy messages.
          - `occurredAt` string, date-time, nullable — Timestamp of the most recent status transition.
        - `aiSentType` 'aiGenerated' | 'aiGeneratedEdited' | 'autoSent', nullable — For a sent message, identifies that it was generated by AI. `null` when the message was not AI-generated.
  - `aiDraft` object, nullable — The thread's pending AI-drafted reply, awaiting review. A thread has at most one active AI draft.
    - `message` string, required — The AI-generated draft reply body. May contain HTML.
    - `cc` string[] — Draft CC recipients. Empty when the draft has none.
    - `bcc` string[] — Draft BCC recipients. Empty when the draft has none.
    - `attachments` object[] — Files attached to the draft. Empty when the draft has none.
      - `id` integer, required — Attachment identifier — pass this in `attachmentIds` arrays on email-template, sequence-step, and inbox-message endpoints.
      - `fileName` string, required — Original file name as supplied by the upload.
      - `size` integer, required — File size in kilobytes (rounded up).
  - `category` object, nullable — Minimal category reference embedded in thread responses.
    - `id` integer, required
    - `name` string, required
  - `hasMeetingIntent` boolean — Whether the thread has been flagged as carrying meeting intent (manually or via AI detection).

## Other responses

- `400` — Invalid id parameter or a business-rule rejection.
- `401` — Unauthorized. The response body is empty; check the `WWW-Authenticate` header for the expected scheme.
- `403` — Inbox feature is not available for this user or team.
- `404` — Thread not found or not visible to the current user.
- `429` — Too Many Requests

---

[API](https://skmtc.net/reply/apis/reply-api.md) · [All operations](https://skmtc.net/reply/apis/reply-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/reply/reply-api/revisions/1c3d32eaf95e/schema)
