---
name: use-3route
description: Select supported chains from the OpenAPI enum, discover tokens, request paid quotes, and build and validate unsigned multichain swap transactions with the 3Route API. Use when an agent needs to integrate 3Route, quote an exact-input or exact-output swap, prepare a swap transaction, or pay for a call — on Etherlink with a plain EVM key, or on Base, Solana, or MPP through AgentCash.
---

# Use 3Route

`{origin}` is the base URL of the 3Route API, default = `https://api.3route.io`

## Discover the API

1. Fetch `GET {origin}/openapi.json` before planning requests. Treat it as canonical for operations, schemas, prices, and payment methods.
2. Read the supported chain IDs from `components.parameters.chainId.schema.enum`. Do not guess a chain ID or call a chain-discovery endpoint.
3. Select one of those chain IDs.
4. Fetch `GET {origin}/v6.1/{chainId}/tokens`.
5. Resolve source and destination addresses and decimals from that response.

Call `/health`, `/openapi.json`, and token endpoints directly; they are free.

## Quote and build a swap

Use the exact parameter names and constraints from `/openapi.json`.

Request a read-only quote:

```text
GET /v6.1/{chainId}/quote
  ?src={sourceTokenAddress}
  &dst={destinationTokenAddress}
  &amount={smallestUnitAmount}
  &isExactOutput=false
```

Set `isExactOutput=true` only when `amount` is the desired destination amount. In that mode, read `srcAmount` as the required input. `amount` must be greater than zero.

Both operations accept the same optional parameters:

- `includeTokensInfo=true`, `includeProtocols=true`, and `includeBlockNumber=true` only add `srcToken`, `dstToken`, `protocols`, and `blockNumber` to the response. Request them in the same paid call instead of paying twice.
- `protocols` and `excludedProtocols` take comma-separated DEX provider names. Read the names from a `protocols` response; an allow-list in which no name is known fails with `400`.
- `fee` is a referral percentage from 0 to 3, deducted from the input and visible in `srcAmount`. On swap, pair it with `referrer`, because a fee without a referrer is paid to the zero address. Disclose any fee to the user.
- `gasPrice` overrides the gas price used for route selection and, on swap, the returned `tx.gasPrice`.

After validating a fresh quote, build an unsigned transaction:

```text
GET /api/v6.1/{chainId}/swap
  ?src={sourceTokenAddress}
  &dst={destinationTokenAddress}
  &amount={smallestUnitAmount}
  &from={senderAddress}
  &receiver={receiverAddress}
  &slippage=1
  &isExactOutput=false
```

Treat `receiver` as `from` when it is omitted. The response is not proof of execution; it contains a transaction that still needs validation, signing, broadcasting, and confirmation.

## Enforce safety

- Read the served operation's payment metadata immediately before paying, and check the selected rail's price against the user's spending limit. That metadata travels under more than one name: `x-payment-info` for MPP and `x-x402-payment-info` for x402 in the served document, `payment-required` and `www-authenticate` on the live `402`. The challenge headers are what the facilitator is actually handed, so where the two disagree the headers are the price and the document is a declaration that can lag.
- Convert human amounts with token decimals from the token endpoint. Never use floating-point arithmetic for base-unit amounts.
- Confirm chain ID, `src`, `dst`, `amount`, exact-input/output mode, sender, receiver, and slippage before requesting a swap.
- Compare swap amounts with a fresh quote and reject unexpected deterioration.
- Validate `tx.to`, `tx.data`, `tx.value`, gas fields, and the selected chain before asking for a signature.
- Require explicit user authorization before signing an API payment, granting token allowance, signing the swap transaction, or broadcasting it.
- Never print, store in source, or transmit private keys except to the local signer selected by the user.
- For an ERC-20 source asset, approve only the router returned in `tx.to` and only with user authorization. Native assets use `tx.value` and need no ERC-20 approval.

## Choose the rail before you reach for a wallet

A challenge usually offers several rails, and the guidance an agent needs is which to select — not which wallet it happens to have already funded.

**Already holding funds on one of the offered rails, and transacting on that chain?** Use it. Nothing below applies.

