---
title: "Get one thread"
method: GET
path: "/inbox/threads/{thread_id}/"
tags: ["inbox"]
---

# Get one thread

`GET /inbox/threads/{thread_id}/`

## Request

- Base URL: `https://api.getoneprofile.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.getoneprofile.ai/inbox/threads/{thread_id}/`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

## Path parameters

- `thread_id` string, uuid, required

## Response `200`

Successful Response

- ThreadReadSchema
  - `came_back` boolean, required: Back in the Inbox because our answer went three business days unanswered: `returns_at` has passed.
  - `can_reply_on_linkedin` boolean: Whether an explicit channel='linkedin' reply can go out on this thread, because it carries a LinkedIn member identity and a paired account. The composer's channel toggle keys off this.
  - `channel` 'email' | 'linkedin', required: Which surface a conversation happens on. Threads are contact-scoped, not channel-scoped, so this says how a thread is REACHED rather than partitioning the inbox: a reply arrives, is classified and stops the cadence identically either way, and only the send path differs.
  - `contact_email` string, nullable, required
  - `contact_key` string, required
  - `contact_linkedin_url` string, nullable: The contact's LinkedIn profile URL, when our own evidence (invitation ledger, dispatched actions, or the sequence's mapped column) names one. Only the SINGLE-thread read resolves it; the list leaves it null.
  - `contact_name` string, required
  - `contact_replied` boolean, nullable: Whether the contact has written back in this thread: a person's reply, never an auto-reply, a bounce or a robot's acknowledgement. False on a send nobody answered, which the working views never list. Only the thread LIST populates it; single-thread reads leave it null.
  - `created_at` string, date-time, required
  - `done_at` string, date-time, nullable: When a person marked the conversation done. `is_done` says whether the mark still holds.
  - `enrolment_id` string, uuid, nullable: The contact's enrolment in this thread's sequence, when it has one: the id the 'Resume cadence' action targets.
  - `follow_up_expected` boolean, required: Whether an answer of ours they leave unanswered would come back to the Inbox: the contact has written, and the verdict on their latest reply, by the classifier or a label a person set, does not say the conversation is over.
  - `has_pending_draft` boolean: An AI reply is waiting for approval on this thread: the list row's 'Action required' mark. Only the thread LIST populates it; single-thread reads leave it False and the open conversation fetches the draft itself.
  - `id` string, uuid, required
  - `is_bounce` boolean, required
  - `is_done` boolean, required: Marked done, and no new message has reached us since: out of the Inbox. Their reply, or an answer of ours, arriving after the mark ends it, whatever time the message gives itself; an auto-reply, a bounce, a forward or a reply still waiting on Tasks does not.
  - `is_out_of_office` boolean, required
  - `is_unread` boolean, required
  - `label_ids` string[], required
  - `last_message_at` string, date-time, required
  - `last_snippet` string, required
  - `linkedin_account_status` 'pending' | 'active' | 'revoked': Pairing lifecycle. ``PENDING`` exists between "the user asked to connect" and "an extension actually bound a LinkedIn member to it", so the sender page can show a half-finished connection rather than nothing at all.
  - `linkedin_checkpoint_status` 'ok' | 'checkpoint': Whether LinkedIn is currently challenging this account.
  - `linkedin_last_seen_at` string, date-time, nullable: When a browser on that account last checked in; null when none ever has. Single-thread read only; the list leaves it null.
  - `linkedin_presence` 'active' | 'idle' | 'not_seen': How recently ANY browser connected to this sender checked in. Three states, not two, because two different questions are asked of a connection. ``ACTIVE`` answers "can a step run right now": a browser is open and heartbeating. ``IDLE`` answers "is this still set up": the laptop was closed for the evening. ``NOT_SEEN`` is the one that needs a person: nothing has checked in for a day, and queued work is silently waiting.
  - `linkedin_queue_expiry_days` integer, nullable: Always null. The wait window was retired: a queued LinkedIn reply now waits for a person, or for a browser, without expiring. The field stays so older clients still find it; a null hides the composer's sentence about it.
  - `linkedin_sender_profile_id` string, uuid, nullable: The sender the LinkedIn account belongs to, so the composer can send a person to that sender's LinkedIn tab to reconnect. Single-thread read only; the list leaves it null.
  - `listed_at` string, date-time, required: The moment the list sorts this conversation by: its last message, or later when a reminder went off or, on the Inbox's own views, when it came back from silence. The time to show beside the row.
  - `mailbox_id` string, uuid, nullable, required
  - `match_excerpt` string, nullable: The matched message, headlined around the match. Only set when searching.
  - `message_count` integer, required
  - `returns_at` string, date-time, nullable: When this conversation comes back to the Inbox if the contact stays quiet: three business days after our latest answer, at the same time of day, counted in the sender's timezone. In the past once it has come back (`came_back`). Null when it will not: they have the last word, the verdict on their latest reply, by the classifier or a label a person set, says the conversation is over (Negative, Meeting booked, Meeting completed, Closed or Wrong contact), or it is done.
  - `sequence_id` string, uuid, nullable, required
  - `snoozed_until` string, date-time, nullable: Hidden from the working views until this instant.
  - `step_id` string, uuid, nullable, required
  - `stop_reason` 'reply' | 'unsubscribe' | 'bounce' | 'manual' | 'company_reply' | 'row_left_audience' | 'row_left_paused' | 'step_removed' | 'removed' | 'cooldown' | 'rejected' | 'mailbox_removed' | 'trashed' | 'trashed_paused'
  - `subject` string, required
  - `updated_at` string, date-time, required

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found.
- `422`: Invalid request made to the API.
- `500`: Internal server error.
- `502`: Bad gateway error.
- `503`: Service unavailable.

---

[API](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile.md) · [All operations](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/llms.txt) · [OpenAPI document](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/revisions/4a6bd71e3f02?raw)
