Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/anygas-xyz:anygas-xyz-routing-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Anygas Xyz Routing API
version: 3.28.2
contact:
name: Robyn AnyGas
url: https://anygas.xyz
license:
name: Service terms
url: https://anygas.xyz/svc/api/terms
x-lastUpdated: '2026-07-29'
description: 'Operations tagged routing across 2 of this provider''s published API definitions: anygas-openapi.json, anygas-xyz-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.anygas.xyz/svc
description: Production gateway (also https://anygas.xyz/svc)
tags:
- name: Routing
description: Quote and execute gasless cross-chain routes
paths:
/api/route/quote:
post:
tags:
- Routing
summary: Quote a gasless route
description: Best gasless route for a single intent. POST a JSON body (preferred from code); the same fields are also accepted as GET query parameters with an identical response. EVMEVM runs best-of-N over the bridge aggregators; a Stellar/Solana/Bitcoin/Tron side is dispatched to its dedicated leg. Rate limit 40/min.
operationId: quoteRoute
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RouteRequest'
responses:
'200':
description: Best route quote
content:
application/json:
schema:
$ref: '#/components/schemas/Quote'
'400':
description: 'Malformed or incomplete request. Body: {error, errorCode (e.g. MISSING_FIELD, BAD_REQUEST), suggestedAction, example} — fix and resend.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Unroutable lane
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'422':
description: NO_ROUTE — no rail can settle this exact lane/amount right now (every rail's own reason is in `error`). Not a rate limit; try /api/route/compare, another amount or lane.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: RATE_LIMITED — Retry-After header (seconds) + retryAfterMs in the body. Anonymous callers get 40 quotes/min per IP; a free key (POST /api/keys/create, header x-anygas-key) raises it.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
parameters:
- $ref: '#/components/parameters/AnygasPass'
get:
tags:
- Routing
summary: Quote a gasless route (GET query form)
description: Same quote as POST /api/route/quote with the body fields given as query parameters — for browsers, curl and quick checks. Same rate limit (40/min) and response. Without any parameters it answers 400 with a usage object.
operationId: quoteRouteGet
parameters:
- name: fromChain
in: query
required: true
schema:
oneOf:
- type: string
- type: integer
description: 'Source node: EVM chain id or solana|stellar|bitcoin|tron.'
example: 8453
- name: toChain
in: query
required: true
schema:
oneOf:
- type: string
- type: integer
description: Destination node.
example: 42161
- name: amount
in: query
required: true
schema:
type: string
description: Source-token smallest units (25000000 = 25 USDC).
example: '25000000'
- name: fromToken
in: query
required: false
schema:
type: string
description: Symbol or address; omit for native.
example: USDC
- name: toToken
in: query
required: false
schema:
type: string
description: Symbol or address; omit for native.
example: USDC
- name: toAddress
in: query
required: false
schema:
type: string
description: Recipient; defaults to fromAddress.
- name: fromAddress
in: query
required: false
schema:
type: string
description: Quote origin; anonymous default used if omitted.
- name: slippage
in: query
required: false
schema:
type: number
description: Fraction, e.g. 0.005.
- $ref: '#/components/parameters/AnygasPass'
responses:
'200':
description: Best route quote
content:
application/json:
schema:
$ref: '#/components/schemas/Quote'
'400':
description: Missing/invalid parameters (body carries usage)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Unroutable lane
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
servers:
- url: https://api.anygas.xyz/svc
description: Production gateway (also https://anygas.xyz/svc)
/api/route/execute:
post:
tags:
- Routing
summary: Execute a signed gasless route
description: 'Submit a route; the relayer fronts all gas, tries ranked routes in net-output order and fails over on error, then returns a route id to track. Use mode=permit2 for a user-signed off-chain pull. Add header x-anygas-sandbox: 1 for a zero-funds simulation. Rate limit 8/min. REHEARSAL: send dryRun:true (or live:false) for a rail-independent dry run that broadcasts nothing, or the x-anygas-sandbox: 1 header for a full simulation with sbx_ ids.
**THIS ENDPOINT BROADCASTS REAL TRANSACTIONS BY DEFAULT.** Omitting `live` does NOT mean dry run. To simulate without moving funds, send `"live": false` or `"dryRun": true` (or the header `x-anygas-sandbox: 1` for a fully simulated route with `sbx_` ids). Requests to burn/null addresses are refused with `BURN_ADDRESS_REFUSED` because those funds would be unrecoverable; pass `"allowBurnAddress": true` only if the burn is intentional. Amounts must be a positive integer string in base units — malformed, zero or negative amounts are rejected with `BAD_AMOUNT` on the dry path as well as the live one.
**`minOut` coverage:** the Robyn float lane enforces it and refuses the transfer with `BELOW_AGREED_OUTPUT` before any custody change. On third-party bridge rails `minOut` is passed through to the underlying bridge as its slippage floor rather than enforced by Robyn, so the guarantee is the bridge''s, not ours. Use `POST /api/floatlane/execute` when you need Robyn itself to refuse a route that would deliver less than you agreed to.'
operationId: executeRoute
parameters:
- $ref: '#/components/parameters/SandboxHeader'
- $ref: '#/components/parameters/ApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ExecuteRequest'
properties:
dryRun:
type: boolean
description: 'Rehearse WITHOUT broadcasting. Returns {status:''DRY'', broadcast:false, wouldSend, rankedRails}. This is RAIL-INDEPENDENT and is the safe way to preview an execution. IMPORTANT: do not rely on simply OMITTING `live` — that means DRY on the float lane and the non-EVM legs, but the EVM<->EVM path ignores it and BROADCASTS. Use dryRun:true (or live:false), or the x-anygas-sandbox: 1 header for a fully simulated route.'
example: true
live:
type: boolean
description: Set false for an explicit dry run (same effect as dryRun:true). Setting it true is required by the float lane and the non-EVM legs to broadcast; the EVM<->EVM path broadcasts by default when neither dryRun nor live:false is present.
responses:
'200':
description: Route accepted (or FUNDS_REQUIRED for an unfunded non-EVM lane)
content:
application/json:
schema:
$ref: '#/components/schemas/RouteReceipt'
servers:
- url: https://api.anygas.xyz/svc
description: Production gateway (also https://anygas.xyz/svc)
/api/route/status:
get:
tags:
- Routing
summary: Track a route
description: Live ids (rt_…) are re-checked against the underlying bridge on each read; sandbox ids (sbx_…) advance on a timer. No key required.
operationId: routeStatus
parameters:
- name: id
in: query
required: true
schema:
type: string
description: Route id from execute
example: sbx_611d3343c9b8a0edae
responses:
'200':
description: Route status
content:
application/json:
schema:
$ref: '#/components/schemas/RouteReceipt'
'404':
description: Unknown route id
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
servers:
- url: https://api.anygas.xyz/svc
description: Production gateway (also https://anygas.xyz/svc)
/api/route/stream:
get:
tags:
- Routing
summary: Server-sent events for route lifecycle
description: 'Streams the route status object on every change instead of making you poll. Emits one event immediately so a late subscriber is caught up, then event: status on each change, and event: done on a terminal state (DONE/FAILED/REFUNDED) before closing. Heartbeat comments keep idle proxies open. Bounded to 15 minutes and 50 concurrent streams.'
operationId: streamRoute
parameters:
- name: id
in: query
required: true
schema:
type: string
description: route id returned by /api/route/execute
responses:
'200':
description: text/event-stream of status events
content:
text/event-stream:
schema:
type: string
'400':
description: Typed error - branch on errorCode, never on the message text
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Typed error - branch on errorCode, never on the message text
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
servers:
- url: https://api.anygas.xyz/svc
description: Production gateway (also https://anygas.xyz/svc)
/api/route/preflight:
post:
tags:
- Routing
summary: GO / NO-GO check before executing a transfer (free, read-only)
description: 'Call this before /api/route/execute. Returns `decision` (GO|NO_GO), typed `blockers` each carrying a `fix`, advisory `warnings`, and the `expected` delivery. It answers for free the questions that otherwise cost gas to discover: BELOW_FEE_THRESHOLD (a fixed corridor fee would consume the entire amount, so nothing arrives), BAD_RECIPIENT (address not valid for the destination chain family — unrecoverable once broadcast), QUOTE_ONLY_CORRIDOR (the rail prices but cannot settle), ABOVE_LANE_CAPACITY (the instant lane is full so a dearer bridge would serve you; the response names the exact ceiling to split at), HIGH_COST (>=20% of the amount withheld by vendor fees). Signs nothing, broadcasts nothing, moves nothing. Pass `fromAddress` so NFT membership — and therefore free micro-transfers — is recognised. A GO reflects conditions now; capacity and vendor fees move, so treat it as fresh for seconds. Also reports OUR OWN readiness — relayer native gas on both chains — because a preflight that says GO while the relayer cannot perform the transfer is worse than none.'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- fromChain
- toChain
- amount
properties:
fromChain:
oneOf:
- type: integer
- type: string
example: 42161
toChain:
oneOf:
- type: integer
- type: string
example: 8453
amount:
type: string
example: '5000000'
fromToken:
type: string
example: USDC
toToken:
type: string
example: USDC
fromAddress:
type: string
description: Determines membership and therefore fee tier
toAddress:
type: string
description: Validated against the destination chain family
responses:
'200':
description: Preflight verdict
content:
application/json:
schema:
type: object
properties:
decision:
type: string
enum:
- GO
- NO_GO
ok:
type: boolean
blockers:
type: array
items:
type: object
properties:
code:
type: string
what:
type: string
fix:
type: string
warnings:
type: array
items:
type: object
checks:
type: object
additionalProperties: true
expected:
type: object
additionalProperties: true
'400':
description: Malformed request. Body carries errorCode + suggestedAction + example.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: RATE_LIMITED — honour Retry-After.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
parameters:
- name: deep
in: query
required: false
schema:
type: string
enum:
- '1'
description: Set to 1 to additionally run the rail's real DRY build and inspect relayer-side readiness (token balance, allowance the bridge will pull against). This is the check that catches a missing ERC-20 allowance BEFORE it costs gas. Slower (seconds), so it is opt-in.
- $ref: '#/components/parameters/AnygasPass'
operationId: postApiRoutePreflight
x-operation-id-source: derived
servers:
- url: https://api.anygas.xyz/svc
description: Production gateway (also https://anygas.xyz/svc)
/api/preflight/full:
post:
tags:
- Routing
summary: 'One call: should I do this, and what should I know first?'
operationId: fullPreflight
description: 'Everything needed to decide well exists, but across five endpoints: can this corridor be served right now, which rails are actually competing, what would make it cheaper, is the duration measured or guessed, and does this spend fit the budget the principal set. An agent that must make five calls and reconcile them will make one and guess. BLOCKERS AND WARNINGS ARE NEVER MERGED. A blocker WILL fail; a warning might cost you. An agent that cannot tell "impossible" from "suboptimal" either aborts on noise or ploughs through real obstacles. A check that could not run is reported in `unavailable` and DOWNGRADES the verdict to `caution` — silence is never read as assent. Pass an unknown `mandateId` and you are BLOCKED, because you would be spending outside any budget while believing you were inside one. `proceed:true` means nothing KNOWN TO US blocks it. It is not a promise of success.'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RouteRequest'
responses:
'200':
description: verdict, blockers, warnings and the supporting detail
content:
application/json:
schema:
type: object
'400':
description: fromChain, toChain and amount are required
content:
application/json:
schema:
type: object
servers:
- url: https://api.anygas.xyz/svc
description: Production gateway (also https://anygas.xyz/svc)
/api/route/aggregators:
get:
summary: Per-aggregator breaker state + rolling-hour live budget (read-only, no secrets)
tags:
- Routing
responses:
'200':
description: health
operationId: getApiRouteAggregators
x-operation-id-source: derived
servers:
- url: https://api.anygas.xyz/svc
description: Production gateway (also https://anygas.xyz/svc)
components:
schemas:
Permit2SignatureTransfer:
type: object
description: 'A signed Permit2 SignatureTransfer authorising the relayer to pull exactly `amount` of `token` once. Sign the EIP-712 payload returned by POST /api/agent/do as signRequest.eip712 (domain {name:''Permit2'', chainId, verifyingContract: the canonical Permit2 contract}; types PermitTransferFrom + TokenPermissions). IMPORTANT: the signed `spender` must be the relayer address from signRequest.spender - permitTransferFrom takes the spender implicitly as msg.sender, so a permit signed for any other address cannot be redeemed.'
required:
- owner
- permitted
- nonce
- deadline
- signature
properties:
owner:
type: string
description: Address that signed the permit (the payer).
example: '0xAbC0000000000000000000000000000000000001'
permitted:
type: object
required:
- token
- amount
description: The single token permission being granted.
properties:
token:
type: string
description: ERC-20 contract on the source chain (signRequest.tokenAddress).
example: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
amount:
type: string
description: Exact amount in the token's smallest units.
example: '4000000'
nonce:
type: string
description: Unordered Permit2 nonce (bitmap) - any unused value; signRequest suggests one.
example: 0x9f2c…
deadline:
type: string
description: Unix seconds after which the permit is void.
example: '1785300000'
signature:
type: string
description: 0x… EIP-712 signature over the payload above.
example: 0x…
Error:
type: object
description: Every error carries a stable errorCode plus recovery metadata. The legacy `error` string is retained for backward compatibility - branch on errorCode.
properties:
error:
type: string
description: human-readable message (legacy field)
errorCode:
type: string
example: INSUFFICIENT_FLOAT
description: stable machine code; see GET /api/errors for the full catalogue
retryable:
type: boolean
retryAfterMs:
type: integer
description: present when the failure is transient
suggestedAction:
type: string
description: what the caller should actually do next
docs:
type: string
required:
- error
Quote:
type: object
description: Single-intent quote. Non-EVM legs return a dedicated shape (shown); EVM<->EVM lanes return best-of-N fields (bridge, bestOf, compared[]).
properties:
gasless:
type: boolean
example: true
from:
type: object
properties:
chain: {}
token:
type: string
amount:
type: string
example:
chain: 42161
token: USDC
amount: '50000000'
to:
type: object
additionalProperties: true
example:
chain: bitcoin
token: BTC
estimated: '78660'
min: '76693'
recipient: bc1q…
bridge:
type: string
example: chainflip
via:
type: array
items:
type: string
example:
- Chainflip (REGULAR)
bestOf:
type: integer
description: 'EVM<->EVM: number of aggregators compared'
example: 3
compared:
type: array
items:
type: object
additionalProperties: true
description: 'EVM<->EVM: per-aggregator outputs'
durationSec:
type: number
example: 408
robynRouteFeeBps:
type: integer
example: 25
robynRouteFee:
type: string
example: '125000'
quoteOnly:
type: boolean
description: 'TRUE means this corridor can be PRICED but NOT settled: POST /api/route/execute will refuse it with status UNSUPPORTED_DIRECTION. Absent or false means the route is executable. ALWAYS branch on this before presenting a quote as actionable - a quoteOnly route is for price comparison only. Currently set for Solana (both directions) and stellar->evm.'
example: true
executeReady:
type: boolean
description: False alongside quoteOnly:true. Present so a client can gate on a single positive assertion of executability rather than inferring it from the absence of an error.
example: false
quoteOnlyReason:
type: string
description: Human-readable explanation of why this corridor cannot settle, and what would lift the restriction.
example: Solana settlement is not proven in either direction - this quote is for comparison only.
floatlane:
type: object
additionalProperties: true
description: 'Present when the Robyn float lane can serve this pair (our own inventory on both chains, no bridge in the path). Key fields: `fee` (base units), `effectiveFeeBps`, `pricing.mode` (free-micro-vip | micro-standard | rebalancing-discount | rebalancing-partial | base | adaptive | undercut), `freeTier` (whether the micro tier applied and, if not, exactly which check failed), `vip` (member status and the recognised collections), `capNow` (largest transfer this lane can serve right now = 25% of destination float) and `destFloat`. MICRO TIER: transfers of $0.10-$25 to a low-cost destination are FREE for holders of a recognised member NFT, and cost a fraction of a cent for everyone else - never more than the standard 8bps. Pass `fromAddress` so membership can be recognised.'
properties:
fee:
type: string
example: '0'
effectiveFeeBps:
type: number
example: 0
capNow:
type: string
description: Largest transfer this lane can serve right now, in base units
example: '15020000'
pricing:
type: object
additionalProperties: true
freeTier:
type: object
additionalProperties: true
vip:
type: object
additionalProperties: true
note:
type: string
additionalProperties: true
RouteReceipt:
type: object
properties:
id:
type: string
example: rt_1a2b3c4d5e6f
status:
type: string
description: BRIDGING | DONE | FAILED (plus FUNDS_REQUIRED / AWAITING_DEPOSIT for unfunded non-EVM lanes)
example: BRIDGING
gasless:
type: boolean
example: true
sandbox:
type: boolean
example: false
bridge:
type: string
example: across
aggregator:
type: string
example: lifi
robynFee:
type: string
example: '12500'
bridged:
type: string
example: '4987500'
from:
type: object
additionalProperties: true
to:
type: object
additionalProperties: true
srcTx:
type: string
nullable: true
destTx:
type: string
nullable: true
stage:
type: string
example: RECEIVING
elapsedSec:
type: number
track:
type: string
example: /api/route/status?id=rt_1a2b3c4d5e6f
additionalProperties: true
RouteRequest:
type: object
required:
- fromChain
- toChain
- amount
properties:
fromChain:
description: 'Source node: EVM chain id or one of "solana"/"stellar"/"bitcoin".'
oneOf:
- type: string
- type: integer
example: 42161
toChain:
description: Destination node.
oneOf:
- type: string
- type: integer
example: bitcoin
amount:
type: string
description: Source-token smallest units.
example: '50000000'
fromToken:
type: string
description: Symbol or address; omit for native.
example: USDC
toToken:
type: string
description: Symbol or address; omit for native.
example: BTC
toAddress:
type: string
description: Recipient; defaults to fromAddress.
fromAddress:
type: string
description: Quote origin; anonymous default used if omitted.
slippage:
type: number
description: Fraction, e.g. 0.005.
token:
type: string
description: 'Shorthand: sets BOTH fromToken and toToken (e.g. "USDC"). Accepted on POST bodies and as a GET query parameter. Explicit fromToken/toToken win when present.'
example: USDC
ExecuteRequest:
type: object
required:
- fromChain
- toChain
- amount
properties:
fromChain:
oneOf:
- type: string
- type: integer
example: 42161
toChain:
oneOf:
- type: string
- type: integer
example: 8453
amount:
type: string
description: Smallest units.
example: '5000000'
fromToken:
type: string
example: USDC
toToken:
type: string
example: USDC
toAddress:
type: string
example: '0x8EdE0eEb8C03a45886836A1baDec03CdB08cDFb2'
mode:
type: string
enum:
- self
- permit2
default: self
description: '"permit2" = user-signed off-chain pull; "self" = operator moves own funds.'
permit2:
allOf:
- $ref: '#/components/schemas/Permit2SignatureTransfer'
description: Required when mode=permit2. Build it from signRequest returned by POST /api/agent/do.
parameters:
AnygasPass:
name: x-anygas-pass
in: header
required: false
schema:
type: string
description: 'Anonymous quota raise: base64(JSON {preparedMsg, sig}) of a one-time Plus blind pass (RFC 9474). Exempts THIS request from the rate limit and, unlike x-anygas-key, is unlinkable to any identity or other request. Free passes: POST /api/plus/trial (20/day). Over the OHTTP relay put the pass in body.pass instead (headers do not cross the envelope).'
ApiKeyHeader:
name: x-anygas-key
in: header
required: false
description: Optional API key (ak_…). Never required for reads; only tags requests for usage visibility.
schema:
type: string
SandboxHeader:
name: x-anygas-sandbox
in: header
required: false
description: Set to "1" to simulate the full execute lifecycle with zero funds — no signature, no relayer spend, nothing on-chain. Returns an sbx_ id that progresses BRIDGING -> DONE in ~40s.
schema:
type: string
enum:
- '1'
x-refined-from:
- anygas-openapi.json
- anygas-xyz-openapi.json