Most agents need to read the contents of a thread before they decide what to do, whether that’s classifying it, adding a label, summarising it into a note, or generating a reply. This page covers how to read thread context via the GraphQL API.Documentation Index
Fetch the complete documentation index at: https://www.plain.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Get a thread
Thethread query returns a thread by ID along with its metadata. It throws if the thread doesn’t exist. This operation requires the thread:read permission.
customer, assignee, labels, …) are lazy-loaded, so accessing them triggers a separate API call. See the GraphQL SDK for more on how this works.
Get the thread content as LLM text
Each entry in a thread’s timeline (an inbound message, an outbound reply, a note, an assignment change, a label change) exposes anllmText field. This is a plain-text rendering of the entry shaped for feeding into a language model.
To get the full thread as LLM-ready text, paginate through timelineEntries and concatenate llmText:
llmText is null for entry types where there’s nothing meaningful to render. Skip those entries.Reading individual fields
If you don’t need the whole thread, you can read specific data directly. Some common patterns:- The customer: use
thread.customer, orplain.query.customer({ customerId }). Useful for looking up subscription tier, external IDs, or anything else attached to the customer. - Custom thread fields: read structured data attached to the thread. See thread fields.
- The triggering message: for events like
thread.email_receivedorthread.chat_received, the message itself is on the webhook payload. No extra API call needed if that’s all you want.

