Defaults
Unary requests
A unary call (complete, images, code, documents, job, list endpoints, …) is bounded by timeoutMs end-to-end. If it elapses, the SDK aborts the request and throws a TheoTimeoutError (error.kind === "timeout", error.timeoutMs carries the budget).
Streaming requests
stream() is not capped by a total-duration timeout — a long but healthy stream can run for minutes. Instead:
timeoutMsguards the connection / first byte. If headers never arrive, you get aTheoTimeoutError(“Stream did not start…”).streamIdleTimeoutMsguards the gap between chunks. The timer resets on every chunk; if the stream goes silent for longer than the window, the SDK aborts it and the async iterator throws aTheoTimeoutError.
TheoStream.cancel() is different from a timeout. Cancelling ends the iterator cleanly (no throw); a timeout throws TheoTimeoutError.Retry policy
The SDK retries automatically on:- 429 — rate limited (honors
Retry-Afterup to 60s) - 5xx — server errors (exponential backoff: 1s, 2s, 4s, capped at 8s)
It does not retry
4xx(other than429).
Timeouts are not retried on writes
If you need at-most-once semantics across your own retries, send anIdempotency-Key header (supported platform-wide) so a replay reuses the original result instead of generating again.
Per-mode guidance
fast/auto: the 30s default is plenty.think/code: can run longer — raisetimeoutMs(e.g. 60–120s) for big prompts.research/video: do not send these tocomplete()/stream(). They are asynchronous and run as jobs — usetheo.research()/theo.video()+theo.waitForJob(). The SDK throws aTheoUsageErrorimmediately if you try. See Async Jobs.
Errors
All of the above surface through the SDK error hierarchy. See Error Handling forTheoTimeoutError, TheoCancelledError, TheoUsageError, and the kind discriminator.