Retry without a second generation

Use an idempotency key for a logical request and honor public retry headers.

Set BASE_URL to your HTTPS API origin without a trailing slash or /v1, and pass API_KEY from your credential store. OpenAI-compatible SDKs use ${BASE_URL}/v1; Anthropic-compatible SDKs use BASE_URL.

Send Idempotency-Key when your application may retry an inference call after a timeout or connection loss. Generate one fresh, unpredictable value per new logical request and store it alongside the exact request parameters. Reuse the same value and parameters for every retry of that request. Within 24 hours, a completed duplicate returns its terminal result without another generation or charge. A new user request needs a new key, even if its prompt happens to match.

Send and retain one logical request

Make sure API_KEY is available to the process. In a shell with OpenSSL, generate one random key; in an application, use your cryptographically secure UUID generator or equivalent. Keep the idempotency value and body in application state until the call has a terminal outcome. Do not put an API key or prompt inside the idempotency value.

bash
export UNLIMGPT_REQUEST_KEY="$(openssl rand -hex 16)"

Send the request from the same shell. If key generation failed, the check stops the request before paid work:

bash
test -n "${UNLIMGPT_REQUEST_KEY:-}" \
  && printf 'Authorization: Bearer %s\n' "$API_KEY" \
  | curl -q -H @- -i "$BASE_URL/v1/responses" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $UNLIMGPT_REQUEST_KEY" \
    -d '{
  "model": "gpt-5.6-sol",
  "input": "Say hello.",
  "max_output_tokens": 64,
  "stream": false
}'

Expect a terminal JSON response on success. Save the HTTP request-id for diagnostics; it is different from a run ID in API Activity. For a retry, run only the second block with the same variable and unchanged body. Rerunning the OpenSSL command creates a new key and may start a second paid generation.

Decide whether to retry

  • A duplicate while its first execution is active returns temporary HTTP 409 with retry-after: 1 and x-should-retry: true. Wait at least the advised time, then send the unchanged request with the same key.
  • The same key with changed parameters returns a permanent 409 and x-should-retry: false. Treat it as an application bug; choose a new key only for a genuinely new logical request.
  • For HTTP 429, read retry-after and x-should-retry. A transient rate limit may be retried after its delay; a package usage limit needs its reset or a plan change. Do not loop on x-should-retry: false.
  • For a broken stream, inspect Activity and the last native event before deciding what happened. A stream may carry its failure after HTTP 200; use the same key for a safe retry when the client supports that behavior.

Bound your own retry count and total elapsed time. Do not automatically retry a non-retryable public error or change the request body while retaining its old key. See streaming, errors and limits, and Responses for the protocol context.