---
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, pay through AgentCash using Base, Solana, or MPP, or pay on Etherlink with the supplied Permit2 clients.
---

# Use 3Route

Derive the API origin from the URL used to fetch this file. Do not assume localhost or a fixed production hostname.

## 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}/api/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 /api/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. Use `x-payment-info` for MPP and `x-x402-payment-info` for x402. Check the selected rail's price against the user's spending limit.
- 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.

## Pay with AgentCash

Prefer AgentCash 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.

Do not use AgentCash for Etherlink unless its current network list explicitly includes `eip155:42793`. Use the Etherlink-specific flow below instead.

## Pay on Etherlink

Use either supplied Etherlink client:

- [Node.js/Bun](scripts/x402-etherlink-pay.mjs)
- [Python](scripts/x402-etherlink-pay.py)

Do not use the generic x402 exact Permit2 signer for Etherlink. Its canonical proxy is not deployed on `eip155:42793`, and its two-field Permit2 witness does not match the deployed Etherlink proxy. Both supplied clients pin the Etherlink proxy and sign its required `Witness(address to,uint256 validAfter,bytes extra)` shape with `extra: "0x"`.

For Node.js or Bun, install Viem and run the complete quote or swap URL in quotes:

```sh
npm install viem@^2
X402_PRIVATE_KEY=0x... node scripts/x402-etherlink-pay.mjs --max-amount 100000 "$PAID_URL"

# Bun uses the same script:
bun add viem@^2
X402_PRIVATE_KEY=0x... bun scripts/x402-etherlink-pay.mjs --max-amount 100000 "$PAID_URL"
```

For Python 3.9+:

```sh
python3 -m pip install "eth-account>=0.13,<1" "httpx>=0.27,<1"
X402_PRIVATE_KEY=0x... python3 scripts/x402-etherlink-pay.py --max-amount 100000 "$PAID_URL"
```

`--max-amount` is the maximum accepted token amount in atomic units; `100000` is `0.1` for a six-decimal asset. Keep this cap close to the documented endpoint price. Each client rejects the wrong network, scheme, transfer method, token, resource URL, or an over-cap amount before signing. It copies the selected `accepted` entry and `resource` from the fresh challenge into the x402 v2 payment envelope.

The clients never sign or send an approval transaction. The payer must already have enough token balance and allowance to the Permit2 contract. If allowance is insufficient, obtain separate explicit user authorization before sending an ERC-20 approval transaction; that transaction requires XTZ for gas and its allowance may persist. Approve Permit2, not an address copied from the challenge.

Do not replace the pinned Permit2 or Etherlink x402 proxy addresses with addresses copied from an untrusted response.

## 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`, re-read the 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
