Developers
Changelog
What changed, newest first: the app and website in plain words, then the REST API and the MCP server by version. The current API version is 3.2.1; the API index (GET /api/v1), the OpenAPI document and the MCP server all report it. A new endpoint, field or tool is a minor version; a change that could break a working integration would be a major one, announced here first.
App · 17 October 2026
ZeroFee is now a family: Swap, Pay, and Wallet coming soon. Zcash is back: four privacy protocols. ZeroFee is now a family of privacy apps on open protocols, with 0% from ZeroFee: ZeroFee Swap, ZeroFee Pay and, coming soon, ZeroFee Wallet. The Zcash step is live again, so there are four privacy protocols to stack your way.
- One family, one fee: ZeroFee Swap (cross-chain swaps across 70+ chains), ZeroFee Pay (pay links) and the REST API and MCP server for developers and AI agents. ZeroFee adds 0% to all of them.
- ZeroFee Wallet is coming soon: your keys on your device, Shield and Unshield in a tap, and the ZeroFee Swap engine built in. Follow @ZeroFeeSi on X for the launch.
- The Zcash step is back: your coin becomes shielded ZEC in a Zcash wallet made in your browser, where the sender, the receiver and the amount are hidden, then leaves it as the coin you want.
- Four privacy protocols, stacked your way: a confidential crossing on NEAR Intents, the Solana ZK pool, Zcash shielded and Monero.
- Pay links can go private through the Solana ZK pool, Zcash and Monero, in the order the payer chooses. A standard link delivers exactly the amount asked, a private link at least that amount, and the payer pays every fee.
App · 16 October 2026
A new swap page, with protocols instead of exchanges. The swap page was rebuilt. Swaps now go through protocols, privacy is a set of steps you switch on, and you see the total cost before you start. ZeroFee still takes 0%.
- Protocols instead of exchanges. NEAR Intents carries most swaps and Relay carries coins NEAR Intents doesn’t list. The swap page no longer falls back to a single exchange.
- Privacy is now a set of steps: the Solana ZK pool (new, through Privacy Cash) and Monero. Switch on one or both and choose their order. Crossing chains on NEAR Intents stays confidential wherever NEAR allows it, with no switch needed.
- The Monero step now takes about 15 minutes on a swap; Monero hides the sender, the receiver and the amount (ring signatures and stealth addresses). Your coins are held for a few minutes on the way. Private payments (about 15–30 minutes) and the REST API’s xmr option use the same step.
- The Zcash step is paused while we update for a Zcash network upgrade. It is coming back soon.
- Privacy steps use temporary wallets made in your browser. Their keys stay in your browser, and each wallet is designed to end empty. If a step fails, it is tried once more on a different route; if it still can’t finish, your money goes back to your refund address.
- Before you start, the page shows what arrives, how long it takes and the total cost in dollars and as a percentage, with what’s in it.
- The coin list shows only coins a protocol has been checked to carry.
- Each swap’s page now shows the time so far, the cost, where your money is, and a “Slower than usual” notice. If something goes wrong, the page tells our team automatically. A stopped swap shows “Try again” and “Send my money back”, and a support button that opens @ZeroFeeSi_bot on Telegram with that swap attached.
- Removed from the swap page: the list of competing routes, presets and quick amounts, and the skip-review option.
API 3.2.1 · 2026-10-17
Fewer "busy" answers from Relay, and every Relay refusal says why. No request or response shape changed.
Fixed
- errors[].error for Relay read "busy right now — try again in a moment" on many pairs that do route: one quote asked Relay up to 22 times (the two-step route's hubs, and an immediate retry of each rate-limited answer), so Relay's per-key limit answered HTTP 429. A quote now asks Relay about once per distinct question, and the two-step route's legs only use spare capacity. Ask again after a busy answer, as before.
- errors[].error for Relay now gives Relay's own reason and the size asked instead of a bare "not available for this pair" / "no route for this pair", e.g. "not available for this pair: Relay opens deposit addresses only for major tokens, and CLANKER isn't one (Relay: “Deposit addresses only supported for major tokens”)", "below Relay's minimum: 0.0001 ETH is too small for this pair — a larger amount may route (Relay: “…”)", or "the refund address isn't accepted — check it (Relay: “…”)". A refusal is never read as busy because of the words in it.
- POST /api/v1/quote: with `routes: []` and nothing else in `errors`, the `note` and the prehop / posthop block's `why` are also listed in `errors` (provider "zerofee", "temporary-wallet (pay side)" or "temporary-wallet (receive side)"), even when the temporary-wallet route is offered, so a client that reads only `errors` sees the reason.
- GET /api/v1/chains: XRP Ledger now says canPayFrom true. NEAR Intents takes XRP deposits (XRP → SOL, USDC on Base and ETH all quote); it said false while quotes from XRP routed.
API 3.2.0 · 2026-10-17
The pre-launch lock is gone: swaps, pay links and funding are created as normal, and the not_open error no longer exists.
Fixed
- POST /api/v1/quote, POST /api/v1/swap, POST /api/v1/paylink and the MCP tools get_quote, create_deposit_swap and create_payment_link: a recipient, refundTo or pay-link `to` on the wrong chain is refused up front with 400 validation_error (error.issues names the field) and now says why, e.g. "recipient is not a valid Solana address. That's an EVM address (0x…) — this field needs a Solana address." An EVM address given for a Cardano, Starknet, Aleo, Dash or Fogo recipient or refundTo is refused too; it used to pass and price to nothing.
- POST /api/v1/quote: a quote with no route always says why. `errors` is never empty beside `routes: []` unless a priced prehop / posthop route stands in: when no provider supports the pair it holds one entry from provider "zerofee"; providers that had not answered by the deadline are listed in the 504 timeout's `partial.errors` ("did not answer within 15s"); a provider that failed with a blank message is listed instead of dropped; a failed temporary-wallet price is added when nothing else explains the empty list.
Removed
- Error code not_open (HTTP 503), which 3.1.0 added on POST /api/v1/swap and POST /api/v1/paylink and on the MCP tools create_deposit_swap and create_payment_link. Swap, pay-link and fund creation are open: those calls work as before 3.1.0.
API 3.1.0 · 2026-10-17
Before launch, creating swaps and pay links answers 503 not_open; quotes, status and the read-only endpoints are unchanged.
Added
- Error code not_open (HTTP 503) on POST /api/v1/swap and POST /api/v1/paylink, and from the MCP tools create_deposit_swap and create_payment_link, while ZeroFee finishes testing before launch: "ZeroFee opens soon — swaps and pay links are being tested." Nothing is created. GET /api/v1/chains, /tokens, /status, /health, /clock, /openapi.json and POST /quote, /payreq and /x402/fund answer as before.
API 3.0.0 · 2026-10-16
Funding several wallets is off for now: ZeroFee offers swaps and pay links. Create one swap per wallet instead.
Removed
- POST /api/v1/fund and POST /api/v1/fund/create now answer 404 not_found ("Funding several wallets isn't offered right now — create one swap per wallet with POST /api/v1/swap."). They are gone from GET /api/v1 and the OpenAPI document.
- MCP tools plan_wallet_funding and fund_wallets. The server now lists 9 tools; fund_x402_payment (one wallet, the exact amount an HTTP 402 asks for) is unchanged.
API 2.0.0 · 2026-10-16
Exchanges only for the Monero step: privacy "fast" is retired, and privacy "xmr" runs Exolix, then ChangeNOW, as the swap page does.
Changed
- privacy "xmr": the first exchange is Exolix and the second ChangeNOW (was Exolix and FixedFloat, either way round). FixedFloat is not used for any new swap or payment; status reads for older FixedFloat orders still work.
- notes (POST /api/v1/quote, privacy "standard"): when no bridge lists a pair but an exchange does, the note suggests privacy "xmr" instead of "fast".
- get_privacy_options (MCP) and GET /api/v1/ops privacy list: "fast" removed; "standard" now names the routes it really uses (NEAR Intents, Relay, and a two-step route through USDC).
Removed
- privacy "fast" (one instant exchange carrying the whole swap): POST /api/v1/quote and /swap, and the MCP tools, now refuse it with validation_error ("privacy \"fast\" is retired"). Use "standard", "private" or "xmr".
API 1.1.5 · 2026-10-16
Routes that create a FixedFloat order carry FixedFloat's own notice, as its terms require, and a rate-limited Relay reads as busy, not as no route. No request or response shape changed.
Changed
- privacy "xmr": "Below the minimum — send at least N" gives the first exchange's minimum rounded up to 4 significant digits (558.8 CELO, not 558.72291904), as the second exchange's already was.
- routes[].notes (POST /api/v1/quote, and the route in POST /api/v1/swap and the MCP tools): a route with a FixedFloat leg (provider "fixedfloat", or a Monero step whose route names FixedFloat) now includes "The exchange service is provided by FixedFloat. Creating an order confirms your agreement with the rules of FixedFloat." Show it to your user before they send.
Fixed
- errors[].error for Relay when it rate-limits (HTTP 429 "Please try again later") read "no route for this pair"; it now reads "busy right now — try again in a moment", like every other busy provider. Ask again; the pair does route.
- …except Relay's HTTP 500 "Could not execute swap. Please try again with a different amount or token pair.", which it gives every time for a pair it can't fill: it reads "can't fill this amount or pair — try a different amount", not busy.
API 1.1.4 · 2026-10-15
The Monero step refuses a refund address that is the recipient, which would show the first exchange both ends. No request or response shape changed.
Changed
- privacy "xmr", POST /api/v1/swap (and the MCP create tool): refundTo or hopRefunds.entry equal to the recipient is refused with validation_error. The first exchange is given the refund address, so it would see both your deposit and where the coins go. Give an address you pay from. A quote with the same addresses still prices, with a warning.
API 1.1.3 · 2026-10-15
NEAR Intents' minimum is only stated when it is proven, and a quote that is merely too small no longer suggests an exchange. No request or response shape changed.
Fixed
- errors[].error for a NEAR Intents minimum named a figure that wasn't always the minimum (DOGE → USDC on Solana: "send at least 0.46 DOGE" for 3 DOGE, which still fails). The figure is now given only when a dry quote at exactly it succeeds; otherwise the error reads "Below NEAR Intents' minimum for this pair — this amount is too small after its fees; try a larger amount" (a payment: "…this payment is too small after its fees"). Both are still code below_minimum on /swap.
- suggestedMinInput uses only figures that quoted, so it no longer suggests an amount NEAR Intents refuses (0.001 SOL → USDC on Solana suggested 0.001035 SOL; 0.002 SOL is still refused).
- privacy "standard": the note 'No bridge routes this pair right now. An instant exchange does …' no longer appears when a bridge refused only because the amount is under its minimum (it does route the pair; send more).
API 1.1.2 · 2026-10-15
A NEAR token address that looks like a ticker resolves, and a pair only an instant exchange lists gets one clear note. No request or response shape changed.
Changed
- privacy "standard", a pair no bridge lists but an instant exchange does: the note reads 'No bridge lists this pair. An instant exchange does: ask again with privacy "fast" …' instead of 'No provider supports this pair … check the chains and tokens' followed by the exchange note. Native NEAR (token "native" on near) is such a pair; through NEAR Intents, ask for token "wNEAR".
Fixed
- token "wrap.near" (and other NEAR account ids shaped like a ticker, e.g. "meta-pool.near") was refused with token_not_found although it is the listed address; a symbol still answers first, then the listed address.
API 1.1.1 · 2026-10-15
Clearer refusals while NEAR Intents pauses routes, price-only quotes to NEAR that work, and more chains. No request or response shape changed.
Added
- A privacy "standard" quote with no route adds a note when an instant exchange lists the pair: ask again with privacy "fast". "standard" itself stays bridges-only.
- Movement both ways (MOVE through an instant exchange, privacy "fast"); Lighter and Robinhood Lighter as destinations, with the recipient a numeric account index.
Changed
- errors[].error reads "paused by the provider right now — try again later" when NEAR Intents answers "Quoting for this pair is not available" (a route pause; it read "no route for this pair").
Fixed
- Quotes to or from wNEAR (NEAR's coin as NEAR Intents lists it) without a recipient / refundTo: the price-only placeholder was wrap.near, the wNEAR contract itself, which NEAR Intents refuses when it is the coin being priced. It is now a keyless implicit account; wrap.near is refused as a real address by /swap (400).
- QTC carries 12 decimals (was 8).
API 1.1.0 · 2026-10-15
Fund several wallets in one call, a ceiling on every payment quote, refund addresses for routes with a middle step, and stricter address checks. Additive: every 1.0.0 request still works.
Added
- POST /api/v1/fund/create and the MCP tool fund_wallets: plan a funding batch and reserve every wallet's own deposit address in one call (up to 20 wallets, 4 at a time).
- POST /api/v1/fund and the MCP tool plan_wallet_funding: price an exact amount of one coin to each of up to 20 wallets, paid from any coin.
- routes[].maxAmountIn on exact-output (payment) quotes: amountIn plus your slippage, rounded up. Pass it to /swap as maxAmountIn; passing amountIn exactly was refused by tiny price moves.
- hopRefunds in the request, routes[].refundsNeeded in quotes and the 400 refund_needed error: a route with a middle step (the Monero step, the two-step route) asks for your own refund address on the chain where that step runs, and reserves nothing until it has it.
- Provider twoleg: a two-step route through USDC or ETH on Base or Arbitrum, for pairs no single route serves (e.g. SOL to BNB).
- privacy "xmr" with amountOut: a private payment that delivers at least the amount (routes[].delivery "at_least" with cushionBps).
- suggestedMinInput.recommended: 5% above the providers' minimum, the amount to tell a user to send.
- A route answering privacy "private" without NEAR Intents' confidential mode says so in its notes.
- routes[].confidentialLeg: under privacy "private", the two-step route runs its NEAR Intents step confidentially and names it (e.g. "step 1 (NEAR Intents)"); the route stays confidential: false and its note says PARTLY confidential.
Changed
- The swap rate limit is 30 a minute (was 10), so a whole funding batch fits.
- Address fields accept up to 512 characters (was 200): a Zcash unified address with every receiver is about 213.
- Zcash unified addresses are checked in full (ZIP-316: checksum, padding, receivers); a mistyped one is a 400 instead of reaching a route.
- The same coin on the same chain for both sides is a 400 (nothing to swap).
- Every response carries security headers (no framing, no referrer, nosniff).
Fixed
- NEAR Intents' one-round "not enough liquidity" answer is asked again once before it becomes "no route".
- A FixedFloat order it doesn't know is a 404 not_found from /status, not "pending" forever.
- The two-step route re-prices both steps before reserving anything: a price drop since the quote is a refusal with nothing reserved, and the quote it returns carries the fresh amounts.
- POST /api/v1/fund/create (and fund_wallets) never runs past its time limit: a reservation starts only if it can finish, and wallets not started say so, to be retried on their own.
Removed
- The execute_in_app error code, which no endpoint returned.
API 1.0.0 · 2026-10-14
The API as it stood at the end of 14 October 2026: chains, tokens, quotes, deposit swaps, status, pay links, payment codes, x402 funding, live chain ETAs (/clock), health, the OpenAPI document and the MCP server.