Skip to content
StatefoldDocsChangelogOpen app

Threads API

Create a thread

Start a thread on one of your connections and send its first message.

POST/api/v1/tasks

Starts a thread in an existing project or a new empty one and delivers its first message. You choose the identifiers, so a retry with the same taskId and an identical body returns the same thread instead of starting another; the same taskId with a different body is a conflict.

The response is admission, not a finished reply. Poll Get a thread and read statusSummary for progress.

Requires a personal API token with the tasks:create scope, sent as Authorization: Bearer over HTTPS.

Body

taskIdstring (UUID)required

A fresh UUID you generate. Reuse it with an identical body to retry safely.

projectIdstring (UUID)required

An existing project, or a fresh UUID together with newProjectName to create an empty one.

titlestring, 1–200 charactersrequired

The thread title shown in the sidebar.

messageIdstring, 1–200 charactersrequired

A fresh identifier for the first message, such as a UUID.

messagestring, up to 200,000 charactersrequired

What you want the agent to do. It cannot be blank.

executionobjectrequired

Which harness, connection and model run the thread. Credentials are never chosen for you.

execution.idstring, letters, digits, - and _required

Your name for this execution, such as build. Later sends must carry it.

execution.rolestring, 1–100 charactersrequired

A short label for the execution, such as Build.

execution.connectionIdstring (UUID)required

One of your connections. statefold connections lists them.

execution.harness"codex" | "claude-code" | "opencode" | "pi" | "gemini"required

The coding agent. It must match the connection.

execution.modelstringrequired

A model that connection offers.

execution.reasoningstringoptional

A reasoning level the model offers. Checked when the thread is admitted.

execution.skillIdsstring (UUID)[], up to 20optional

Skills from your library to make available to the agent.

newProjectNamestring, 1–200 characterssometimes required

Required to start in a new empty project; omit source then. A project id already used for another project is a conflict.

automaticProjectNamebooleanoptional

With newProjectName: treat the name as a placeholder that the thread replaces once. Only applies when projectId equals taskId.

sourceobjectsometimes required

Required for an existing project instead of newProjectName: its confirmed workspace snapshot, exactly as the CLI recorded it.

source.repositorystringsometimes required

The project's snapshot repository.

source.refstring (refs/statefold/snapshots/<commit>)sometimes required

The confirmed snapshot ref.

source.commitstring (40-character commit SHA)sometimes required

The commit that ref points at.

Returns

201 Created with version and the new thread's metadata in task. A retry of an admitted request returns the same thread.

Response fields

version1required

Payload version.

taskobjectrequired

The thread's metadata, the same shape as Get a thread.

Errors

Errors are JSON: { "version": 1, "error": { "code", "message" } }. See Errors for retry advice.

400invalid_request

The body is invalid, the connection cannot run the model, or the connection is unusable or out of quota.

401unauthorized

The bearer token is missing, invalid or revoked.

403forbidden

The token does not have the tasks:create scope, or the account is suspended.

402forbidden

Billing is not set up or the account is out of credits.

404not_found

The project or the connection is not yours.

409conflict

The taskId was used with a different body (this answer has a plain-text body), the project id belongs to another project, or source is not the project's confirmed snapshot.

413invalid_request

The body is larger than 256 KiB.

503unavailable

A dependency was unavailable. Retry with the same body.