error result kind; run() never throws for them. On the blocking route the SDK retries a retryable failure once before resolving; streamed turns resolve without a retry. Schedule any second attempt for later and honour retryAfterMs when it is set.
Structured data methods throw FinancialDataError instead. Their job limits,
resumable timeouts, and partial-result behavior are covered in the
financial-data guide.
Lifetimes
status() reports health: "expiring_soon" from 14 days out on either 90-day clock.
A connection nobody uses is swept after 30 days, whether or not the 90-day clock has run. Any call resets it, so an app a customer actually uses never hits it. One a customer connected and forgot does.
Rate limits
The budgets are deploy configuration, so no figures here. The keying is the contract:
Per grant is the one to pace: each customer budgets separately, so the traffic that hits it is yours, and one customer can never starve another. A 429 surfaces as
rate_limited.
Error codes
result.code is a closed set.
deployment_paused and deployment_incomplete never succeed on retry. Alert yourself rather than asking the customer to fix them mid-conversation.
agent_busy is the one retryable code that is not a failure. A customer’s agent runs one turn at a time per conversation, so a turn sent while the previous one is still running is turned away rather than queued. Send the same call again after a moment; do not tell the customer something broke.
The hosted MCP server has a twin of it, run_in_progress, which means exactly the same thing about a run it is already holding. Neither charges anything and neither ran.
Two more statuses are not errors at all and never reach this table: needs_provider and no_capable_provider arrive as ok results. See the Wallet.

