Threads

In shortReference for all thread, state, and message methods on AgentFlowClient.

  • 7 min read
  • 8 sections
  • Updated
  • v0.9.2
  • Markdown

10xGraph organises conversation history into threads. Each thread has a unique thread_id and stores a sequence of messages and a state snapshot (checkpoint). The client provides methods to list, inspect, update, and delete threads and their messages.

Source: src/client.ts, src/endpoints/threads*.ts, src/endpoints/threadState.ts


Thread management

threads(request?)

List all threads. Supports optional search and pagination.

TypeScript
// List all threads
const response = await client.threads();

// With search
const response = await client.threads({ search: 'Paris' });

// With pagination
const response = await client.threads({ offset: 0, limit: 20 });

Overloads:

TypeScript
client.threads(): Promise<ThreadsResponse>
client.threads(request: ThreadsRequest): Promise<ThreadsResponse>
client.threads(search?: string, offset?: number, limit?: number): Promise<ThreadsResponse>

ThreadsRequest:

Field Type Description
search string Substring filter applied to thread names.
offset number Number of threads to skip (for pagination). Must be ≥ 0.
limit number Maximum number of threads to return. Must be > 0.

ThreadsResponse:

TypeScript
interface ThreadsResponse {
  data: {
    threads: ThreadItem[];
  };
  metadata: ResponseMetadata;
}

interface ThreadItem {
  thread_id: string;
  thread_name: string | null;
  user_id: string | null;
  metadata: Record<string, any> | null;
  updated_at: string | null;
  run_id: string | null;
}

threadDetails(threadId)

Fetch metadata for a single thread.

TypeScript
const response = await client.threadDetails('thread-123');
console.log(response.data.thread_data.thread);

Parameters:

Parameter Type Description
threadId string | number The thread ID. Must be non-empty (string) or ≥ 1 (integer).

ThreadDetailsResponse:

TypeScript
interface ThreadDetailsResponse {
  data: {
    thread_data: {
      thread: Record<string, any>;
    };
  };
  metadata: ResponseMetadata;
}

deleteThread(threadId, config?)

Delete a thread and all its associated state and messages. This is irreversible.

TypeScript
await client.deleteThread('thread-123');

// With optional config
await client.deleteThread('thread-123', { user_id: 'u-456' });

Parameters:

Parameter Type Description
threadId string | number The thread ID to delete.
config Record<string, any> Optional configuration passed with the delete request body.

Thread state

threadState(threadId)

Fetch the current state snapshot for a thread (the full graph state at the last checkpoint).

TypeScript
const response = await client.threadState(12345);
console.log(response.data);
// { state: { messages: [...], user_id: 'abc', ... } }

Parameters:

Parameter Type Description
threadId number The thread ID. See the note below: the TypeScript signature says number, but the server accepts strings and real thread ids usually are strings.

updateThreadState(threadId, config, state)

Write a new state snapshot for a thread. Use this to seed initial state, repair a corrupted thread, or inject values that the graph needs but cannot derive from messages alone.

TypeScript
await client.updateThreadState(
  12345,
  {},                          // config body (the server derives it from the path thread_id)
  { user_preferences: { lang: 'fr' } }  // new state
);

Parameters:

Parameter Type Description
threadId number The thread ID. Typed number; see the note below.
config Record<string, any> Config body. The server rebuilds the config from the path thread_id and ignores what you send here, so {} is fine.
state any New state object to write. Keys must match the graph’s state schema.

clearThreadState(threadId)

Delete all checkpointed state for a thread. The thread itself (its metadata and messages) is not deleted — only the state snapshot is cleared.

TypeScript
await client.clearThreadState(12345);

Parameters:

Parameter Type Description
threadId number The thread ID.

Messages

threadMessages(threadId, request?)

List messages for a thread with optional search and pagination.

TypeScript
// All messages
const response = await client.threadMessages('thread-123');

// With search term
const response = await client.threadMessages('thread-123', 'capital');

// As a request object
const response = await client.threadMessages('thread-123', {
  search: 'capital',
  offset: 0,
  limit: 50,
});

Overloads:

