For integrators

Link in, read out.

Two things other sites, wallets and bots can use today: a link that opens Nero with the token and amount already filled in, and the public numbers as JSON. There is no key and no sign-up. How the exits themselves work is in the Paper.

Send someone to the swap page with the token and amount set. They paste their own Monero address, check the quote and sign. Everything is optional; a bare /swap opens the private exit on SOL.

https://www.neroswap.app/swap?in=<token address>&amount=<amount>&tab=<tab>
inThe token to exit from, as its Solana address. Understood today: SOL So11111111111111111111111111111111111111112, USDC EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v, USDT Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB. Any other value is ignored and the page opens on SOL; every other token is one tap away in the page's own token list.
amountHow much of that token, in whole units: 1, 0.5, 250. Digits and at most one dot. Anything else is ignored.
tabprivate (the default, paid by our solver), exit (the standard exit through the wXMR bridge, for larger amounts) or enter (Monero into Solana).

Examples

https://www.neroswap.app/swap?in=So11111111111111111111111111111111111111112&amount=1
https://www.neroswap.app/swap?in=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=250
https://www.neroswap.app/swap?tab=exit&in=So11111111111111111111111111111111111111112&amount=30

Try them: 1 SOL, 250 USDC, 30 SOL on the standard exit.

There is no parameter for the Monero address, and there will not be one. A link must never be able to choose where someone's money goes, so the address is always typed or pasted by the person themselves. If a link claims to fill it in, it is not ours.

Reading the numbers

Every address below is a plain GET on https://www.neroswap.app and answers in JSON. A few rules cover all of them:

  • Amounts are whole numbers sent as text, in the smallest unit. A field ending in Pico is XMR: divide by 1,000,000,000,000. SOL is in lamports: divide by 1,000,000,000.
  • Times are Unix seconds, UTC.
  • Errors come back as { "error": "…" } with a 4xx or 5xx status. A 502 or 503 means that part is not answering right now; the status page shows the same thing.
  • Call from your server. Browsers on other sites are not allowed to read these addresses directly.
  • Ask at most twice a minute. The numbers do not move faster than that, and the totals are cached for about 20 seconds anyway.
  • Fields may be added over time. Ignore the ones you do not know.

Totals

GET/api/stats

Everything on the home page in one call: prices, the private exit's running totals and our Monero node. solver.xmrPico is all XMR paid on private exits so far, solver.reservePico is the XMR in the solver's wallet, and node is our node as the solver reads it.

{
  "wxmrSupply": "3209487611904223",
  "xmrUsd": 524.79,
  "solUsd": 109.69,
  "solver": {
    "exits": 2,
    "xmrPico": "62680603749",
    "refunds": 0,
    "reservePico": "4248146712348",
    "enabled": true,
    "lastPaidAt": 1791597875
  },
  "node": {
    "height": 3790812,
    "targetHeight": 3790812,
    "synchronized": true,
    "topBlockHash": "aa39ebf55a4b1ec35bd2a64be2f273362882eddf664f32b4cd2580d66a81e585",
    "walletHeight": 3790812,
    "at": 1792813309
  }
}

Private exit

GET/api/v2/info

Whether the private exit is open, and its limits right now. minPico and maxPico are the smallest and largest single order, availablePico is the most it can pay this minute, spreadBps is the fee in hundredths of a percent (60 is 0.6%), and quoteTtl is how many seconds a wallet quote is held. Without a wallet connection the fee is addrFeeBps (90 is 0.9%) and the order is locked for addrTtl seconds (900 is 15 minutes).

{
  "version": "3f1c2a9d0b7e",
  "enabled": true,
  "deposit": "5GDP6viv4mK1XE2RBtdLoz3ct65YFjq6yfFoqXBi7bbk",
  "boxPub": "l0meX+p6q/5U+TC5qoqbTZLttsYxSrqy8EPjXZGyhTA=",
  "spreadBps": 60,
  "quoteTtl": 60,
  "minPico": "10000000000",
  "maxPico": "500000000000",
  "availablePico": "500000000000",
  "addrFeeBps": 90,
  "addrTtl": 900
}

GET/api/v2/estimate?amount=1000000000

What an amount of SOL gets in XMR on the no-wallet route, fees included. amount is in lamports, so this example asks about 1 SOL. feeBps is 90 (0.9%); a connected wallet pays 0.6% and gets slightly more. It is a price, not a reservation: nothing is held until someone creates an order on the swap page, and ttl is how many seconds that order would then be locked for.

{
  "lamports": "1000000000",
  "xmrOut": "206393255024",
  "feeBps": 90,
  "ttl": 900
}

GET/api/v2/stats

The solver part of the totals on its own, uncached. Private exits are published as running totals only, never per order and never per day, so no single exit can be picked out by its date and size.

Our Monero node

GET/api/node

Our node's height and top block hash, and the same block as a public Monero node we do not run sees it. reference.match is true when both have the same block at that height, which means our node is on the real Monero chain. This is what the Verify page shows.

{
  "ours": {
    "height": 3790812,
    "targetHeight": 3790812,
    "synchronized": true,
    "topBlockHash": "aa39ebf55a4b1ec35bd2a64be2f273362882eddf664f32b4cd2580d66a81e585",
    "walletHeight": 3790812,
    "at": 1792813309
  },
  "reference": {
    "node": "node.sethforprivacy.com",
    "height": 3790812,
    "hashAtOurTop": "aa39ebf55a4b1ec35bd2a64be2f273362882eddf664f32b4cd2580d66a81e585",
    "match": true
  }
}

Token search

GET/api/tokens?q=USDC

The lookup behind the swap page's token list: search by name or ticker, or pass a token address. Up to eight matches with name, ticker, decimals and icon. verified is the token list's own mark, not ours; tickers are not unique, so match on mint.

[
  {
    "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "symbol": "USDC",
    "name": "USD Coin",
    "decimals": 6,
    "icon": "https://…/logo.png",
    "verified": true
  }
]

What is not offered

  • No address that builds an exit for you. An exit is made on neroswap.app, where the page seals the Monero address in the person's own browser and checks the transaction before their wallet sees it. Handing that to another site would remove both checks, so use the link.
  • No per-order data for private exits. Totals only, on purpose.
  • No referral fee today. If that changes it will be written here first.

Building something on top of this, or missing a number? Open an issue on GitHub. The same facts in a form made for language models are at /llms.txt.