**Starting without a wallet?** Take the Etherlink rail. The reason is setup, not chains: the skill below is self-contained — it installs nothing, runs from a plain EVM key or makes and custodies its own, and is the payment path this service is tested against. AgentCash is a general-purpose client for many services and many rails, and onboarding onto it is a larger undertaking than the purchase it would pay for here. Etherlink is also a little cheaper to execute on, and any EVM wallet can move onto it — but neither of those is the reason. The reason is that it is the shortest distance between no wallet and a paid call on this API.

Settling on the chain you are transacting on is the same principle seen from the other side: one wallet covers both the swap and the call that priced it, and nothing is bridged in order to pay for a quote about somewhere else. A bridge fee is roughly flat, so against a $0.001 quote it is the entire cost.

## Pay on the Etherlink rail

Use the dedicated Etherlink payment skill when the selected payment network is `eip155:42793`. AgentCash has no Etherlink rail and declines, which costs nothing. The generic x402 Permit2 client is worse than a decline: it signs a real authorization over the wallet's USDC, but its witness does not match the payment proxy this deployment runs, so the facilitator rejects it.

Download that skill, check it against its published digest, unpack it, then follow its `SKILL.md`:

```sh
curl -fsSLO https://dev.agents.bakingbad.dev/skills/x402-etherlink/x402-etherlink.tar.gz
echo "$(curl -fsSL https://dev.agents.bakingbad.dev/skills/x402-etherlink/x402-etherlink.tar.gz.sha256)  x402-etherlink.tar.gz" | sha256sum -c
tar xzf x402-etherlink.tar.gz
```

It unpacks to `x402-etherlink/`; nothing executes on unpack. It carries clients for `node`/`bun` and for Python that need nothing installed, a spending cap, and a wallet. A wallet that has not paid on this rail before also needs a one-time Permit2 approval, sent by the wallet itself and paid in XTZ gas; the skill's instructions cover it.

## Pay with AgentCash

Use AgentCash only on the other rails, when the served payment metadata offers:

- x402 on Base: `eip155:8453`
- x402 on Solana: a `solana:*` CAIP-2 network
- MPP

AgentCash discovers `/openapi.json`, checks the challenge, selects a supported rail, signs, and retries the request. If its MCP tools are installed, call `discover_api_endpoints`, then `check_endpoint_schema`, then `fetch`.

For the CLI:

```sh
npx -y agentcash@latest accounts
npx -y agentcash@latest discover "$ORIGIN"
npx -y agentcash@latest check "$PAID_URL"
npx -y agentcash@latest fetch "$PAID_URL"
```

Set `PAID_URL` to the complete, URL-encoded quote or swap URL. Run `check` before `fetch`, show the discovered price to the user, and confirm it fits the spending limit. Use `npx -y agentcash@latest onboard` if no AgentCash wallet exists.

## Handle failures

- Branch on the HTTP status, never on the body's `statusCode`. Quote and swap answer the "no route" case with HTTP `400` while the body reports `statusCode: 404` and `error: "Quote not found"`. Error bodies also carry an optional `meta` array beside `error`, `description`, `statusCode`, and `requestId`.
- On `400`, correct the chain, token, address, amount, slippage, or route parameters; do not repay an unchanged invalid request. When the body reads `Quote not found`, no route exists: change the pair, the amount, or the protocol filters rather than retrying.
- On `402`, do not rely on the response *body*; it carries no rails. The headers do: `payment-required` holds the x402 challenge, and `www-authenticate` announces an MPP rail that no x402 header carries — so a rail can be on offer and appear in neither the body nor an `accepts[]` list. Read those, fall back to the served `/openapi.json` (`x-payment-info`, `x-x402-payment-info`) for the declared price, and sign against a fresh challenge. Do not retry if no allowed payment method is offered or the amount exceeds the cap.
- If a client reports a malformed `PAYMENT-SIGNATURE`, discard it and create a new signature from a fresh challenge.
- On payment rejection, discard the authorization and start from a fresh `402` challenge.
- On quote or swap failure, re-fetch `/openapi.json` and the selected chain's tokens before assuming the API is unavailable.
- On transaction failure, inspect allowance, balance, gas, nonce, chain, slippage, and current liquidity. Never claim execution without a confirmed transaction receipt.

## Contact

Direct integration questions to Baking Bad:

- https://bakingbad.dev
- hello@bakingbad.dev