TypeScript
client.threadMessages(threadId: string | number): Promise<ThreadMessagesResponse>
client.threadMessages(threadId: string | number, request: ThreadMessagesRequest): Promise<ThreadMessagesResponse>
client.threadMessages(threadId: string | number, search?: string, offset?: number, limit?: number): Promise<ThreadMessagesResponse>

ThreadMessagesRequest (without threadId):

Field Type Description
search string Substring filter applied to message content.
offset number Number of messages to skip (≥ 0).
limit number Maximum number to return (> 0).

ThreadMessagesResponse:

TypeScript
interface ThreadMessagesResponse {
  data: {
    messages: Message[];
    total?: number;
  };
  metadata: ResponseMetadata;
}

addThreadMessages(threadId, messages, config?, metadata?)

Append messages to a thread’s saved history. Useful for injecting context, system prompts, or synthetic messages without running the graph.

TypeScript
await client.addThreadMessages(
  'thread-123',
  [Message.text_message('You are a travel guide.', 'system')],
  {},                         // config body (the server derives it from the path thread_id)
  { injected_by: 'setup' }    // metadata
);

Parameters:

Parameter Type Default Description
threadId string | number — The thread ID.
messages Message[] — Messages to append.
config Record<string, any> {} Config body. The server rebuilds the config from the path thread_id, so this is effectively ignored.
metadata Record<string, any> undefined Optional metadata attached to the checkpoint.

singleMessage(threadId, messageId)

Fetch a single message from a thread by message ID.

TypeScript
const response = await client.singleMessage('thread-123', 'msg-001');
console.log(response.data.message);

Parameters:

Parameter Type Description
threadId string | number The thread ID.
messageId string The message ID. Must be non-empty.

deleteMessage(threadId, messageId, config?)

Delete a single message from a thread by message ID.

TypeScript
await client.deleteMessage('thread-123', 'msg-001');

Parameters:

Parameter Type Description
threadId string | number The thread ID.
messageId string The message ID to delete. Must be non-empty.
config Record<string, any> Optional configuration passed in the request body.

Validation rules

These rules are enforced by the server and will produce AgentFlowError status 422 if violated:

Rule Description
thread_id non-empty String thread IDs must not be empty or whitespace. Integer IDs must be ≥ 1.
message_id non-empty messageId must not be empty.
offset ≥ 0 Pagination offset must be a non-negative number.
limit > 0 Pagination limit must be a positive number.

Common patterns

Paginate through all threads

TypeScript
async function* allThreads(pageSize = 50) {
  let offset = 0;
  while (true) {
    const response = await client.threads({ offset, limit: pageSize });
    const threads = response.data.threads;
    if (threads.length === 0) break;
    yield* threads;
    offset += threads.length;
    if (threads.length < pageSize) break;
  }
}

for await (const thread of allThreads()) {
  console.log(thread.thread_id, thread.thread_name);
}

Display a conversation history

TypeScript
const response = await client.threadMessages('thread-123', {
  offset: 0,
  limit: 100,
});

for (const msg of response.data.messages) {
  const text = msg.content
    .filter(b => b.type === 'text')
    .map(b => (b as any).text)
    .join('');
  console.log(`[${msg.role}] ${text}`);
}

Reset a thread

TypeScript
// Keep the thread metadata but wipe the state
await client.clearThreadState(12345);

// Or delete everything including metadata and messages
await client.deleteThread('thread-123');


Common errors

Error Cause Fix
AgentFlowError status 404 Thread not found, or no checkpointer configured. Verify thread_id, and confirm the graph is compiled with a checkpointer.
TypeScript error passing a string id to threadState / updateThreadState / clearThreadState Those three are typed threadId: number. Cast at the call site; the server accepts strings. See the caution above.
AgentFlowError status 422 Validation failure — invalid thread_id, empty message_id, bad pagination values. Check the field constraints listed in Validation rules.

What you learned

  • Threads persist conversation history and state between invoke() calls when config.thread_id is set.
  • threadMessages() supports search and pagination.
  • clearThreadState() removes the state snapshot but not the thread or messages.
  • All thread operations require the graph to be compiled with a checkpointer.
  • threadState, updateThreadState, and clearThreadState are typed threadId: number while their siblings accept string | number; the server accepts both.

Next step

See reference/client/memory to learn how to store and search long-term memories beyond per-thread conversation history.

Last updated for v0.9.2Edit this page on GitHubReport an issue