Use the API

Runs and retries

Find out what happened, recover a result, or stop work without submitting it twice.

A request timed out, or the connection closed before the answer arrived. Start by checking the work Fluso already accepted.

Use the Bash shell from your first request. It contains the api helper and saved IDs.

Check the run

api "/threads/$thread_id/runs/$run_id" | jq '{status, error}'
StatusYour next step
queued or runningWait, then check again.
waiting_actionRead thread state and handle the pending action.
heldReview the queue in thread state before resuming an input.
completedRead every result page.
failed or cancelledRead the error and partial results before deciding what to do next.

A completed run can contain a failed tool call. A failed run can still have changed an external service. Check the answer and tool results before repeating work.

Recover after a timeout

What you haveWhat to do
A receipt with thread_id and run_idRead that run and its saved output.
A saved key and body, but no receiptRepeat the original submission with both unchanged.
A disconnected streamReconnect for new events, then read saved state and items.

For a lost follow-up response, resend the saved request:

receipt=$(api "/threads/$thread_id/inputs" \
  -H "Idempotency-Key: $input_key" \
  -H 'Content-Type: application/json' -d "$input_body") &&
run_id=$(printf '%s' "$receipt" | jq -er '.run_id')

Do not generate another key for this retry. A new key can start duplicate work. For the quickstart's initial submission, retry /threads instead of /threads/$thread_id/inputs.

Input receipts remain until 24 hours after completion. After that, inspect the saved run before submitting again. Saved runs remain readable until their conversation is deleted.

Thread created, but the first input failed

An error from POST /v1/threads can include error.details.thread_id. Keep that ID and inspect its state. Thread creation alone does not prove that Fluso accepted the input.

After resolving the error, send the original input and key to that thread's /inputs endpoint. This can recover an uncertain acceptance within the retry window.

Stop work

To cancel only the saved run:

api "/threads/$thread_id/runs/$run_id/cancel" -X POST

Then check its status until execution stops. Cancellation cannot undo an external action that already completed.

To stop the conversation and hold its follow-up messages, use POST /v1/threads/{thread_id}/stop instead. Review the queue before resuming held inputs.

Decide whether to retry

For temporary read failures, wait before retrying. Increase the delay between attempts, set a maximum wait, and honor Retry-After. Stop when error.retryable is explicitly false. The quickstart's read helpers already do this.

For writes, use the operation's own recovery rule. Inputs use saved keys and bodies. Uploads use their receipts. Schedules use their IDs. Configuration edits use revisions.

A failed run stays failed when you resend its old key. Review partial results before choosing a new message and key.

Errors and request identity
ResponseAction
400 or 422Correct the request fields.
401Replace the credential or sign in again.
402Check the account allowance and any resets_at value.
403Use the required access level or signed-in app session.
404Check the workspace and resource ID. The resource may no longer exist.
409Read the resource before resolving the conflict. Keep unsent edits.
410Follow the error's instructions for the expired resource or approval.
413 or 507Reduce the transfer or free workspace storage.
408, 429, 500, 502, 503, or 504Retry transient reads with a delay. Preserve keys for uncertain writes.

Errors include error.code and error.message, with details and retry guidance where available. Keep request_id or X-Request-ID for support. A request ID is not an idempotency key.

Use UUIDs for new input keys. Accepted characters are ASCII letters, digits, _, -, ., :, and @, with a maximum of 128 characters. A single dot, consecutive dots, and the agent-turn: and agent-result: prefixes are reserved.

For historical run IDs containing /, use GET /v1/runs with URL-encoded thread_id and run_id query parameters. Read output through the items endpoint's run_id filter.

Run endpoints and admission limits
Method and pathUse
GET /v1/runsList saved runs or find one through query filters.
GET /v1/threads/{thread_id}/runsList a conversation's runs. Follow next_cursor as after.
GET /v1/threads/{thread_id}/runs/{run_id}Read status, error, and recorded execution settings.
GET /v1/threads/{thread_id}/runs/{run_id}/usageRead recorded usage or null when unreported.
POST /v1/threads/{thread_id}/runs/{run_id}/cancelRequest cancellation of this run.
POST /v1/threads/{thread_id}/stopStop active work and hold follow-ups.

An input accepts up to 200,000 text characters and 25 attachments. A thread holds up to 100 queued inputs and 50 steering inputs per active turn.

Each thread retains up to 1,000 recent input receipts. At capacity, admission refuses new work while preserving existing retry receipts. Waiting for a local timeout does not clear accepted work.

Merge state.runs by ID when reading multiple item pages. An old item without a saved run has an unknown outcome. Its text alone does not prove success.

On this page