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}'| Status | Your next step |
|---|---|
queued or running | Wait, then check again. |
waiting_action | Read thread state and handle the pending action. |
held | Review the queue in thread state before resuming an input. |
completed | Read every result page. |
failed or cancelled | Read 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 have | What to do |
|---|---|
A receipt with thread_id and run_id | Read that run and its saved output. |
| A saved key and body, but no receipt | Repeat the original submission with both unchanged. |
| A disconnected stream | Reconnect 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 POSTThen 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
| Response | Action |
|---|---|
| 400 or 422 | Correct the request fields. |
| 401 | Replace the credential or sign in again. |
| 402 | Check the account allowance and any resets_at value. |
| 403 | Use the required access level or signed-in app session. |
| 404 | Check the workspace and resource ID. The resource may no longer exist. |
| 409 | Read the resource before resolving the conflict. Keep unsent edits. |
| 410 | Follow the error's instructions for the expired resource or approval. |
| 413 or 507 | Reduce the transfer or free workspace storage. |
| 408, 429, 500, 502, 503, or 504 | Retry 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 path | Use |
|---|---|
GET /v1/runs | List saved runs or find one through query filters. |
GET /v1/threads/{thread_id}/runs | List 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}/usage | Read recorded usage or null when unreported. |
POST /v1/threads/{thread_id}/runs/{run_id}/cancel | Request cancellation of this run. |
POST /v1/threads/{thread_id}/stop | Stop 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.