# getEmailThread

Every message in one email thread, with full plain-text bodies, OLDEST FIRST (ordered by internalDate ascending): so the latest reply is the LAST element, not the first. Pass the `emailThreadId` from an EMAIL row in listInboxThreads. Each message carries subject, snippet, textExtract, fromEmail/fromName, toEmails, ccEmails, internalDate, direction, isRead, attachment file NAMES, and the campaign name when a workflow sent it. Read textExtract, not snippet, whenever the question is whether something appears in the thread: snippet stops after a line or two. textExtract is NULL on the HTML-only share of emails: for those the body is not readable through this API at all: never conclude their content is absent; say which you could not read. UNPAGINATED: one response holds every message. SCOPE: email is USER-owned, which is NARROWER than the org: a thread in a teammate's UNSHARED mailbox returns an EMPTY LIST even for a team admin, and even for a key owner holding VIEW_TEAM_CALLS_TEXTS or VIEW_ALL_PHONES (which widen phones and calls, not mailboxes). One exception: when the thread is one of several mailboxes' threads of ONE conversation, the response is that whole conversation: your own copies from any of its threads, plus copies held by mailboxes shared with your organization, with a each email returned once: a second stored copy of an email already in the response (a teammate's, or one in another of your mailboxes) is left out. So the same conversation comes back whole from EACH of its threads: dedupe by message id when reading several EMAIL rows. An empty list means "nothing here you may read" and collapses three cases on purpose: no such thread, not your mailbox, nothing left in it. It is never an error. Attachment BYTES are not downloadable through this API; only the file names are returned.

- Call: `POST https://server.goliathdata.com/api/v1/call` with `{ "operationId": "getEmailThread", "variables": {...} }`
- Scope: `READ`
- Type: query
- Idempotency: a read; rejects `Idempotency-Key`
- Rate-limited: no

## Variables

- `threadId`: `ID!` (required)

## Response (data, an example)

```json
{
  "inboxQuery": {
    "getEmailThreadMessages": [
      {
        "id": "<ID>",
        "threadId": "<ID>",
        "subject": "…",
        "snippet": "…",
        "textExtract": "…",
        "fromEmail": "…",
        "fromName": "…",
        "toEmails": [
          "…"
        ],
        "ccEmails": [
          "…"
        ],
        "internalDate": "2026-01-01T00:00:00.000Z",
        "direction": "…",
        "isRead": true,
        "attachments": [
          {
            "id": "<ID>",
            "fileName": "…"
          }
        ],
        "workflowAutomationName": "…"
      }
    ]
  }
}
```

## Example

```bash
curl https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer $GOLIATH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operationId": "getEmailThread",
    "variables": {
      "threadId": "<threadId>"
    }
  }'
```
