{"ok":true,"version":"2026-08-09","confirmation":{"header":"x-confirmation-token","flow":"Side-effecting tools: call unconfirmed -> 428 with error.preview + error.confirmationToken -> resend the identical body with the token. Tokens are single-use, expire in 10 minutes and are bound to the exact arguments previewed."},"docs":"https://3bi.ai/docs","openapi":"https://3bi.ai/api/public/v1/openapi.json","auth":{"type":"bearer","header":"Authorization: Bearer sk_agent_...","alternateHeader":"x-api-key: sk_agent_... (fallback when Authorization cannot be set)","signup":"https://3bi.ai/api/public/v1/signup","signupMethod":"POST","humanSignup":"https://3bi.ai/auth"},"pricing":{"unit":"credit","currency":"USD","usdPerCredit":0.009,"freeGrant":500,"packs":[{"priceId":"credits_1k","label":"Starter","credits":1000,"usd":9,"usdPerCredit":0.009},{"priceId":"credits_5k","label":"Builder","credits":5000,"usd":39,"usdPerCredit":0.0078},{"priceId":"credits_25k","label":"Scale","credits":25000,"usd":149,"usdPerCredit":0.00596}],"pricingUrl":"https://3bi.ai/api/public/v1/pricing","purchase":{"machine":{"url":"https://3bi.ai/api/public/v1/credits/purchase","method":"POST","protocol":"x402","asset":"USDC","networks":["base"]},"human":{"url":"https://3bi.ai/pricing"}}},"tools":[{"confirmation":{"required":false},"name":"fetch_url","label":"Fetch URL","description":"Fetch a public web page or JSON endpoint over HTTPS and return its readable text content plus metadata. Real network call, not a simulation. Read-only.","sideEffecting":false,"demo":false,"credits":2,"usdPerCall":0.02,"invokeUrl":"https://3bi.ai/api/public/v1/tools/fetch_url","inputSchema":{"type":"object","properties":{"url":{"type":"string","description":"Absolute https:// URL to fetch"},"maxChars":{"type":"number","description":"Truncate the extracted text to this many characters (default 8000, max 50000)"}},"required":["url"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/fetch_url","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"url":"https://example.com"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"fetch_url","demo":false,"credits":{"charged":2,"balance":498},"result":{"ok":true,"url":"https://example.com/","status":200,"contentType":"text/html","title":"Example Domain","text":"Example Domain. This domain is for use in illustrative examples in documents...","chars":208,"truncated":false,"fetchedAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":false},"name":"crawl_site","label":"Crawl site","description":"Crawl a public site starting from one https:// URL and return readable text for that page plus up to nine same-origin pages it links to. Real network calls. Read-only.","sideEffecting":false,"demo":false,"credits":6,"usdPerCall":0.06,"invokeUrl":"https://3bi.ai/api/public/v1/tools/crawl_site","inputSchema":{"type":"object","properties":{"url":{"type":"string","description":"Absolute https:// seed URL"},"maxPages":{"type":"number","description":"Total pages to fetch, 1-10. Defaults to 3"},"maxCharsPerPage":{"type":"number","description":"Truncate each page's text to this many characters (default 4000, max 20000)"}},"required":["url"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/crawl_site","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"url":"https://example.com","maxPages":3}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"crawl_site","demo":false,"credits":{"charged":6,"balance":494},"result":{"ok":true,"seed":"https://example.com","pageCount":2,"pages":[{"url":"https://example.com/","status":200,"title":"Example Domain","text":"Example Domain. This domain is for use in illustrative examples...","chars":208}],"crawledAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":false},"name":"extract_structured","label":"Extract structured data","description":"Extract named fields as JSON from a public URL or supplied text, using a server-side model. Returns one value per requested field, or null when absent. Read-only.","sideEffecting":false,"demo":false,"credits":8,"usdPerCall":0.08,"invokeUrl":"https://3bi.ai/api/public/v1/tools/extract_structured","inputSchema":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string"},"description":"Field names to extract, e.g. [\"companyName\", \"pricingModel\"]"},"url":{"type":"string","description":"Absolute https:// URL to read. Required unless text is given"},"text":{"type":"string","description":"Raw text to extract from instead of fetching a URL"},"instruction":{"type":"string","description":"Optional extra guidance for the extraction"}},"required":["fields"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/extract_structured","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"url":"https://example.com","fields":["title","purpose"]}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"extract_structured","demo":false,"credits":{"charged":8,"balance":492},"result":{"ok":true,"sourceUrl":"https://example.com/","fields":{"title":"Example Domain","purpose":"Illustrative examples in documents"},"missing":[],"extractedAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":false},"name":"search_web","label":"Search web","description":"Search the public web and return ranked results with titles, snippets, and source URLs. Uses a server-side search API. Read-only.","sideEffecting":false,"demo":false,"credits":4,"usdPerCall":0.04,"invokeUrl":"https://3bi.ai/api/public/v1/tools/search_web","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Natural language search query"},"maxResults":{"type":"number","description":"Number of results to return, 1-20. Defaults to 5"},"includeAnswer":{"type":"boolean","description":"Include a short AI-generated answer based on the results. Defaults to false"}},"required":["query"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/search_web","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"query":"x402 payment protocol summary"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"search_web","demo":false,"credits":{"charged":4,"balance":496},"result":{"ok":true,"query":"x402 payment protocol summary","results":[{"title":"x402 - Machine-payable HTTP","url":"https://x402.org","content":"x402 is a protocol for machine payments over HTTP using stablecoins...","score":0.94}],"answer":"x402 lets servers request on-chain payment by returning HTTP 402.","searchedAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":false},"name":"search_knowledge_base","label":"Search knowledge base","description":"Search this workspace's uploaded documents using semantic similarity. Returns the most relevant text chunks with document titles and source URLs. Read-only.","sideEffecting":false,"demo":false,"credits":3,"usdPerCall":0.03,"invokeUrl":"https://3bi.ai/api/public/v1/tools/search_knowledge_base","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Natural language search query"},"maxResults":{"type":"number","description":"Number of chunks to return, 1-20. Defaults to 5"},"documentIds":{"type":"array","items":{"type":"string"},"description":"Optional list of document IDs to restrict the search to"}},"required":["query"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/search_knowledge_base","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"query":"refund policy"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"search_knowledge_base","demo":false,"credits":{"charged":3,"balance":497},"result":{"ok":true,"matches":[{"documentId":"doc_...","chunkIndex":0,"title":"Refund policy","sourceUrl":null,"content":"Refunds are issued within 14 days of purchase for annual plans...","similarity":0.91}]}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":true,"header":"x-confirmation-token","steps":[{"step":1,"description":"Call with no confirmation header. The response is 428 confirmation_required and carries error.preview plus error.confirmationToken.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/execute_code","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"code":"print('hello')","language":"python"}},"response":{"status":428,"body":{"ok":false,"error":{"code":"confirmation_required","message":"This tool has side effects. Show the preview to your operator, then retry the identical request with header 'x-confirmation-token: <confirmationToken>'.","tool":"execute_code","credits":8,"preview":{"summary":"python snippet","args":{"code":"print('hello')","language":"python"}},"confirmationToken":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60","expiresAt":"2026-08-09T20:25:18.358Z"}}}},{"step":2,"description":"After a human approves the preview, repeat the identical body with the token. The token is single-use and bound to these arguments — changing the body returns 409 confirmation_mismatch.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/execute_code","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>","x-confirmation-token":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60"},"body":{"code":"print('hello')","language":"python"}},"response":{"status":200,"body":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"execute_code","demo":false,"credits":{"charged":8,"balance":492},"result":{"ok":true,"language":"python","stdout":"hello\n","stderr":"","exitCode":0,"executedAt":"2026-08-09T20:15:18.358Z"}}}}]},"name":"execute_code","label":"Execute code","description":"Run Python or JavaScript code in a sandboxed E2B environment and return stdout, stderr, and the exit code. Files are ephemeral, but code can make external network requests with side effects. Requires the configured side-effect confirmation flow.","sideEffecting":true,"demo":false,"credits":8,"usdPerCall":0.08,"invokeUrl":"https://3bi.ai/api/public/v1/tools/execute_code","inputSchema":{"type":"object","properties":{"code":{"type":"string","description":"Python or JavaScript code to execute"},"language":{"type":"string","enum":["python","javascript"],"description":"Language. Defaults to python"},"timeout":{"type":"number","description":"Timeout in seconds, 1-300. Defaults to 60"}},"required":["code"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/execute_code","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"code":"print('hello')","language":"python"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"execute_code","demo":false,"credits":{"charged":8,"balance":492},"result":{"ok":true,"language":"python","stdout":"hello\n","stderr":"","exitCode":0,"executedAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":428,"code":"confirmation_required","cause":"A side-effecting tool was called without a confirmation token. Nothing was executed or charged.","action":"Show error.preview to your operator. Once they approve, repeat the identical request with header x-confirmation-token: <error.confirmationToken>."},{"status":403,"code":"confirmation_invalid","cause":"The x-confirmation-token header is unknown or belongs to another workspace.","action":"Call the tool without a token to receive a fresh preview and token, then retry."},{"status":409,"code":"confirmation_mismatch","cause":"The token is bound to a specific tool and argument set; this request differs from what was previewed.","action":"Send the exact body that was previewed, or request a new confirmation for the new body."},{"status":409,"code":"confirmation_used","cause":"That confirmation token was already redeemed. Tokens are single-use.","action":"Request a new confirmation for the next call."},{"status":410,"code":"confirmation_expired","cause":"The confirmation token passed its 10-minute validity window.","action":"Call again without a token to get a new preview and token."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":false},"name":"browse_page","label":"Browse page","description":"Open a URL in a remote Browserbase browser and return the rendered page as markdown text, including title, status code, and content type. Runs in Browserbase's cloud so it works from serverless runtimes.","sideEffecting":false,"demo":false,"credits":10,"usdPerCall":0.09,"invokeUrl":"https://3bi.ai/api/public/v1/tools/browse_page","inputSchema":{"type":"object","properties":{"url":{"type":"string","description":"URL to open and render"}},"required":["url"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/browse_page","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"url":"https://example.com"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"browse_page","demo":false,"credits":{"charged":10,"balance":490},"result":{"ok":true,"url":"https://example.com/","statusCode":200,"contentType":"text/markdown","title":"Example Domain","text":"Example Domain\n\nThis domain is for use in illustrative examples...","finishedAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":true,"header":"x-confirmation-token","steps":[{"step":1,"description":"Call with no confirmation header. The response is 428 confirmation_required and carries error.preview plus error.confirmationToken.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/gmail_send","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"to":"dana@northwind.io","subject":"Your invoice is ready","body":"Hi Dana — invoice in_881 is attached. Thanks!"}},"response":{"status":428,"body":{"ok":false,"error":{"code":"confirmation_required","message":"This tool has side effects. Show the preview to your operator, then retry the identical request with header 'x-confirmation-token: <confirmationToken>'.","tool":"gmail_send","credits":6,"preview":{"summary":"dana@northwind.io — Your invoice is ready","args":{"to":"dana@northwind.io","subject":"Your invoice is ready","body":"Hi Dana — invoice in_881 is attached. Thanks!"}},"confirmationToken":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60","expiresAt":"2026-08-09T20:25:18.358Z"}}}},{"step":2,"description":"After a human approves the preview, repeat the identical body with the token. The token is single-use and bound to these arguments — changing the body returns 409 confirmation_mismatch.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/gmail_send","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>","x-confirmation-token":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60"},"body":{"to":"dana@northwind.io","subject":"Your invoice is ready","body":"Hi Dana — invoice in_881 is attached. Thanks!"}},"response":{"status":200,"body":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"gmail_send","demo":false,"credits":{"charged":6,"balance":494},"result":{"ok":true,"messageId":"18f2a91cd4b5e607","to":"dana@northwind.io","threadId":"18f2a91cd4b5e607","sentAt":"2026-09-23T18:00:00.000Z"}}}}]},"name":"gmail_send","label":"Send Gmail","description":"Send an email through the workspace's connected Google account. Uses the managed OAuth connection — the agent never sees credentials. Requires the workspace to connect Google first (POST /api/public/v1/oauth/google/authorize). Side-effecting: requires confirmation.","sideEffecting":true,"demo":false,"credits":6,"usdPerCall":0.06,"invokeUrl":"https://3bi.ai/api/public/v1/tools/gmail_send","inputSchema":{"type":"object","properties":{"to":{"type":"string","description":"Recipient email address"},"subject":{"type":"string","description":"Email subject"},"body":{"type":"string","description":"Plain text email body"}},"required":["to","subject","body"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/gmail_send","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"to":"dana@northwind.io","subject":"Your invoice is ready","body":"Hi Dana — invoice in_881 is attached. Thanks!"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"gmail_send","demo":false,"credits":{"charged":6,"balance":494},"result":{"ok":true,"messageId":"18f2a91cd4b5e607","to":"dana@northwind.io","threadId":"18f2a91cd4b5e607","sentAt":"2026-09-23T18:00:00.000Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":428,"code":"confirmation_required","cause":"A side-effecting tool was called without a confirmation token. Nothing was executed or charged.","action":"Show error.preview to your operator. Once they approve, repeat the identical request with header x-confirmation-token: <error.confirmationToken>."},{"status":403,"code":"confirmation_invalid","cause":"The x-confirmation-token header is unknown or belongs to another workspace.","action":"Call the tool without a token to receive a fresh preview and token, then retry."},{"status":409,"code":"confirmation_mismatch","cause":"The token is bound to a specific tool and argument set; this request differs from what was previewed.","action":"Send the exact body that was previewed, or request a new confirmation for the new body."},{"status":409,"code":"confirmation_used","cause":"That confirmation token was already redeemed. Tokens are single-use.","action":"Request a new confirmation for the next call."},{"status":410,"code":"confirmation_expired","cause":"The confirmation token passed its 10-minute validity window.","action":"Call again without a token to get a new preview and token."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":true,"header":"x-confirmation-token","steps":[{"step":1,"description":"Call with no confirmation header. The response is 428 confirmation_required and carries error.preview plus error.confirmationToken.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/slack_post_message","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"channel":"#general","text":"Deploy finished :white_check_mark:"}},"response":{"status":428,"body":{"ok":false,"error":{"code":"confirmation_required","message":"This tool has side effects. Show the preview to your operator, then retry the identical request with header 'x-confirmation-token: <confirmationToken>'.","tool":"slack_post_message","credits":4,"preview":{"summary":"#general — Deploy finished :white_check_mark:","args":{"channel":"#general","text":"Deploy finished :white_check_mark:"}},"confirmationToken":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60","expiresAt":"2026-08-09T20:25:18.358Z"}}}},{"step":2,"description":"After a human approves the preview, repeat the identical body with the token. The token is single-use and bound to these arguments — changing the body returns 409 confirmation_mismatch.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/slack_post_message","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>","x-confirmation-token":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60"},"body":{"channel":"#general","text":"Deploy finished :white_check_mark:"}},"response":{"status":200,"body":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"slack_post_message","demo":false,"credits":{"charged":4,"balance":496},"result":{"ok":true,"channel":"C0123456789","ts":"1758650400.000100","messageId":"C0123456789:1758650400.000100","postedAt":"2026-09-23T18:00:00.000Z"}}}}]},"name":"slack_post_message","label":"Post Slack message","description":"Post a message to a Slack channel as the workspace's connected Slack identity. Uses the managed OAuth connection — the agent never sees credentials. Requires the workspace to connect Slack first (POST /api/public/v1/oauth/slack/authorize). Side-effecting: requires confirmation.","sideEffecting":true,"demo":false,"credits":4,"usdPerCall":0.04,"invokeUrl":"https://3bi.ai/api/public/v1/tools/slack_post_message","inputSchema":{"type":"object","properties":{"channel":{"type":"string","description":"Channel name (e.g. #general) or channel ID"},"text":{"type":"string","description":"Message text (Slack mrkdwn supported)"}},"required":["channel","text"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/slack_post_message","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"channel":"#general","text":"Deploy finished :white_check_mark:"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"slack_post_message","demo":false,"credits":{"charged":4,"balance":496},"result":{"ok":true,"channel":"C0123456789","ts":"1758650400.000100","messageId":"C0123456789:1758650400.000100","postedAt":"2026-09-23T18:00:00.000Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":428,"code":"confirmation_required","cause":"A side-effecting tool was called without a confirmation token. Nothing was executed or charged.","action":"Show error.preview to your operator. Once they approve, repeat the identical request with header x-confirmation-token: <error.confirmationToken>."},{"status":403,"code":"confirmation_invalid","cause":"The x-confirmation-token header is unknown or belongs to another workspace.","action":"Call the tool without a token to receive a fresh preview and token, then retry."},{"status":409,"code":"confirmation_mismatch","cause":"The token is bound to a specific tool and argument set; this request differs from what was previewed.","action":"Send the exact body that was previewed, or request a new confirmation for the new body."},{"status":409,"code":"confirmation_used","cause":"That confirmation token was already redeemed. Tokens are single-use.","action":"Request a new confirmation for the next call."},{"status":410,"code":"confirmation_expired","cause":"The confirmation token passed its 10-minute validity window.","action":"Call again without a token to get a new preview and token."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":true,"header":"x-confirmation-token","steps":[{"step":1,"description":"Call with no confirmation header. The response is 428 confirmation_required and carries error.preview plus error.confirmationToken.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/github_create_issue","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"owner":"octocat","repo":"hello-world","title":"Found a bug","body":"Steps to reproduce..."}},"response":{"status":428,"body":{"ok":false,"error":{"code":"confirmation_required","message":"This tool has side effects. Show the preview to your operator, then retry the identical request with header 'x-confirmation-token: <confirmationToken>'.","tool":"github_create_issue","credits":4,"preview":{"summary":"octocat/hello-world — Found a bug","args":{"owner":"octocat","repo":"hello-world","title":"Found a bug","body":"Steps to reproduce..."}},"confirmationToken":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60","expiresAt":"2026-08-09T20:25:18.358Z"}}}},{"step":2,"description":"After a human approves the preview, repeat the identical body with the token. The token is single-use and bound to these arguments — changing the body returns 409 confirmation_mismatch.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/github_create_issue","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>","x-confirmation-token":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60"},"body":{"owner":"octocat","repo":"hello-world","title":"Found a bug","body":"Steps to reproduce..."}},"response":{"status":200,"body":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"github_create_issue","demo":false,"credits":{"charged":4,"balance":496},"result":{"ok":true,"issueNumber":1347,"url":"https://github.com/octocat/hello-world/issues/1347","state":"open","createdAt":"2026-09-23T18:00:00.000Z"}}}}]},"name":"github_create_issue","label":"Create GitHub issue","description":"Create an issue in a GitHub repository as the workspace's connected GitHub identity. Uses the managed OAuth connection — the agent never sees credentials. Requires the workspace to connect GitHub first (POST /api/public/v1/oauth/github/authorize). Side-effecting: requires confirmation.","sideEffecting":true,"demo":false,"credits":4,"usdPerCall":0.04,"invokeUrl":"https://3bi.ai/api/public/v1/tools/github_create_issue","inputSchema":{"type":"object","properties":{"owner":{"type":"string","description":"Repository owner (user or organization)"},"repo":{"type":"string","description":"Repository name"},"title":{"type":"string","description":"Issue title"},"body":{"type":"string","description":"Issue body in markdown"}},"required":["owner","repo","title"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/github_create_issue","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"owner":"octocat","repo":"hello-world","title":"Found a bug","body":"Steps to reproduce..."}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"github_create_issue","demo":false,"credits":{"charged":4,"balance":496},"result":{"ok":true,"issueNumber":1347,"url":"https://github.com/octocat/hello-world/issues/1347","state":"open","createdAt":"2026-09-23T18:00:00.000Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":428,"code":"confirmation_required","cause":"A side-effecting tool was called without a confirmation token. Nothing was executed or charged.","action":"Show error.preview to your operator. Once they approve, repeat the identical request with header x-confirmation-token: <error.confirmationToken>."},{"status":403,"code":"confirmation_invalid","cause":"The x-confirmation-token header is unknown or belongs to another workspace.","action":"Call the tool without a token to receive a fresh preview and token, then retry."},{"status":409,"code":"confirmation_mismatch","cause":"The token is bound to a specific tool and argument set; this request differs from what was previewed.","action":"Send the exact body that was previewed, or request a new confirmation for the new body."},{"status":409,"code":"confirmation_used","cause":"That confirmation token was already redeemed. Tokens are single-use.","action":"Request a new confirmation for the next call."},{"status":410,"code":"confirmation_expired","cause":"The confirmation token passed its 10-minute validity window.","action":"Call again without a token to get a new preview and token."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":false},"name":"sandbox_search_knowledge_base","label":"Search knowledge base (sandbox)","description":"Sandbox: searches a fixed set of fixture documents and returns simulated matches. Free — use it to exercise the API, not for real knowledge.","sideEffecting":false,"demo":true,"credits":0,"usdPerCall":0,"invokeUrl":"https://3bi.ai/api/public/v1/tools/sandbox_search_knowledge_base","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Natural language search query"}},"required":["query"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_search_knowledge_base","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"query":"refund policy"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_search_knowledge_base","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"matches":[{"title":"Refund policy","body":"Refunds are issued within 14 days of purchase for annual plans, pro-rated after that."}]}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":false},"name":"sandbox_lookup_crm_contact","label":"Look up CRM contact (sandbox)","description":"Sandbox: returns a fixture CRM contact by email. Free — no real CRM is queried.","sideEffecting":false,"demo":true,"credits":0,"usdPerCall":0,"invokeUrl":"https://3bi.ai/api/public/v1/tools/sandbox_lookup_crm_contact","inputSchema":{"type":"object","properties":{"email":{"type":"string","description":"Contact email address"}},"required":["email"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_lookup_crm_contact","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"email":"dana@northwind.io"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_lookup_crm_contact","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"contact":{"id":"c_1024","name":"Dana Whitfield","email":"dana@northwind.io","company":"Northwind","stage":"customer","mrr":4200}}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":false},"name":"sandbox_list_records","label":"List records (sandbox)","description":"Sandbox: lists fixture records (contacts, invoices, tickets) with paging and filtering. Free — no real data.","sideEffecting":false,"demo":true,"credits":0,"usdPerCall":0,"invokeUrl":"https://3bi.ai/api/public/v1/tools/sandbox_list_records","inputSchema":{"type":"object","properties":{"type":{"type":"string","description":"Record type: contacts, invoices or tickets"},"status":{"type":"string","description":"Optional status filter; omit for all records"},"limit":{"type":"number","description":"Page size, 1-100. Defaults to 25"},"cursor":{"type":"string","description":"Opaque cursor from a previous nextCursor"}},"required":["type"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_list_records","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"type":"invoices","limit":25}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_list_records","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"type":"invoices","count":2,"rows":[{"id":"in_881","contact":"dana@northwind.io","amountCents":420000,"status":"paid"},{"id":"in_882","contact":"priya@fernbrook.co","amountCents":89000,"status":"open"}],"nextCursor":null}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":true,"header":"x-confirmation-token","steps":[{"step":1,"description":"Call with no confirmation header. The response is 428 confirmation_required and carries error.preview plus error.confirmationToken.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_send_email","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"to":"dana@northwind.io","subject":"Your invoice is ready","body":"Hi Dana — invoice in_881 is attached. Thanks!"}},"response":{"status":428,"body":{"ok":false,"error":{"code":"confirmation_required","message":"This tool has side effects. Show the preview to your operator, then retry the identical request with header 'x-confirmation-token: <confirmationToken>'.","tool":"sandbox_send_email","credits":0,"preview":{"summary":"dana@northwind.io — Your invoice is ready","args":{"to":"dana@northwind.io","subject":"Your invoice is ready","body":"Hi Dana — invoice in_881 is attached. Thanks!"}},"confirmationToken":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60","expiresAt":"2026-08-09T20:25:18.358Z"}}}},{"step":2,"description":"After a human approves the preview, repeat the identical body with the token. The token is single-use and bound to these arguments — changing the body returns 409 confirmation_mismatch.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_send_email","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>","x-confirmation-token":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60"},"body":{"to":"dana@northwind.io","subject":"Your invoice is ready","body":"Hi Dana — invoice in_881 is attached. Thanks!"}},"response":{"status":200,"body":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_send_email","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"simulated":true,"messageId":"sim_4f2a91cd","to":"dana@northwind.io","subject":"Your invoice is ready","deliveredAt":"2026-08-09T20:15:18.358Z"}}}}]},"name":"sandbox_send_email","label":"Send email (sandbox)","description":"Sandbox: simulates sending an email and returns a fake message id. Nothing is delivered. Free, and still side-effecting so you can exercise the confirmation flow.","sideEffecting":true,"demo":true,"credits":0,"usdPerCall":0,"invokeUrl":"https://3bi.ai/api/public/v1/tools/sandbox_send_email","inputSchema":{"type":"object","properties":{"to":{"type":"string","description":"Recipient email address"},"subject":{"type":"string","description":"Email subject"},"body":{"type":"string","description":"Plain text email body"}},"required":["to","subject","body"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_send_email","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"to":"dana@northwind.io","subject":"Your invoice is ready","body":"Hi Dana — invoice in_881 is attached. Thanks!"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_send_email","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"simulated":true,"messageId":"sim_4f2a91cd","to":"dana@northwind.io","subject":"Your invoice is ready","deliveredAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":428,"code":"confirmation_required","cause":"A side-effecting tool was called without a confirmation token. Nothing was executed or charged.","action":"Show error.preview to your operator. Once they approve, repeat the identical request with header x-confirmation-token: <error.confirmationToken>."},{"status":403,"code":"confirmation_invalid","cause":"The x-confirmation-token header is unknown or belongs to another workspace.","action":"Call the tool without a token to receive a fresh preview and token, then retry."},{"status":409,"code":"confirmation_mismatch","cause":"The token is bound to a specific tool and argument set; this request differs from what was previewed.","action":"Send the exact body that was previewed, or request a new confirmation for the new body."},{"status":409,"code":"confirmation_used","cause":"That confirmation token was already redeemed. Tokens are single-use.","action":"Request a new confirmation for the next call."},{"status":410,"code":"confirmation_expired","cause":"The confirmation token passed its 10-minute validity window.","action":"Call again without a token to get a new preview and token."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":true,"header":"x-confirmation-token","steps":[{"step":1,"description":"Call with no confirmation header. The response is 428 confirmation_required and carries error.preview plus error.confirmationToken.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_update_crm_record","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"recordId":"c_1024","fields":{"stage":"churn_risk","owner":"ae_12"}}},"response":{"status":428,"body":{"ok":false,"error":{"code":"confirmation_required","message":"This tool has side effects. Show the preview to your operator, then retry the identical request with header 'x-confirmation-token: <confirmationToken>'.","tool":"sandbox_update_crm_record","credits":0,"preview":{"summary":"c_1024","args":{"recordId":"c_1024","fields":{"stage":"churn_risk","owner":"ae_12"}}},"confirmationToken":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60","expiresAt":"2026-08-09T20:25:18.358Z"}}}},{"step":2,"description":"After a human approves the preview, repeat the identical body with the token. The token is single-use and bound to these arguments — changing the body returns 409 confirmation_mismatch.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_update_crm_record","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>","x-confirmation-token":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60"},"body":{"recordId":"c_1024","fields":{"stage":"churn_risk","owner":"ae_12"}}},"response":{"status":200,"body":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_update_crm_record","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"simulated":true,"recordId":"c_1024","updatedFields":{"stage":"churn_risk","owner":"ae_12"},"updatedAt":"2026-08-09T20:15:18.358Z"}}}}]},"name":"sandbox_update_crm_record","label":"Update CRM record (sandbox)","description":"Sandbox: simulates updating a CRM record. Nothing is written. Free, and still side-effecting so you can exercise the confirmation flow.","sideEffecting":true,"demo":true,"credits":0,"usdPerCall":0,"invokeUrl":"https://3bi.ai/api/public/v1/tools/sandbox_update_crm_record","inputSchema":{"type":"object","properties":{"recordId":{"type":"string","description":"CRM record id"},"fields":{"type":"object","additionalProperties":{},"description":"Object of field names to new values, e.g. { stage: \"churn_risk\" }"}},"required":["recordId","fields"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_update_crm_record","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"recordId":"c_1024","fields":{"stage":"churn_risk","owner":"ae_12"}}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_update_crm_record","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"simulated":true,"recordId":"c_1024","updatedFields":{"stage":"churn_risk","owner":"ae_12"},"updatedAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":428,"code":"confirmation_required","cause":"A side-effecting tool was called without a confirmation token. Nothing was executed or charged.","action":"Show error.preview to your operator. Once they approve, repeat the identical request with header x-confirmation-token: <error.confirmationToken>."},{"status":403,"code":"confirmation_invalid","cause":"The x-confirmation-token header is unknown or belongs to another workspace.","action":"Call the tool without a token to receive a fresh preview and token, then retry."},{"status":409,"code":"confirmation_mismatch","cause":"The token is bound to a specific tool and argument set; this request differs from what was previewed.","action":"Send the exact body that was previewed, or request a new confirmation for the new body."},{"status":409,"code":"confirmation_used","cause":"That confirmation token was already redeemed. Tokens are single-use.","action":"Request a new confirmation for the next call."},{"status":410,"code":"confirmation_expired","cause":"The confirmation token passed its 10-minute validity window.","action":"Call again without a token to get a new preview and token."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":true,"header":"x-confirmation-token","steps":[{"step":1,"description":"Call with no confirmation header. The response is 428 confirmation_required and carries error.preview plus error.confirmationToken.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_create_payment","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"customerId":"c_1024","amountCents":4200,"currency":"usd"}},"response":{"status":428,"body":{"ok":false,"error":{"code":"confirmation_required","message":"This tool has side effects. Show the preview to your operator, then retry the identical request with header 'x-confirmation-token: <confirmationToken>'.","tool":"sandbox_create_payment","credits":0,"preview":{"summary":"42.00 USD · c_1024","args":{"customerId":"c_1024","amountCents":4200,"currency":"usd"}},"confirmationToken":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60","expiresAt":"2026-08-09T20:25:18.358Z"}}}},{"step":2,"description":"After a human approves the preview, repeat the identical body with the token. The token is single-use and bound to these arguments — changing the body returns 409 confirmation_mismatch.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_create_payment","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>","x-confirmation-token":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60"},"body":{"customerId":"c_1024","amountCents":4200,"currency":"usd"}},"response":{"status":200,"body":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_create_payment","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"simulated":true,"paymentId":"pay_9c31be40","customerId":"c_1024","amountCents":4200,"currency":"usd","status":"succeeded"}}}}]},"name":"sandbox_create_payment","label":"Create payment (sandbox)","description":"Sandbox: simulates creating a payment charge. No money moves. Free, and still side-effecting so you can exercise the confirmation flow.","sideEffecting":true,"demo":true,"credits":0,"usdPerCall":0,"invokeUrl":"https://3bi.ai/api/public/v1/tools/sandbox_create_payment","inputSchema":{"type":"object","properties":{"customerId":{"type":"string","description":"Customer id"},"amountCents":{"type":"number","description":"Amount in cents"},"currency":{"type":"string","description":"ISO currency code, e.g. usd"}},"required":["customerId","amountCents","currency"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_create_payment","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"customerId":"c_1024","amountCents":4200,"currency":"usd"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_create_payment","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"simulated":true,"paymentId":"pay_9c31be40","customerId":"c_1024","amountCents":4200,"currency":"usd","status":"succeeded"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":428,"code":"confirmation_required","cause":"A side-effecting tool was called without a confirmation token. Nothing was executed or charged.","action":"Show error.preview to your operator. Once they approve, repeat the identical request with header x-confirmation-token: <error.confirmationToken>."},{"status":403,"code":"confirmation_invalid","cause":"The x-confirmation-token header is unknown or belongs to another workspace.","action":"Call the tool without a token to receive a fresh preview and token, then retry."},{"status":409,"code":"confirmation_mismatch","cause":"The token is bound to a specific tool and argument set; this request differs from what was previewed.","action":"Send the exact body that was previewed, or request a new confirmation for the new body."},{"status":409,"code":"confirmation_used","cause":"That confirmation token was already redeemed. Tokens are single-use.","action":"Request a new confirmation for the next call."},{"status":410,"code":"confirmation_expired","cause":"The confirmation token passed its 10-minute validity window.","action":"Call again without a token to get a new preview and token."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}},{"confirmation":{"required":true,"header":"x-confirmation-token","steps":[{"step":1,"description":"Call with no confirmation header. The response is 428 confirmation_required and carries error.preview plus error.confirmationToken.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_delete_record","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"type":"tickets","recordId":"t_51"}},"response":{"status":428,"body":{"ok":false,"error":{"code":"confirmation_required","message":"This tool has side effects. Show the preview to your operator, then retry the identical request with header 'x-confirmation-token: <confirmationToken>'.","tool":"sandbox_delete_record","credits":0,"preview":{"summary":"tickets · t_51","args":{"type":"tickets","recordId":"t_51"}},"confirmationToken":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60","expiresAt":"2026-08-09T20:25:18.358Z"}}}},{"step":2,"description":"After a human approves the preview, repeat the identical body with the token. The token is single-use and bound to these arguments — changing the body returns 409 confirmation_mismatch.","request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_delete_record","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>","x-confirmation-token":"cnf_2f6c1a94b7d34e0f9a1c5e7d8b2f4a60"},"body":{"type":"tickets","recordId":"t_51"}},"response":{"status":200,"body":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_delete_record","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"simulated":true,"deleted":{"type":"tickets","recordId":"t_51"},"deletedAt":"2026-08-09T20:15:18.358Z"}}}}]},"name":"sandbox_delete_record","label":"Delete record (sandbox)","description":"Sandbox: simulates deleting a record. Nothing is deleted. Free, and still side-effecting so you can exercise the confirmation flow.","sideEffecting":true,"demo":true,"credits":0,"usdPerCall":0,"invokeUrl":"https://3bi.ai/api/public/v1/tools/sandbox_delete_record","inputSchema":{"type":"object","properties":{"type":{"type":"string","description":"Record type"},"recordId":{"type":"string","description":"Record id"}},"required":["type","recordId"],"additionalProperties":false},"example":{"request":{"method":"POST","url":"https://3bi.ai/api/public/v1/tools/sandbox_delete_record","headers":{"Authorization":"Bearer sk_agent_...","content-type":"application/json","idempotency-key":"<unique-per-attempt>"},"body":{"type":"tickets","recordId":"t_51"}},"response":{"ok":true,"requestId":"b0e1c8a2-9f4d-4d0f-9a1e-2c5d7f8e1a30","tool":"sandbox_delete_record","demo":true,"credits":{"charged":0,"balance":500},"result":{"ok":true,"simulated":true,"deleted":{"type":"tickets","recordId":"t_51"},"deletedAt":"2026-08-09T20:15:18.358Z"}},"errors":[{"status":401,"code":"missing_api_key","cause":"No Authorization: Bearer header on the request.","action":"Send Authorization: Bearer sk_agent_… , or POST /api/public/v1/signup to mint a key."},{"status":401,"code":"invalid_api_key","cause":"The key is unknown, revoked, or past its rotation grace window.","action":"Rotate with POST /api/public/v1/keys/rotate, or create a new key in the console."},{"status":402,"code":"insufficient_credits","cause":"The workspace balance is below this tool's price. Nothing was executed or charged.","action":"Pay machine-to-machine: the body carries an x402 accepts[] offer — settle it and retry the same request with an X-PAYMENT header. Humans can instead buy credits via POST /api/public/v1/claim."},{"status":402,"code":"payment_failed","cause":"An X-PAYMENT header was supplied but the facilitator could not verify or settle it.","action":"Re-read accepts[0] from a fresh 402, rebuild the payment payload for the exact amount, asset and network, and retry."},{"status":401,"code":"key_expired","cause":"The key passed the expiry date set by its owner.","action":"Rotate the key or issue a new one in the console."},{"status":403,"code":"budget_exceeded","cause":"The call would exceed a per-call, 24-hour, or lifetime credit cap set on this key.","action":"Wait for the window to roll over, or ask the key owner to raise the cap in the console."},{"status":403,"code":"tool_not_allowed","cause":"This key has a tool allowlist that does not include the requested tool.","action":"Call an allowed tool, or ask the key owner to widen the allowlist."},{"status":403,"code":"tool_disabled","cause":"The workspace owner has disabled this tool for the org.","action":"Enable the tool in the console, or call a different tool."},{"status":403,"code":"insufficient_scope","cause":"The key is valid but does not carry the tools:invoke scope.","action":"Issue a key with tools:invoke from the console and retry with it."},{"status":404,"code":"unknown_tool","cause":"No public tool with that name exists in the catalog.","action":"Re-read GET /api/public/v1/tools and use an exact name from the catalog."},{"status":409,"code":"request_in_progress","cause":"Another call with the same idempotency-key is still executing, or an approved confirmation token is already running.","action":"Wait and retry the same idempotency-key to receive the stored response; do not change the body. If the original request is known to have failed, retry with a new idempotency-key. For a confirmation token, call the tool again with no token to get a fresh preview."},{"status":422,"code":"invalid_json","cause":"The request body was not valid JSON.","action":"Send a JSON object with content-type: application/json."},{"status":422,"code":"invalid_input","cause":"Arguments failed the tool's JSON Schema. No credits were charged.","action":"Fix the fields listed in error.issues[].path and resend."},{"status":428,"code":"confirmation_required","cause":"A side-effecting tool was called without a confirmation token. Nothing was executed or charged.","action":"Show error.preview to your operator. Once they approve, repeat the identical request with header x-confirmation-token: <error.confirmationToken>."},{"status":403,"code":"confirmation_invalid","cause":"The x-confirmation-token header is unknown or belongs to another workspace.","action":"Call the tool without a token to receive a fresh preview and token, then retry."},{"status":409,"code":"confirmation_mismatch","cause":"The token is bound to a specific tool and argument set; this request differs from what was previewed.","action":"Send the exact body that was previewed, or request a new confirmation for the new body."},{"status":409,"code":"confirmation_used","cause":"That confirmation token was already redeemed. Tokens are single-use.","action":"Request a new confirmation for the next call."},{"status":410,"code":"confirmation_expired","cause":"The confirmation token passed its 10-minute validity window.","action":"Call again without a token to get a new preview and token."},{"status":429,"code":"rate_limited","cause":"Over 60 calls per minute for this API key.","action":"Back off ~1 minute, or mint additional keys for parallel workers."},{"status":502,"code":"tool_failed","cause":"The upstream tool threw while executing. Reserved credits are refunded automatically.","action":"Retry with backoff; if it persists the integration is down — check status and report."},{"status":503,"code":"metering_unavailable","cause":"Credit metering could not be reached, so the call was not authorized or charged.","action":"Retry with backoff; the same idempotency-key is safe to reuse."},{"status":404,"code":"approval_intent_not_found","cause":"No approval intent with that id exists in this workspace.","action":"Use the intent_id from the 428 approval object; intents expire after 24 hours."},{"status":409,"code":"oauth_connection_required","cause":"This tool needs a connected third-party account, and none is linked for this workspace.","action":"POST the connect URL from the body with your API key to get an authorization URL, have your operator complete the OAuth flow, then retry the call."},{"status":404,"code":"oauth_provider_unknown","cause":"No OAuth provider with that slug is enabled.","action":"GET /api/public/v1/oauth/providers for the supported catalog."},{"status":502,"code":"oauth_callback_failed","cause":"The OAuth provider refused the code exchange or the profile lookup.","action":"Restart the connect flow; if it persists the provider app credentials may be misconfigured."},{"status":502,"code":"oauth_provider_not_configured","cause":"The OAuth provider is enabled in the catalog but its app credentials are missing on RELAY.","action":"The workspace owner should contact support; agents cannot fix this themselves."},{"status":500,"code":"oauth_authorize_failed","cause":"The OAuth authorization URL could not be generated.","action":"Retry; if it persists, check that the provider is still enabled."},{"status":500,"code":"catalog_unavailable","cause":"The OAuth provider catalog could not be loaded.","action":"Retry shortly."},{"status":500,"code":"connections_unavailable","cause":"The workspace's OAuth connections could not be listed.","action":"Retry shortly."},{"status":404,"code":"connection_not_found","cause":"No OAuth connection with that id exists in this workspace.","action":"List connections with GET /api/public/v1/oauth/connections and use a current id."},{"status":500,"code":"revoke_failed","cause":"The OAuth connection could not be revoked.","action":"Retry; the connection remains active until revocation succeeds."}]}}]}