{"openapi":"3.1.1","info":{"title":"taskfuel Gateway API","version":"v1","summary":"Discover and call paid HTTP-402 APIs through one prepaid account.","description":"The CLI and canonical taskfuel agent skill are the recommended interface. Install the CLI with `curl -fsSL https://taskfuel.ai/install.sh | sh`, run `taskfuel sync-skill`, then use `taskfuel connect`. The user must complete browser sign-in/approval and card top-ups themselves. Use this OpenAPI document for direct HTTP integrations."},"externalDocs":{"description":"Agent setup, usage guide, and human handoffs","url":"https://app.taskfuel.ai/llms.txt"},"servers":[{"url":"https://app.taskfuel.ai"}],"tags":[{"name":"Setup","description":"Install the recommended taskfuel CLI."},{"name":"Connection","description":"Pair the CLI with a user's account. The user must approve the code in a browser."},{"name":"Account","description":"Read the authenticated account and balance."},{"name":"Discovery","description":"Find allowed services and inspect their operations."},{"name":"Calls","description":"Quote or execute calls to allowed paid services."},{"name":"Feedback","description":"Rate catalog endpoints, and send feedback about taskfuel itself."},{"name":"Operations","description":"Public treasury address and funding health endpoints."}],"security":[{"bearerAuth":[]}],"paths":{"/install.sh":{"get":{"operationId":"installCli","tags":["Setup"],"summary":"Download the taskfuel CLI installer","description":"Run it with `curl -fsSL https://taskfuel.ai/install.sh | sh`, then run `taskfuel sync-skill` to ensure the canonical agent skill is installed.","security":[],"responses":{"200":{"description":"POSIX shell installer.","content":{"text/x-shellscript":{"schema":{"type":"string"}}}}}}},"/v1/connect/start":{"post":{"operationId":"startConnection","tags":["Connection"],"summary":"Start a device-code connection","description":"Returns a short-lived code and browser URL. Show both to the user and ask them to sign in and approve the connection. No API key is required.","security":[],"responses":{"200":{"description":"Connection request created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectStart"}}}}}}},"/v1/connect/poll":{"get":{"operationId":"pollConnection","tags":["Connection"],"summary":"Poll a device-code connection","description":"Poll at the interval returned by /v1/connect/start. An approved API key is delivered once and the connection request is then deleted.","security":[],"parameters":[{"name":"code","in":"query","required":true,"description":"The code returned by /v1/connect/start.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Connection pending or approved.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ConnectPending"},{"$ref":"#/components/schemas/ConnectApproved"}]}}}},"400":{"description":"The code query parameter is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The code is unknown or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectExpired"}}}}}}},"/v1/me":{"get":{"operationId":"getAccount","tags":["Account"],"summary":"Read the connected account and balance","responses":{"200":{"description":"Authenticated account summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"401":{"description":"The bearer API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/discover":{"get":{"operationId":"discoverOperations","tags":["Discovery"],"summary":"List services, search operations, or inspect one operation","description":"With no parameters, lists allowed domains. Use q for keyword search, domain to list or filter one service, or url and method together for one operation's full provider docs.","parameters":[{"name":"q","in":"query","description":"Keywords to search across indexed provider operations.","schema":{"type":"string"}},{"name":"domain","in":"query","description":"Allowed domain to list or search. A URL-shaped value is normalized.","schema":{"type":"string"}},{"name":"url","in":"query","description":"Exact operation URL. Must be supplied together with method.","schema":{"type":"string","format":"uri"}},{"name":"method","in":"query","description":"HTTP method for the exact operation URL. Must be supplied together with url.","schema":{"type":"string"}}],"responses":{"200":{"description":"Domain list, operation list, or full operation docs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscoverResponse"}}}},"400":{"description":"The query parameter combination is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The bearer API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The domain or operation was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/call":{"post":{"operationId":"callPaidService","tags":["Calls"],"summary":"Quote or call an allowed paid service","description":"Set dryRun to true to read the real price from a paid upstream's HTTP-402 challenge without paying. A free upstream does not issue a challenge, so a dry run executes it at $0. The response body and content type otherwise pass through from the upstream. Quote the first call, and use maxAmountUsd on the paid call to cap it at the approved quote.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallRequest"}}}},"responses":{"200":{"description":"Quote JSON, free response, or paid upstream response. Successful upstream status codes other than 200 are also passed through.","headers":{"x-taskfuel-source":{"description":"Present when the body was relayed from the upstream endpoint (always `upstream`). Responses the gateway authors itself (quotes and gateway errors) omit it, so on a failure it tells you whose error you are reading.","schema":{"type":"string","enum":["upstream"]}},"x-taskfuel-cost":{"description":"USD charged for this response, formatted to six decimals.","schema":{"type":"number","format":"double"}},"x-taskfuel-balance":{"description":"Remaining prepaid USD balance, formatted to six decimals.","schema":{"type":"number","format":"double"}},"x-taskfuel-result-url":{"description":"Where this same response can be fetched back, free, for the next hour. Present only on a charged call. It exists because a paid call is not cancelled when a client stops waiting for it: use this rather than repeating the call, which would pay for the same work twice.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Quote"},{}]}},"text/plain":{"schema":{"type":"string"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The JSON request is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The bearer API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The account balance is empty; the user must top up in the dashboard.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The domain is not allowed or the upstream price exceeds the active cap.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The request body exceeds 1 MiB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The API key exceeded a rate limit (60 calls/min per key, 300/min across all keys). The body's retry_after_seconds and the Retry-After header give the wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The upstream request or payment failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The required payment adapter is not configured.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Any upstream status and body can be passed through after a call.","headers":{"x-taskfuel-source":{"description":"Present when the body was relayed from the upstream endpoint (always `upstream`). Responses the gateway authors itself (quotes and gateway errors) omit it, so on a failure it tells you whose error you are reading.","schema":{"type":"string","enum":["upstream"]}},"x-taskfuel-cost":{"description":"USD charged for this response, formatted to six decimals.","schema":{"type":"number","format":"double"}},"x-taskfuel-balance":{"description":"Remaining prepaid USD balance, formatted to six decimals.","schema":{"type":"number","format":"double"}},"x-taskfuel-result-url":{"description":"Where this same response can be fetched back, free, for the next hour. Present only on a charged call. It exists because a paid call is not cancelled when a client stops waiting for it: use this rather than repeating the call, which would pay for the same work twice.","schema":{"type":"string"}}}}}}},"/v1/calls":{"get":{"operationId":"listCallResults","tags":["Calls"],"summary":"List paid results still available to fetch back","description":"What the caller has outstanding: `in_flight` for calls still running, `results` for finished calls whose response is still stored, newest first. Free. This is the way back in after a client-side timeout: no response arrived, so no request id was ever learned. A call is in flight for as long as the upstream takes, which is exactly when a caller who gave up is deciding whether to call again, so check here before repeating anything. Results are kept for an hour, and only for calls that were charged.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The caller's still-available results.","content":{"application/json":{"schema":{"type":"object","properties":{"in_flight":{"type":"array","description":"Calls running right now: the upstream has not answered, so they are not charged and have no result yet. Wait for one rather than repeating it.","items":{"$ref":"#/components/schemas/InFlightCall"}},"results":{"type":"array","items":{"$ref":"#/components/schemas/CallResult"}},"retention_seconds":{"type":"number"},"detail":{"type":"string"}}}}}},"401":{"description":"The bearer API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/calls/{request_id}":{"get":{"operationId":"getCallResult","tags":["Calls"],"summary":"Fetch back a paid call's response","description":"Returns the stored response for a call already paid for, with the upstream's own status, content type and body, so it parses like the POST /v1/call response it replaces. It carries x-taskfuel-cost for what the original call cost, but no x-taskfuel-balance, since nothing is charged here. Free: the call is already paid for, and charging to collect it would reproduce the problem this solves. Use it instead of repeating a call that timed out.","security":[{"bearerAuth":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"description":"The call's request id, as returned in x-taskfuel-request-id or by GET /v1/calls.","schema":{"type":"string"}}],"responses":{"200":{"description":"The stored upstream response. Other successful upstream status codes are mirrored the same way.","headers":{"x-taskfuel-cost":{"description":"USD charged for this response, formatted to six decimals.","schema":{"type":"number","format":"double"}},"x-taskfuel-source":{"description":"Present when the body was relayed from the upstream endpoint (always `upstream`). Responses the gateway authors itself (quotes and gateway errors) omit it, so on a failure it tells you whose error you are reading.","schema":{"type":"string","enum":["upstream"]}},"x-taskfuel-request-id":{"description":"The request id this result belongs to.","schema":{"type":"string"}},"x-taskfuel-replayed":{"description":"Always `true` here. Marks this as a replay of a call already billed, so the spend is not counted twice.","schema":{"type":"string","enum":["true"]}},"x-taskfuel-called-at":{"description":"When the original call was made (ISO 8601).","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{}},"text/plain":{"schema":{"type":"string"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"202":{"description":"The call is still running: the upstream has not answered, so nothing has been charged and there is no body yet. The in-flight metadata is returned alongside. Ask again rather than repeating the call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The bearer API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No stored result for that request id: it expired, the call was never charged, or it belongs to another account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The call was charged, but its body was too large to store. The metadata is returned alongside the error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/rate":{"post":{"operationId":"rateEndpoint","tags":["Feedback"],"summary":"Rate a documented endpoint","description":"Rate a catalog endpoint you called, using the method and url exactly as discover returns them: vote up if you got the expected/useful result, down if it didn't work or wasn't worth the price. Rate it against its own docs, from a call you made. Not down-votes: a missing catalog entry, your own bad arguments, or an endpoint that worked but wasn't what your task needed. Vote and report must agree. Add report to describe what concretely disrupted usage: an unexpected response code, ignored arguments, an empty or low-quality response (it doesn't change the rating). One vote per endpoint: voting again replaces the previous vote. Problems with taskfuel itself go to /v1/feedback instead.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateRequest"}}}},"responses":{"200":{"description":"Vote recorded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateResult"}}}},"400":{"description":"The rating body is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The bearer API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This account has not made any paid call yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No documented operation with that method and url.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The rating body exceeds 16 KiB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"More than one vote per second.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/feedback":{"post":{"operationId":"submitFeedback","tags":["Feedback"],"summary":"Send feedback about taskfuel itself","description":"One free-text message to taskfuel (the gateway, not any provider): setup or connection trouble, discovery that found nothing or the wrong things, billing or balance confusion, wrong docs, a capability missing from the catalog, or one failure pattern across several endpoints. A problem with a single endpoint's own behavior belongs at /v1/rate instead. The message is read for triage and never published.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackRequest"}}}},"responses":{"200":{"description":"Feedback received.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackResult"}}}},"400":{"description":"The feedback body is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The bearer API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The body is an endpoint rating, which moved to POST /v1/rate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The feedback body exceeds 16 KiB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"More than one submission per second.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/treasury":{"get":{"operationId":"getTreasury","tags":["Operations"],"summary":"Read the public treasury address and supported networks","security":[],"responses":{"200":{"description":"Public treasury information.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Treasury"}}}},"503":{"description":"The treasury is not configured.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/treasury/balances":{"get":{"operationId":"getTreasuryBalances","tags":["Operations"],"summary":"Check treasury funding health","description":"Returns 200 only when the configured treasury holds more than the reported minimum on both Base and Tempo.","security":[],"responses":{"200":{"description":"Treasury balances are above the minimum.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TreasuryBalances"}}}},"502":{"description":"On-chain balances could not be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The treasury is missing or at least one balance is low.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/TreasuryLow"}]}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A taskfuel API key with the sk-402- prefix."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"detail":{"type":"string"}},"additionalProperties":true},"ConnectStart":{"type":"object","required":["code","verification_url","expires_in","poll_interval"],"properties":{"code":{"type":"string","minLength":8,"maxLength":8},"verification_url":{"type":"string","format":"uri"},"expires_in":{"type":"integer","description":"Lifetime in seconds."},"poll_interval":{"type":"integer","description":"Recommended polling interval in seconds."}},"additionalProperties":false},"ConnectPending":{"type":"object","required":["status"],"properties":{"status":{"const":"pending"}},"additionalProperties":false},"ConnectApproved":{"type":"object","required":["status","key"],"properties":{"status":{"const":"approved"},"key":{"type":"string","description":"Single-delivery taskfuel API key. Store it securely and never display it to anyone else.","pattern":"^sk-402-"}},"additionalProperties":false},"ConnectExpired":{"type":"object","required":["status"],"properties":{"status":{"const":"expired"}},"additionalProperties":false},"Account":{"type":"object","required":["email","balance_usd","spent_usd","credit_limit_usd"],"properties":{"email":{"type":"string","format":"email"},"balance_usd":{"type":"number","format":"double"},"spent_usd":{"type":"number","format":"double"},"credit_limit_usd":{"type":"number","format":"double"}},"additionalProperties":false},"Rating":{"type":"object","description":"Feedback from paying users. `score` is the share of up-votes weighted by each voter's lifetime top-ups; `weight` is the total voter weight behind it.","required":["score","up","down","weight"],"properties":{"score":{"type":"number","minimum":0,"maximum":1},"up":{"type":"integer","minimum":0},"down":{"type":"integer","minimum":0},"weight":{"type":"number","minimum":0}},"additionalProperties":false},"Domain":{"type":"object","required":["domain","name","description","specUrl","score","protocol","rating"],"properties":{"domain":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"specUrl":{"type":"string","format":"uri"},"score":{"type":"number","minimum":0,"maximum":1},"protocol":{"type":"string","enum":["x402","mpp"]},"rating":{"anyOf":[{"$ref":"#/components/schemas/Rating"},{"type":"null"}]}},"additionalProperties":false},"OperationSummary":{"type":"object","required":["domain","method","url","summary","rating"],"properties":{"domain":{"type":"string"},"method":{"type":"string"},"url":{"type":"string","format":"uri"},"summary":{"type":"string"},"matchedOn":{"type":"array","items":{"type":"string"}},"score":{"type":"number"},"rating":{"anyOf":[{"$ref":"#/components/schemas/Rating"},{"type":"null"}]}},"additionalProperties":false},"DomainList":{"type":"object","required":["domains","hint"],"properties":{"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"hint":{"type":"string"}},"additionalProperties":false},"OperationList":{"type":"object","required":["results"],"properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/OperationSummary"}},"unavailable":{"type":"array","items":{"type":"string"}}},"additionalProperties":false},"OperationDocs":{"type":"object","required":["domain","method","url","docs","rating"],"properties":{"domain":{"type":"string"},"method":{"type":"string"},"url":{"type":"string","format":"uri"},"docs":{"description":"The exact provider OpenAPI operation object, including parameters and request-body schema."},"rating":{"anyOf":[{"$ref":"#/components/schemas/Rating"},{"type":"null"}]}},"additionalProperties":false},"DiscoverResponse":{"oneOf":[{"$ref":"#/components/schemas/DomainList"},{"$ref":"#/components/schemas/OperationList"},{"$ref":"#/components/schemas/OperationDocs"}]},"CallRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"An operation URL returned by /v1/discover on an allowed domain."},"method":{"type":"string","default":"GET"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"anyOf":[{"type":"object"},{"type":"array"},{"type":"string"}],"description":"The upstream request body. Pass JSON as an object or array: it is serialized once and forwarded. A string is forwarded byte for byte, so do not JSON-encode the object yourself."},"dryRun":{"type":"boolean","default":false,"description":"Read the upstream's 402 price without paying. Free endpoints execute at $0."},"maxAmountUsd":{"type":"number","format":"double","exclusiveMinimum":0,"description":"Caller-selected USD ceiling. It can tighten but never raise the gateway cap."},"model":{"type":"string","maxLength":128,"description":"The caller's own model id, e.g. claude-opus-5. Recorded with the call and nothing else: it never affects pricing, routing, what is sent upstream, or whether the call succeeds."}},"additionalProperties":false},"Quote":{"type":"object","required":["dry_run","amount_usd","exceeds_cap","per_call_cap_usd","max_amount_usd","detail","upstream_402_body"],"properties":{"dry_run":{"const":true},"amount_usd":{"type":"number","format":"double"},"exceeds_cap":{"type":"boolean"},"per_call_cap_usd":{"type":"number","format":"double"},"max_amount_usd":{"type":["number","null"],"format":"double"},"detail":{"type":"string"},"upstream_402_body":{}},"additionalProperties":false},"CallResult":{"type":"object","description":"A paid call whose response is still stored. The body itself is not here: fetch it with GET /v1/calls/{request_id}.","required":["request_id","method","endpoint","domain","status","content_type","body_bytes","charged_usd","settlement","called_at","expires_at"],"properties":{"request_id":{"type":"string"},"method":{"type":"string"},"endpoint":{"type":"string"},"domain":{"type":"string"},"status":{"type":"integer"},"content_type":{"type":"string"},"body_bytes":{"type":"integer"},"charged_usd":{"type":"number","format":"double"},"settlement":{"type":["string","null"],"description":"The settlement reference this call was debited against, `x402:<tx>` or `mpp:<reference>`."},"called_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}},"additionalProperties":false},"InFlightCall":{"type":"object","description":"A paid call that is running right now. It has no status, no body and no charge yet: the upstream has not answered. Repeating it buys the same work a second time.","required":["request_id","method","endpoint","domain","started_at","state"],"properties":{"request_id":{"type":"string"},"method":{"type":"string"},"endpoint":{"type":"string"},"domain":{"type":"string"},"started_at":{"type":"string","format":"date-time"},"state":{"type":"string","enum":["in_flight"]}},"additionalProperties":false},"RateRequest":{"type":"object","required":["method","url","vote"],"properties":{"method":{"type":"string","minLength":1},"url":{"type":"string","format":"uri"},"vote":{"type":"string","enum":["up","down"]},"report":{"type":"string","minLength":1,"maxLength":2000}},"additionalProperties":false},"RateResult":{"type":"object","required":["method","url","vote"],"properties":{"method":{"type":"string"},"url":{"type":"string","format":"uri"},"vote":{"type":"string","enum":["up","down"]}},"additionalProperties":false},"FeedbackRequest":{"type":"object","required":["message"],"properties":{"message":{"type":"string","minLength":1,"maxLength":2000,"description":"What happened and what you expected, briefly and concretely. No secrets or response data."}},"additionalProperties":false},"FeedbackResult":{"type":"object","required":["received"],"properties":{"received":{"const":true}},"additionalProperties":false},"Network":{"type":"object","required":["chainId","token","tokenAddress","protocols"],"properties":{"chainId":{"type":"integer"},"token":{"type":"string"},"tokenAddress":{"type":"string"},"protocols":{"type":"array","items":{"type":"string","enum":["x402","mpp"]}}},"additionalProperties":false},"Treasury":{"type":"object","required":["address","detail","networks"],"properties":{"address":{"type":"string"},"detail":{"type":"string"},"networks":{"type":"object","required":["base","tempo"],"properties":{"base":{"$ref":"#/components/schemas/Network"},"tempo":{"$ref":"#/components/schemas/Network"}},"additionalProperties":false}},"additionalProperties":false},"BalanceValues":{"type":"object","required":["base_usdc","tempo_usdce"],"properties":{"base_usdc":{"type":"number","format":"double"},"tempo_usdce":{"type":"number","format":"double"}},"additionalProperties":false},"TreasuryBalances":{"type":"object","required":["ok","address","min_usd","balances"],"properties":{"ok":{"const":true},"address":{"type":"string"},"min_usd":{"type":"number","format":"double"},"balances":{"$ref":"#/components/schemas/BalanceValues"}},"additionalProperties":false},"TreasuryLow":{"type":"object","required":["error","detail","address","min_usd","balances"],"properties":{"error":{"const":"treasury_low"},"detail":{"type":"string"},"address":{"type":"string"},"min_usd":{"type":"number","format":"double"},"balances":{"$ref":"#/components/schemas/BalanceValues"}},"additionalProperties":false}}}}