# Get Thread

> Retrieve one inbox reply with its lead, campaign and original email.

Requires an API key with the `read` scope.

Returns the reply itself. For the full back-and-forth of sent and received messages, use [Get Conversation](/api-reference/inbox/get-thread). Reading a thread does not mark it read unless you ask.

## Path Parameters

<ParamField path="reply_id" type="string" required>
  The unique identifier of the reply.
</ParamField>

## Query Parameters

<ParamField query="markRead" type="boolean" default="false">
  Mark the thread as read while fetching it.
</ParamField>

## Response

<ResponseField name="data" type="object">
  The thread.

  <Expandable title="data">
    <ResponseField name="id" type="string">Reply identifier.</ResponseField>
    <ResponseField name="accountId" type="string">Mailbox that received the reply.</ResponseField>
    <ResponseField name="campaignId" type="string">Campaign the reply belongs to, or `null`.</ResponseField>
    <ResponseField name="leadId" type="string">Lead the reply belongs to, or `null`.</ResponseField>
    <ResponseField name="fromEmail" type="string">Sender address.</ResponseField>
    <ResponseField name="toEmail" type="string">Recipient address.</ResponseField>
    <ResponseField name="subject" type="string">Subject line.</ResponseField>
    <ResponseField name="body" type="string">Message body as received (HTML when the sender sent HTML).</ResponseField>
    <ResponseField name="bodyPlain" type="string">Plain-text body.</ResponseField>
    <ResponseField name="messageId" type="string">Message-ID header of the reply.</ResponseField>
    <ResponseField name="inReplyTo" type="string">Message-ID the reply answers, or `null`.</ResponseField>
    <ResponseField name="category" type="string">Reply category, for example `interested`.</ResponseField>
    <ResponseField name="isRead" type="boolean">Whether the thread is marked read.</ResponseField>
    <ResponseField name="isStarred" type="boolean">Whether the thread is starred.</ResponseField>
    <ResponseField name="receivedAt" type="string">ISO 8601 timestamp.</ResponseField>
    <ResponseField name="createdAt" type="string">ISO 8601 timestamp.</ResponseField>
    <ResponseField name="account" type="object">`id`, `email` and `displayName` of the receiving mailbox. Present when the mailbox exists.</ResponseField>
    <ResponseField name="lead" type="object">The matched lead: `id`, `email`, `firstName`, `lastName`, `company`, `title`, `phone`, `linkedinUrl`, `website`, `status`, `notes`. Present when a lead matched.</ResponseField>
    <ResponseField name="campaign" type="object">`id` and `name` of the campaign. Present when the reply belongs to one.</ResponseField>
    <ResponseField name="originalEmail" type="object">The email being answered: `id`, `subject`, `body`, `bodyPreview`, `fromEmail`, `toEmail`, `sentAt`. Present when it is known.</ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
```bash cURL
curl -X GET "https://api.foxreach.io/api/v1/inbox/threads/rpl_abc123?markRead=true" \
  -H "X-API-Key: otr_your_key"
```

```python Python SDK
from foxreach import FoxReach

client = FoxReach(api_key="otr_your_key")
thread = client.inbox.get("rpl_abc123", mark_read=True)
```

```typescript TypeScript SDK
import { FoxReach } from "foxreach";

const client = new FoxReach({ apiKey: "otr_your_key" });
const thread = await client.inbox.get("rpl_abc123", { markRead: true });
```
</RequestExample>

<ResponseExample>
```json
{
  "data": {
    "id": "rpl_abc123",
    "accountId": "cea_abc123",
    "campaignId": "cmp_abc123",
    "leadId": "lead_abc123",
    "fromEmail": "jane@acme.com",
    "toEmail": "outreach@company.com",
    "subject": "Re: Quick question",
    "body": "<p>Sounds interesting, can we talk Thursday?</p>",
    "bodyPlain": "Sounds interesting, can we talk Thursday?",
    "messageId": "<abc123@mail.acme.com>",
    "inReplyTo": "<def456@company.com>",
    "category": "interested",
    "isRead": true,
    "isStarred": false,
    "receivedAt": "2026-10-30T14:12:00+00:00",
    "createdAt": "2026-10-30T14:12:05+00:00",
    "account": { "id": "cea_abc123", "email": "outreach@company.com", "displayName": "John from Company" },
    "campaign": { "id": "cmp_abc123", "name": "Q4 outreach" }
  }
}
```
</ResponseExample>

## Errors

| Status | Description |
|--------|-------------|
| `401` | Missing, invalid, revoked or expired API key |
| `403` | API key does not have the required scope: `read` |
| `404` | Reply not found, or it belongs to another workspace |

## Rate Limit

- **100 requests per minute, per API key.** Fixed 60-second window.
- Every response includes `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` (unix epoch seconds).
- A `429` response includes a `Retry-After` header (seconds until the bucket resets).

For client-side patterns (`Retry-After`, exponential backoff, monitoring `X-RateLimit-Remaining`), see [Rate Limiting](/rate-limiting).
