Threads API
Create a thread
Start a thread on one of your connections and send its first message.
/api/v1/tasksStarts 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)requiredA fresh UUID you generate. Reuse it with an identical body to retry safely.
projectIdstring (UUID)requiredAn existing project, or a fresh UUID together with
newProjectNameto create an empty one.titlestring, 1–200 charactersrequiredThe thread title shown in the sidebar.
messageIdstring, 1–200 charactersrequiredA fresh identifier for the first message, such as a UUID.
messagestring, up to 200,000 charactersrequiredWhat you want the agent to do. It cannot be blank.
executionobjectrequiredWhich harness, connection and model run the thread. Credentials are never chosen for you.
execution.idstring, letters, digits, - and _requiredYour name for this execution, such as
build. Later sends must carry it.execution.rolestring, 1–100 charactersrequiredA short label for the execution, such as
Build.execution.connectionIdstring (UUID)requiredOne of your connections.
statefold connectionslists them.execution.harness"codex" | "claude-code" | "opencode" | "pi" | "gemini"requiredThe coding agent. It must match the connection.
execution.modelstringrequiredA model that connection offers.
execution.reasoningstringoptionalA reasoning level the model offers. Checked when the thread is admitted.
execution.skillIdsstring (UUID)[], up to 20optionalSkills from your library to make available to the agent.
newProjectNamestring, 1–200 characterssometimes requiredRequired to start in a new empty project; omit
sourcethen. A project id already used for another project is a conflict.automaticProjectNamebooleanoptionalWith
newProjectName: treat the name as a placeholder that the thread replaces once. Only applies whenprojectIdequalstaskId.sourceobjectsometimes requiredRequired for an existing project instead of
newProjectName: its confirmed workspace snapshot, exactly as the CLI recorded it.source.repositorystringsometimes requiredThe project's snapshot repository.
source.refstring (refs/statefold/snapshots/<commit>)sometimes requiredThe confirmed snapshot ref.
source.commitstring (40-character commit SHA)sometimes requiredThe 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
version1requiredPayload version.
taskobjectrequiredThe thread's metadata, the same shape as Get a thread.
Errors
Errors are JSON: { "version": 1, "error": { "code", "message" } }. See Errors for retry advice.
- 400
invalid_request The body is invalid, the connection cannot run the model, or the connection is unusable or out of quota.
- 401
unauthorized The bearer token is missing, invalid or revoked.
- 403
forbidden The token does not have the
tasks:createscope, or the account is suspended.- 402
forbidden Billing is not set up or the account is out of credits.
- 404
not_found The project or the connection is not yours.
- 409
conflict The
taskIdwas used with a different body (this answer has a plain-text body), the project id belongs to another project, orsourceis not the project's confirmed snapshot.- 413
invalid_request The body is larger than 256 KiB.
- 503
unavailable A dependency was unavailable. Retry with the same body.