ApiError with its HTTP status, code, cause and receipts, plus requestId whenever a request was sent. Arguments rejected before sending throw code: "BAD_REQUEST" with a message naming the method and no requestId, so treat requestId as optional and branch on code. Every failure propagates, and missing live data never becomes a default. Missing memory returns null.
Money submissions throw MoneyActionError, an ApiError whose outcome.status says whether anything can still happen: rejected means the request was refused before an operation existed; failed carries the finished operation, whose effects agent.allocation already includes; unresolved carries the operationId of an operation that is pending, whose response was lost, or whose settlement Circuit is still proving (status unproven, error.code OPERATION_UNPROVEN, operation attached). After rejected or failed, decide again from the current allocation; after unresolved, do not act on that intent again until the operation leaves operations.pending(). completedOperations retains successful prerequisites. error.moneyFailure is { stage: "preparation", operationId: null } for rejected, where nothing exists to follow, and otherwise { stage: "execution", operationId }: follow outcome.status and never resubmit within the run.
A money create, cancel or redeem method’s optional second argument { once, per? } names the decision it carries out, such as { once: "buy", per: "week" }; per (hour, day or week, UTC periods Circuit’s clock decides) scopes the name to the current period. Circuit holds at most one successful operation per name in a session: a later write with a succeeded name, in any run, returns that operation without preparing again; while an operation holding the name is pending, the write throws MoneyActionError with outcome unresolved and that operationId; a failed operation frees the name, so the next write decides again. The name labels only the requested operation, never an approval or funding prerequisite. operations.retrieve({ operationId }) is the authority on an operation: pending means observe, success retains its recorded result, and error retains failure evidence.
operations.cancel({ operationId }) withdraws one of the session’s pending operations while nothing irreversible has happened. An operation still waiting to start ends at once; a submitted one ends when its venue confirms the withdrawal, as Papertrade does for an intent still in its queue. It returns the operation: error with code CANCELED, or the outcome it reached first. It throws when the operation is already broadcast on chain or its venue is already executing it; that operation settles on its own. The write still awaiting a canceled operation throws MoneyActionError with code CANCELED; find the ID to cancel in operations.pending().
operations.pending() returns every one of the current session’s pending operations, including those still settling past their settlement bound (unproven) and admissions whose response was lost; operations.list() pages through all outcomes. Each row is the same operation resource returned by retrieve, plus sessionId and walletId. Unreadable details appear in readError; recorded facts and neighboring entries remain available. Unavailable settlement evidence and missing admission timestamps stay null. Historical kind and status are strings; request, error and result are unknown recorded data, while action is the admitted money action from request, or null when it no longer parses. Receipt networks and reference kinds are recorded strings, including retired values. Narrow fields before using them; never replay a historical action. Fresh money method results remain typed by action kind. Follow list’s nextCursor or use for await to cover every page. Timestamps are UTC ISO-8601 instants with six fractional digits (2026-10-24T20:00:00.123456Z); receipts distinguish submission from observed settlement. Logs and memory references cannot override these resources.
VENUE_PAUSED means the venue refused the action because it is paused, such as Papertrade before it opens intake; nothing changed. OPEN_INTEREST_CAP means the venue refused an open because that side of the market is at its open-interest cap, such as Papertrade when longs are crowded; nothing changed. These two are the errors worth catching: check error.code, log that the venue refused and return, and the next trigger tries again. Uncaught, they fail the run. BELOW_MINIMUM means the action is below a rule the code can read before sizing: a market’s minimumNotional or minimumSize (data.markets, kraken.markets.list, derive.options.list, polymarket.markets.retrieve), Papertrade’s minimumStake, MINIMUM_SWAP_USD, or a swap whose route fees exceed its amount; the message names the rule and nothing changed; size the action at or above it. ACCOUNT_SETUP_REQUIRED and ACCOUNT_FUNDING_REQUIRED carry the exact requirement in error.details.detail.requirement. Account readiness says who completes setup; ACCOUNT_FUNDING_REQUIRED means the venue account does not exist or has no deposit yet, and its first deposit opens it. Failed state reads remain errors rather than setup instructions. LIFECYCLE_TIMEOUT means the deadline passed before Circuit submitted anything; nothing changed, and the outcome is final. When a provider read was still unanswered at that deadline, the code is PROVIDER_UNAVAILABLE and the message names the provider’s host; nothing changed either. An unproven operation passed its settlement bound without evidence; Circuit keeps observing it, later evidence settles it as success or error, the SDK reports it as unresolved with code OPERATION_UNPROVEN, and it stays in operations.pending() until then (execution model).
A hosted run that ends on an uncaught error is your agent’s failure, recorded as AGENT_FAILED with the error’s message, because your code controls everything its sandbox reports. Circuit owns a run’s failure only when Circuit saw it fail on its side, such as a lost runtime host. circuit run reports the first known code in the error’s cause chain.