Skip to main content
This page has one complete client in three languages, ready to copy into a project. Each one sends a decision run the way the production checklist asks: with an idempotency key derived from your business id, a timeout above the run’s deadline, the retry policy from Error handling, error-envelope parsing, request-id logging, and code that reads every answer type.

What the clients do

Retries are bounded to five attempts with exponential backoff and jitter. The status and error.code decide every retry, as in the table above.

Setup

  • The shell client needs curl and jq.
  • The TypeScript client needs Node.js 18 or later, and runs with npx tsx opentype.ts.
  • The Python client needs Python 3.9 or later and pip install requests.

The client

For the shell client, save the request body to a file first:
body.json

What comes back

A completed run, as the clients receive it:
And what the TypeScript and Python clients print for it:
Each attempt also writes one JSON log line to standard error, for example:

Reading each answer type

A skipped answer looks like this:
See Decision runs for choosing thresholds, and Conditional questions for depends_on and ask_if.

Adapting the clients

  • Business ids. Use an id that is stable for one piece of work, such as a ticket id plus the task name. Reusing it for a different body gets 409 idempotency_conflict, which these clients do not retry.
  • Deadlines. Set deadline_ms in the body. The clients wait 10 seconds longer than it before timing out.
  • Credit. A 402 is raised to the caller. In a worker pool, pause every worker on the first 402, as shown in Handling insufficient credits.
  • Quota. A 429 is retried a few times with backoff. For long waits, read GET /v1/quota instead; see Spend limits and quotas.
  • Concurrency. Every run in flight holds up to 20,000 micros of credit and of the period’s spend quota. Limit the number of parallel calls to what your balance covers.