# Uprally API: the full reference for AI agents and developers > Robinhood Chain coins, who's in them, and swaps and launches built for the user's own wallet to sign. Free, no key, non-custodial: every build is simulated against the chain and returned unsigned. Base URL: https://uprally.co/api/v1. Chain id 4663 (Robinhood Chain), currency ETH. This file is generated from the API's own description, error catalogue and docs, so it matches the live API. ## How a swap is found and checked ### Where a coin trades For any coin, the API gathers every way to trade it for ETH right now: - **Its launchpad curve.** A Pons coin trades on its own curve until it graduates; a Flap coin on Flap's portal. Priced in ETH. - **Uniswap pools.** V2, V3 and V4: the pools listed for it, and the pools Uprally's charts saw it trade in (so a coin minutes old, in no listing yet, still has its pool). Each is checked on chain: a V2 or V3 pool must come from Uniswap's own factory, a V4 pool's key must hash to its id. Pools on other exchanges are not routed. - **The way from ETH to the pool's currency.** Most Robinhood coins trade against USDG: the route goes ETH → USDG through the deepest ETH/USDG pools (both are tried). A coin priced in another coin or a stock token goes through that currency's own deepest pool, up to two currencies deep (ETH → USDG → NVDA → the coin, for example). ### The one that pays most Each candidate route is run as the exact transaction it would send, against the chain as it is now (an `eth_simulateV1` simulation), from your wallet when you send one. What you would end up with is read from the simulation, not worked out from a formula, so a pool's fee, a V4 hook's cut, a launchpad's snipe tax and a coin's own transfer tax are all already in `amountOut`. The route that leaves you with the most wins; `routesCompared` says how many were tried. ### The checks before it comes back - **The minimum is in the calldata.** `minOut` is `amountOut` less your `slippageBps` (default 100, 1%). The transaction reverts rather than give you less. - **Simulated again with that minimum,** and refused (`SIMULATION_FAILED`) if it would fail. - **A deadline.** A router swap reverts after `expiresAt` (10 minutes). - **The round trip.** A buy is followed, in the same simulation, by selling 99% of what it bought straight back, through the same route or any other. `sellBack` says what that returns. A coin that cannot be sold back through any route is refused (`HONEYPOT`). - **Price impact.** A trade that moves the price more than 50% is refused (`PRICE_IMPACT_TOO_HIGH`) unless you send `maxPriceImpactPct`. ### Which contract it calls - Pool routes: **Uniswap's Universal Router** (`GET /chain` → `contracts.universalRouter`). The router holds the money between pools and keeps none of it: each step spends everything it holds, and the last sends all of it to you. - A Pons coin on its curve: **that coin's curve contract**. A Flap coin on its curve: **Flap's portal**. Nothing goes through a contract of Uprally's. ### A sale quoted without your coins A sale quote without `wallet`, or for a wallet holding less than `amount`, is simulated from a test wallet given the coins in the simulation, or failing that from a real holder (`simulatedFrom` says which). A build always uses your wallet and your real balance. ## Approvals **A buy needs no approval.** It spends ETH, sent with the transaction. **A sale spends your coins**, so the contract that takes them must be allowed to. `POST /swap` checks your wallet's allowances and lists what is missing in `requires`, in order. Send each, wait for it to confirm, then send `tx` (or build again: the swap was simulated as if they were already in). | Route | Steps the first time | | |---|---|---| | Uniswap pool | `approve-permit2` | Lets Permit2 move this coin for you. Once per coin. | | | `permit2-allow-router` | Lets Uniswap's Universal Router take the coin through Permit2, for 30 days. | | Pons or Flap curve | `approve` | Lets the curve (Pons) or the portal (Flap) take the coins you sell, for that amount. | Permit2 (`0x000000000022d473030f116ddee9f6b43ac78ba3`) is Uniswap's shared approval contract: the same one Uniswap's own app uses. Both approvals are ordinary transactions; nothing is signed off chain. ## Fees ### A swap through a Uniswap pool - **The pool's own fee**, and a V4 hook's cut where the pool has one: already in `amountOut`. - **Uprally's fee**: 1% (`GET /chain` → `swaps.uprallyFeeBps`: 100) of the ETH in or out, to Uprally's treasury. Read it there rather than hard-coding it; every quote lists it in `fees.list`. - **Your fee**, if you add one: `feeBps` to `feeRecipient`, up to 300 (3%). See [Earn on the trades you bring](https://uprally.co/developers/quickstart/earn/). Every fee is paid in ETH, inside the same transaction: from the ETH going in on a buy (exact amounts, listed per fee), from the ETH coming out on a sale (a share of it). Never in the coin. ### A trade on a launchpad curve The launchpad's own fee (Pons and Flap charge on every curve trade) and any tax its creator set: already in `amountOut`. The trade goes straight to the launchpad's contract, which pays no one else, so **neither Uprally's fee nor yours is taken** (`fees.taken: false`). ### A coin's own tax Some coins (Flap's tax coins, for one) take a share of every transfer. It is in `amountOut` too, because every quote is a simulation of the real transfer. ### A launch `GET /launch` → `launchpads..fees`: what each launchpad's coins pay on every trade and how it is split (the creator, the launchpad, Uprally as the launch's referrer), and `launchCostEth`, what launching costs on top of gas. ### Gas Paid in ETH by the wallet that sends. Each `tx` comes with a `gas` limit with room: the chain's own estimate when nothing has to be sent first. ## Holders & risk `GET /coins/{address}/holders` is read from every transfer of the coin since its launch block, kept by Uprally's own recorder. The balances must add up to the coin's total supply on chain; when they don't, the answer is `{ "tracked": false, "reason": "incomplete" }`, never a partial list. **Coverage:** coins launched since 14 October 2026, on Pons, Flap, Doppler (Bankr, Long), Clanker and Pools.trade. An older coin answers `reason: "notFromLaunch"`. ### The groups - **Creator.** The wallet that signed the launch transaction. The launchpad's launcher contract named in the launch event (Flap's and Pons' launchers, Clanker's admin) counts as the same account. Its figures cover both; it is never in a group. - **Bundled.** A wallet that got more than 0.001% of the supply in the launch transaction itself (not the creator), or one of 3 or more wallets whose first buy landed in the same block within 600 blocks (about a minute) of the launch. - **Snipers.** A wallet whose first coins came from a buy within 30 blocks (about 3 seconds) of the launch block, and is not bundled. - **A group follows its coins.** A wallet that received coins by transfer from a group's wallet joins that group. - **Together.** 3 or more of a group whose last sale is the same transaction: only one controller can send that. `/holders/{group}` names it. Pools, launchpad curves, burn addresses and known lockers are never holders or group members; `list` labels them (`pool`, `curve`, `burn`, `locker`). ### The figures Every percentage is of the total supply: `boughtPct` (what the group got), `heldPct` (what it holds now), `burnedPct`. `top10Pct` is the ten biggest holders that are people, not pools. `curvePct` is what is still on the launchpad curve. ### Levels From the share a group **holds now**: | Group | `amber` from | `red` from | |---|---|---| | Bundled | 10% | 20% | | Snipers | 5% | 20% | Below amber, `plain`. ## Launchpads Every coin from these launchpads is in `/coins/new` and `/coins` as it launches, named in each coin's `launchpad`. | Launchpad | `launchpad` | How its coins trade | Launch through the API | |---|---|---|---| | Pons | `pons` | Its own curve per coin, in ETH, then a Uniswap V4 pool | yes | | Flap | `flap` | Flap's portal curve, then a Uniswap V2 pair | yes (needs a picture) | | Doppler | `doppler` | A Uniswap V4 pool with Doppler's hook | yes | | Bankr, Long | `bankr`, `long` | Doppler launches made through them | through `doppler` | | Clanker | `clanker` | A Uniswap V4 pool with Clanker's hook | yes | | Pools.trade | `poolstrade` | A Uniswap V4 pool | yes (no first buy) | Contracts on Robinhood Chain: | | Address | |---|---| | Pons factory | `0x7ed598bcef8bd9edd8c97a195c6d13f40801ec7e` | | Flap portal | `0x26605f322f7ff986f381bb9a6e3f5dab0beaeb09` | | Doppler airlock | `0xeb7c034704ef8dcd2d32324c1545f62fb4ad0862` | | Clanker factory | `0xd3f2cc1731b7fd17f28798835c2e02f0a1839a94` | | Pools.trade | `0x0000ffffbe8efe702c8703ae3477ff5de3d319c0`, `0x00004c4ccc709ef590f7c81102c0689f0263d4e9` | What a launch on each takes, costs and pays, live: `GET /launch`. ## Network, limits and errors ### Robinhood Chain | | | |---|---| | Chain id | `4663` | | Currency | ETH (18 decimals) | | Node | `https://rpc.mainnet.chain.robinhood.com` | | Explorer | `https://robin.etherscan.io` | `GET /chain` answers all of this, with every contract a swap touches (Uniswap's Universal Router, Permit2, the Uniswap factories, the launchpads), the current fees, and how far Uprally has read the chain (`data.indexedThroughBlock`, `data.stale`). Read it when your code starts. Every transaction the API builds carries `chainId` 4663; a wallet on another network refuses it, which is the point. There is no testnet: every answer is about real coins and real money. Quote and build freely (nothing is sent); send only what you mean to. ### Rate limits Per address, per minute: reads 300, quotes 120, swaps and launches 60, image uploads 20. Past one, `429 RATE_LIMITED` with `retry-after`. No key needed, no tiers. ### Errors Every error is one shape, with an HTTP status: ```json { "error": { "code": "NO_ROUTE", "message": "…", "fix": "…", "field": "amount", "detail": [] } } ``` Act on `code`: it never changes. `fix` says what to do; `field` names the input at fault. [Every code](https://uprally.co/developers/errors/), and live at `GET /api/v1/errors` with whether a retry can succeed. ### Amounts In: decimal strings in whole units (`"0.05"` ETH). Out: both, `{ "amount": "0.05", "wei": "50000000000000000" }`. Never JavaScript numbers for money. ## Every endpoint ### GET /chain Robinhood Chain: the contracts a swap or launch touches, the fees, and how far Uprally has read. Answer: - `chainId` (`4663`), required - `name` (string), required - `native` (object), required - `native.symbol` (`ETH`), required - `native.decimals` (`18`), required - `rpc` (string), required - `explorer` (string), required - `currencies` (object), required - `currencies.WETH` (string), required: A 0x address, lower case - `currencies.USDG` (string), required: A 0x address, lower case - `contracts` (object), required - `contracts.universalRouter` (string), required: Uniswap's Universal Router: every pool swap goes through it - `contracts.permit2` (string), required: A 0x address, lower case - `contracts.multicall3` (string), required: A 0x address, lower case - `contracts.uniswap` (object), required - `contracts.uniswap.v2Factory` (string), required: A 0x address, lower case - `contracts.uniswap.v3Factory` (string), required: A 0x address, lower case - `contracts.uniswap.v4PoolManager` (string), required: A 0x address, lower case - `contracts.uniswap.v4PositionManager` (string), required: A 0x address, lower case - `contracts.launchpads` (object), required - `contracts.launchpads.ponsFactory` (string), required: A 0x address, lower case - `contracts.launchpads.flapPortal` (string), required: A 0x address, lower case - `swaps` (object), required - `swaps.uprallyFeeBps` (integer), required: Uprally's fee on a pool swap, basis points - `swaps.maxBuilderFeeBps` (integer), required - `swaps.curveTradesPayFees` (boolean), required - `launches` (object), required - `launches.on` (boolean), required - `launches.launchpads` (string[]), required - `data` (object or null), required - `data.headBlock` (number or null), required - `data.indexedThroughBlock` (number or null), required - `data.stale` (boolean or null), required ### GET /coins Every coin with a market, sorted, with the figures the explore page shows. Parameters: - sort (query): Default volume (24 h) - limit (query): Default 50 - cursor (query): The `next` of the previous page - minHolders (query): Only coins with at least this many holders - maxBundledHeldPct (query): Only coins whose bundled wallets hold at most this % - maxSnipersHeldPct (query): Only coins whose snipers hold at most this % Answer: - `sort` (string), required - `total` (integer), required - `next` (integer or string or null), required: Send as cursor for the next page; null at the end - `leftOutUncounted` (integer or null), required: With a holder filter: coins left out because their holders were not counted from launch - `coins` (object[]), required - `coins[].address` (string), required: A 0x address, lower case - `coins[].name` (string or null), required - `coins[].ticker` (string or null), required - `coins[].image` (string or null), required - `coins[].launchpad` (string or null), required: pons, flap, doppler, bankr, long, clanker, poolstrade, or null - `coins[].stage` (string or null), required: curve: still on its launchpad curve; pool: trading in a pool - `coins[].createdAt` (string or null), required: ISO 8601 - `coins[].graduatedAt` (string or null), required: ISO 8601 - `coins[].marketCapUsd` (number or null), required: US dollars; null when not known - `coins[].change5mPct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].buys5m` (number or null), required - `coins[].buyers5m` (number or null), required - `coins[].volume5mUsd` (number or null), required: US dollars; null when not known - `coins[].volume24hUsd` (number or null), required: US dollars; null when not known - `coins[].trades24h` (number or null), required - `coins[].curve` (object or null), required - `coins[].curve.progress` (number or null), required: 0 to 1: how far to graduation - `coins[].curve.raisedUsd` (number or null), required: US dollars; null when not known - `coins[].curve.targetUsd` (number or null), required: US dollars; null when not known - `coins[].risk` (object or null), required - `coins[].risk.level` (string or null), required: green, amber or red - `coins[].risk.says` (string or null), required - `coins[].risk.unknown` (string[]), required - `coins[].holders` (object or null), required: From the launch block (only coins launched since 14 Oct 2026); null otherwise - `coins[].holders.count` (number or null), required - `coins[].holders.top10Pct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].holders.bundledHeldPct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].holders.snipersHeldPct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].holders.creatorHeldPct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].links` (object), required - `coins[].links.x` (string or null), required - `coins[].links.telegram` (string or null), required - `coins[].links.website` (string or null), required - `coins[].page` (string), required: The coin on uprally.co Errors: INVALID_QUERY. ### GET /coins/new Launches across every launchpad, newest first. Poll with `since`; page back with `before`. Parameters: - limit (query): Default 40 - since (query): Only coins launched after this time (the newest createdAt you have) - before (query): The `next` of the previous page Answer: - `coins` (object[]), required - `coins[].address` (string), required: A 0x address, lower case - `coins[].name` (string or null), required - `coins[].ticker` (string or null), required - `coins[].image` (string or null), required - `coins[].launchpad` (string or null), required: pons, flap, doppler, bankr, long, clanker, poolstrade, or null - `coins[].stage` (string or null), required: curve: still on its launchpad curve; pool: trading in a pool - `coins[].createdAt` (string or null), required: ISO 8601 - `coins[].graduatedAt` (string or null), required: ISO 8601 - `coins[].marketCapUsd` (number or null), required: US dollars; null when not known - `coins[].change5mPct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].buys5m` (number or null), required - `coins[].buyers5m` (number or null), required - `coins[].volume5mUsd` (number or null), required: US dollars; null when not known - `coins[].volume24hUsd` (number or null), required: US dollars; null when not known - `coins[].trades24h` (number or null), required - `coins[].curve` (object or null), required - `coins[].curve.progress` (number or null), required: 0 to 1: how far to graduation - `coins[].curve.raisedUsd` (number or null), required: US dollars; null when not known - `coins[].curve.targetUsd` (number or null), required: US dollars; null when not known - `coins[].risk` (object or null), required - `coins[].risk.level` (string or null), required: green, amber or red - `coins[].risk.says` (string or null), required - `coins[].risk.unknown` (string[]), required - `coins[].holders` (object or null), required: From the launch block (only coins launched since 14 Oct 2026); null otherwise - `coins[].holders.count` (number or null), required - `coins[].holders.top10Pct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].holders.bundledHeldPct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].holders.snipersHeldPct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].holders.creatorHeldPct` (number or null), required: Percent (5 means 5%); null when not known - `coins[].links` (object), required - `coins[].links.x` (string or null), required - `coins[].links.telegram` (string or null), required - `coins[].links.website` (string or null), required - `coins[].page` (string), required: The coin on uprally.co - `next` (string or null), required Errors: INVALID_QUERY. ### GET /coins/{address} One coin: its profile, market, launchpad curve, risk flags, contract checks and pools. Parameters: - address (path, required): The coin's contract address Answer: - `address` (string), required: A 0x address, lower case - `name` (string or null), required - `ticker` (string or null), required - `image` (string or null), required - `description` (string or null), required - `links` (object or null), required - `launchpad` (string or null), required - `createdAt` (string or null), required: ISO 8601 - `market` (object or null), required - `market.priceUsd` (number or null), required: US dollars; null when not known - `market.marketCapUsd` (number or null), required: US dollars; null when not known - `market.liquidityUsd` (number or null), required: US dollars; null when not known - `market.volume24hUsd` (number or null), required: US dollars; null when not known - `market.totalSupply` (number or null), required - `curve` (object or null), required - `curve.launchpad` (string or null), required - `curve.progress` (number or null), required - `curve.graduated` (boolean), required - `risk` (object or null), required - `risk.level` (string), required - `risk.reasons` ([]), required - `risk.unknown` (string[]), required - `contract` (object or null), required - `contract.sellable` - `contract.buyTaxBps` (number or null), required - `contract.sellTaxBps` (number or null), required - `pools` (object[]), required - `pools[].address` (string), required - `pools[].venue` (string or null), required - `pools[].version` (string), required - `pools[].liquidityUsd` (number or null), required: US dollars; null when not known - `page` (string), required Errors: INVALID_ADDRESS, UNKNOWN_COIN, DATA_UNREACHABLE. ### GET /coins/{address}/holders Holders & risk: every holder counted from the launch block, the creator, and the bundled and sniper groups with what they hold now. Parameters: - address (path, required): The coin's contract address Answer: Errors: INVALID_ADDRESS, DATA_UNREACHABLE. ### GET /coins/{address}/holders/{group} The wallets in one group (bundled or snipers), and whether 3 or more of them sold in one transaction. Parameters: - address (path, required): The coin's contract address - group (path, required): bundled or snipers Answer: - `wallets` (object[]), required - `wallets[].wallet` (string), required - `wallets[].boughtPct` (number or null), required: Percent (5 means 5%); null when not known - `wallets[].heldPct` (number or null), required: Percent (5 means 5%); null when not known - `together` (object or null), required: 3+ of the group sold in one transaction - `together.tx` (string), required - `together.wallets` (integer), required - `together.secs` (number), required Errors: INVALID_ADDRESS, UNKNOWN_GROUP, DATA_UNREACHABLE. ### GET /coins/{address}/candles Price candles in USD from every trade on chain, continuous (a quiet interval is flat). Parameters: - address (path, required): The coin's contract address - tf (query): Default 5m - limit (query): Default 300 - to (query): Unix seconds: the last candle; default now Answer: - `token` (string), required: A 0x address, lower case - `tf` (string), required - `stepSecs` (integer), required - `columns` (string[]), required - `candles` (number[][]), required - `more` (boolean), required - `indexedThroughBlock` (number or null), required Errors: INVALID_ADDRESS, INVALID_QUERY, DATA_UNREACHABLE. ### GET /coins/{address}/trades Its latest trades on every app (curve and pool), read from the chain. Parameters: - address (path, required): The coin's contract address Answer: - `token` (string), required: A 0x address, lower case - `trades` (object[]), required - `trades[].tx` (string), required - `trades[].at` (string), required - `trades[].block` (number), required - `trades[].side` (`buy` · `sell`), required - `trades[].trader` (string or null), required - `trades[].valueUsd` (number or null), required: US dollars; null when not known - `trades[].priceUsd` (number or null), required: US dollars; null when not known Errors: INVALID_ADDRESS, DATA_UNREACHABLE. ### GET /coins/{address}/traders Its traders by profit on it: bought, sold, held, realised and unrealised, in USD. Parameters: - address (path, required): The coin's contract address - limit (query): Default 20 Answer: - `token` (string), required: A 0x address, lower case - `traders` (object[]), required - `traders[].wallet` (string), required - `traders[].pnlUsd` (number or null), required: US dollars; null when not known Errors: INVALID_ADDRESS, INVALID_QUERY, DATA_UNREACHABLE. ### GET /coins/{address}/creator Who launched it, their other launches this week, and how they trade this coin and others. Parameters: - address (path, required): The coin's contract address Answer: - `creator` (string or null), required - `launchpad` (string or null), required Errors: INVALID_ADDRESS, UNKNOWN_CREATOR, DATA_UNREACHABLE. ### GET /wallets/{address} A wallet's profit and loss on Robinhood Chain coins: totals, per coin, recent trades. Parameters: - address (path, required): The wallet Answer: - `wallet` (string), required - `totals` (object), required - `coins` (object[]), required - `recent` (object[]), required Errors: INVALID_ADDRESS, DATA_UNREACHABLE. ### GET /smart-money Wallets that keep making money on Robinhood coins (bots left out), and what they bought lately. Parameters: - minutes (query): Buys in this window; default 60 - limit (query): Default 50 Answer: - `wallets` (object[]), required - `buys` (object[]), required Errors: INVALID_QUERY, DATA_UNREACHABLE. ### GET /top-traders The biggest winners right now: each wallet's best coin by profit among coins traded in the window. Parameters: - minutes (query): Default 60 - limit (query): Default 12 Answer: - `wallets` (object[]), required - `wallets[].wallet` (string), required - `wallets[].token` (string), required - `wallets[].pnlUsd` (number or null), required: US dollars; null when not known Errors: INVALID_QUERY, DATA_UNREACHABLE. ### GET /search Coins by name, ticker or address, across the whole chain. Parameters: - q (query, required): 1 to 64 characters Answer: - `q` (string), required - `coins` (object[]), required - `coins[].address` (string), required: A 0x address, lower case - `coins[].page` (string), required Errors: INVALID_QUERY. ### GET /quote What a buy or sale returns right now, simulated through every route it can take: sends nothing. Parameters: - token (query, required): The coin - side (query, required): buy: ETH for the coin; sell: the coin for ETH - amount (query, required): Whole units: ETH (buy) or coins (sell) - wallet (query): Quote for this wallet - slippageBps (query): Default 100 - feeBps (query): Your own fee, up to 300 - feeRecipient (query): Who gets feeBps - maxPriceImpactPct (query): Default 50 Answer: - `chainId` (`4663`), required - `token` (string), required: A 0x address, lower case - `symbol` (string or null), required - `side` (`buy` · `sell`), required - `amountIn` (object), required - `amountIn.amount` (string), required: Whole units, as a decimal string: "0.05" - `amountIn.wei` (string), required: The smallest unit, an integer as a string - `amountIn.symbol` (string or null), required: ETH, or the coin's ticker - `amountOut` (object), required: What the trader ends up with, after every fee and tax, simulated - `amountOut.amount` (string), required: Whole units, as a decimal string: "0.05" - `amountOut.wei` (string), required: The smallest unit, an integer as a string - `amountOut.symbol` (string or null), required: ETH, or the coin's ticker - `minOut` (object), required: The least the transaction accepts - `minOut.amount` (string), required: Whole units, as a decimal string: "0.05" - `minOut.wei` (string), required: The smallest unit, an integer as a string - `minOut.symbol` (string or null), required: ETH, or the coin's ticker - `slippageBps` (integer), required - `priceImpactPct` (number or null), required: Percent (5 means 5%); null when not known - `venue` (object or object), required - `venue.kind` (`curve`), required - `venue.launchpad` (`pons` · `flap`), required - `venue.contract` (string), required: A 0x address, lower case - `routesCompared` (integer), required - `fees` (object), required - `fees.taken` (boolean), required - `fees.list` (object[]), required - `fees.list[].who` (`uprally` · `builder`), required - `fees.list[].recipient` (string), required: A 0x address, lower case - `fees.list[].bps` (integer), required - `fees.why` (string) - `sellBack` (object) - `sellBack.ok` (`true`), required - `sellBack.sharePct` (number), required - `sellBack.eth` (object), required - `sellBack.eth.amount` (string), required: Whole units, as a decimal string: "0.05" - `sellBack.eth.wei` (string), required: The smallest unit, an integer as a string - `simulatedFrom` (`wallet` · `test wallet` · `holder`), required - `gasUsed` (string), required: The smallest unit, an integer as a string - `asOf` (string), required Errors: INVALID_ADDRESS, INVALID_SIDE, INVALID_AMOUNT, TOO_MANY_DECIMALS, INVALID_BPS, INVALID_QUERY, NOT_A_COIN, NO_ROUTE, QUOTE_NEEDS_WALLET, PRICE_IMPACT_TOO_HIGH, SIMULATION_FAILED, HONEYPOT, CHAIN_UNREACHABLE, MARKET_UNREACHABLE, RATE_LIMITED. ### POST /swap An unsigned swap for your wallet: the best route, simulated with its minimum, plus any approvals to send first. Body (JSON): - `token` (string), required: The coin - `side` (`buy` · `sell`), required - `amount` (string), required: Whole units: ETH to spend (buy) or coins to sell (sell) - `wallet` (string), required: A 0x address, lower case - `slippageBps` (integer) - `feeBps` (integer) - `feeRecipient` (string) - `maxPriceImpactPct` (number) Answer: - `chainId` (`4663`), required - `token` (string), required: A 0x address, lower case - `symbol` (string or null), required - `side` (`buy` · `sell`), required - `amountIn` (object), required - `amountIn.amount` (string), required: Whole units, as a decimal string: "0.05" - `amountIn.wei` (string), required: The smallest unit, an integer as a string - `amountIn.symbol` (string or null), required: ETH, or the coin's ticker - `amountOut` (object), required: What the trader ends up with, after every fee and tax, simulated - `amountOut.amount` (string), required: Whole units, as a decimal string: "0.05" - `amountOut.wei` (string), required: The smallest unit, an integer as a string - `amountOut.symbol` (string or null), required: ETH, or the coin's ticker - `minOut` (object), required: The least the transaction accepts - `minOut.amount` (string), required: Whole units, as a decimal string: "0.05" - `minOut.wei` (string), required: The smallest unit, an integer as a string - `minOut.symbol` (string or null), required: ETH, or the coin's ticker - `slippageBps` (integer), required - `priceImpactPct` (number or null), required: Percent (5 means 5%); null when not known - `venue` (object or object), required - `venue.kind` (`curve`), required - `venue.launchpad` (`pons` · `flap`), required - `venue.contract` (string), required: A 0x address, lower case - `routesCompared` (integer), required - `fees` (object), required - `fees.taken` (boolean), required - `fees.list` (object[]), required - `fees.list[].who` (`uprally` · `builder`), required - `fees.list[].recipient` (string), required: A 0x address, lower case - `fees.list[].bps` (integer), required - `fees.why` (string) - `sellBack` (object) - `sellBack.ok` (`true`), required - `sellBack.sharePct` (number), required - `sellBack.eth` (object), required - `sellBack.eth.amount` (string), required: Whole units, as a decimal string: "0.05" - `sellBack.eth.wei` (string), required: The smallest unit, an integer as a string - `simulatedFrom` (`wallet` · `test wallet` · `holder`), required - `gasUsed` (string), required: The smallest unit, an integer as a string - `asOf` (string), required - `wallet` (string), required: A 0x address, lower case - `requires` (object[]), required: Approvals to send first, in order; empty when the wallet is ready - `requires[].step` (string), required - `requires[].explain` (string), required - `requires[].tx` (object), required: An unsigned transaction: sign it with the wallet and send it. - `requires[].tx.chainId` (`4663`), required: Robinhood Chain - `requires[].tx.from` (string) - `requires[].tx.to` (string), required: A 0x address, lower case - `requires[].tx.data` (string), required: The call data: send it exactly as it is - `requires[].tx.value` (string), required: ETH to send with it, in wei - `requires[].tx.gas` (string) - `tx` (object), required: An unsigned transaction: sign it with the wallet and send it. - `tx.chainId` (`4663`), required: Robinhood Chain - `tx.from` (string) - `tx.to` (string), required: A 0x address, lower case - `tx.data` (string), required: The call data: send it exactly as it is - `tx.value` (string), required: ETH to send with it, in wei - `tx.gas` (string) - `expiresAt` (string or null), required: A router swap reverts after this - `checks` (object), required - `checks.minimumInCalldata` (`true`), required - `checks.simulated` (`true`), required Errors: INVALID_ADDRESS, INVALID_SIDE, INVALID_AMOUNT, TOO_MANY_DECIMALS, INVALID_BPS, INVALID_QUERY, NOT_A_COIN, NO_ROUTE, QUOTE_NEEDS_WALLET, PRICE_IMPACT_TOO_HIGH, SIMULATION_FAILED, HONEYPOT, CHAIN_UNREACHABLE, MARKET_UNREACHABLE, RATE_LIMITED, WALLET_REQUIRED, INSUFFICIENT_BALANCE, INSUFFICIENT_FUNDS, INVALID_BODY, INVALID_JSON. ### GET /tx/{hash} Where a transaction is: unknown, pending, confirmed or reverted. Parameters: - hash (path, required): The transaction hash Answer: - `hash` (string), required - `state` (`unknown` · `pending` · `confirmed` · `reverted`), required - `explorer` (string), required Errors: INVALID_HASH, CHAIN_UNREACHABLE. ### GET /launch What each launchpad takes (supply, options, picture) and what a launch on it costs and pays. Answer: - `on` (boolean), required - `chainId` (`4663`), required - `maxFirstBuyEth` (number), required - `launchpads` (object), required ### POST /launch The unsigned steps of a launch on Doppler, Clanker, Pools.trade, Flap or Pons: the coin's details stored, the launch simulated. Body (JSON): - `launchpad` (string), required: One of GET /launch's launchpads: doppler, clanker, poolstrade, flap, pons - `creator` (string), required: The wallet that signs and owns the launch - `name` (string), required: 1 to 32 characters - `symbol` (string), required: 1 to 10 letters or digits - `description` (string) - `image` (string) - `links` (object) - `links.x` (string) - `links.telegram` (string) - `links.website` (string) - `firstBuyEth` (number) - `options` (object) - `metadataURI` (string) Answer: - `launchpad` (string), required - `chainId` (`4663`), required - `creator` (string), required: A 0x address, lower case - `token` (string), required: The coin's address, known before it is sent - `metadataURI` (string), required - `steps` (object[]), required: Send in order, each confirmed before the next - `steps[].step` (string), required - `steps[].tx` (object), required: An unsigned transaction: sign it with the wallet and send it. - `steps[].tx.chainId` (`4663`), required: Robinhood Chain - `steps[].tx.from` (string) - `steps[].tx.to` (string), required: A 0x address, lower case - `steps[].tx.data` (string), required: The call data: send it exactly as it is - `steps[].tx.value` (string), required: ETH to send with it, in wei - `steps[].tx.gas` (string) - `page` (string), required Errors: INVALID_ADDRESS, INVALID_BODY, INVALID_LAUNCH, INVALID_DETAILS, LAUNCH_WOULD_FAIL, LAUNCH_OFF, UPLOADS_BUSY, RATE_LIMITED. ### POST /media/image A picture for a launch: the raw image bytes as the body (PNG, JPEG, GIF or WebP, up to 5 MB). Answers its link. Body: the raw image bytes, Content-Type image/png, image/jpeg, image/gif or image/webp, up to 5 MB. Answer: - `image` (string), required Errors: UNSUPPORTED_IMAGE, IMAGE_TOO_LARGE, INVALID_DETAILS, UPLOADS_BUSY, RATE_LIMITED. ### GET /creators/{address}/fees What each coin a wallet launched has earned it in trading fees, and the transactions that claim it. Parameters: - address (path, required): The creator's wallet Answer: - `wallet` (string), required: A 0x address, lower case - `coins` (object[]), required - `coins[].token` (string), required: A 0x address, lower case - `coins[].launchpad` (string), required - `coins[].owed` (object), required - `coins[].owed.eth` (object or null), required - `coins[].owed.token` (object or null), required - `coins[].steps` (object[]), required - `coins[].steps[].step` (string), required - `coins[].steps[].tx` (object), required: An unsigned transaction: sign it with the wallet and send it. Errors: INVALID_ADDRESS, INVALID_LAUNCH. ### GET /errors Every error code: what it means, the fix, and whether retrying can succeed. Answer: - `errors` (object[]), required - `errors[].code` (string), required - `errors[].status` (integer), required - `errors[].meaning` (string), required - `errors[].fix` (string), required - `errors[].retry` (boolean), required ## Every error Every error is `{ "error": { "code", "message", "fix"?, "field"?, "detail"? } }`. Act on `code`. "retry": the same request can succeed later. - BODY_TOO_LARGE (HTTP 413): The body is larger than the limit (64 KB of JSON, 5 MB for an image). Fix: Send only the fields the endpoint takes. - CHAIN_UNREACHABLE (HTTP 503, retry): Robinhood Chain could not be read or simulated just now. Fix: Retry in a few seconds. - DATA_UNREACHABLE (HTTP 503, retry): The data behind this answer could not be read just now. Fix: Retry in a few seconds. - HONEYPOT (HTTP 422): Selling this coin straight after buying it fails through every route, in simulation: it may not be sellable. Fix: Do not buy it. GET /coins/{address} shows what is known. - IMAGE_TOO_LARGE (HTTP 413): The image is larger than 5 MB. Fix: Send a smaller image. - INSUFFICIENT_BALANCE (HTTP 422): The wallet holds less of the coin than the sale. Fix: Sell at most what the wallet holds. - INSUFFICIENT_FUNDS (HTTP 422): The wallet holds less ETH than the buy. Fix: Spend less, or add ETH (it also pays gas). - INTERNAL (HTTP 500, retry): Something failed on our side; nothing was sent. Fix: Retry; if it persists, tell us the time and the request. - INVALID_ADDRESS (HTTP 400): A field that must be a 0x address is not one; `field` says which. Fix: Send a 40-hex-digit address starting with 0x. - INVALID_AMOUNT (HTTP 400): The amount is not a positive decimal in whole units. Fix: Send a decimal string such as "0.05" (ETH for a buy, the coin for a sale), not wei. - INVALID_BODY (HTTP 400): The body is not a JSON object. Fix: Send Content-Type: application/json and a JSON object. - INVALID_BPS (HTTP 400): slippageBps or feeBps is out of range (basis points: 100 = 1%). Fix: slippageBps: 1 to 5000. feeBps: 0 to 300, with feeRecipient. - INVALID_DETAILS (HTTP 400): A coin detail (name, ticker, description, picture or link) is not accepted; `field` says which. Fix: Fix the field named. A picture must come from POST /media/image. - INVALID_HASH (HTTP 400): That is not a transaction hash. Fix: Send the 0x-prefixed 64-hex-digit hash your wallet returned. - INVALID_JSON (HTTP 400): The body is not valid JSON. Fix: Send Content-Type: application/json and valid JSON. - INVALID_LAUNCH (HTTP 400): A launch field is missing or wrong; `field` says which. Fix: Fix the field named and send it again (GET /launch lists each launchpad's options). - INVALID_QUERY (HTTP 400): A query parameter is out of range or malformed; `field` says which. Fix: Send it as the message says, or leave it out for the default. - INVALID_SIDE (HTTP 400): side is "buy" (ETH for the coin) or "sell" (the coin for ETH). Fix: Send side=buy or side=sell. - LAUNCH_OFF (HTTP 503, retry): Launching is switched off on this server for now. Fix: Try again later. - LAUNCH_WOULD_FAIL (HTTP 422): The launch reverted when simulated. Fix: Change the first buy or the options, then build again. - MARKET_UNREACHABLE (HTTP 503, retry): The coin's pools could not be read just now. Fix: Retry in a few seconds. - NO_ROUTE (HTTP 422, retry): No pool or curve can make this trade right now (none known, or every one failed in simulation; `detail` lists them). Fix: Try a smaller amount; a coin minutes old may have no pool yet. - NOT_A_COIN (HTTP 400): The token address is not an ERC-20 on Robinhood Chain. Fix: Send the coin's contract address. - NOT_FOUND (HTTP 404): There is no such endpoint. Fix: GET /api/v1 lists every endpoint. - PRICE_IMPACT_TOO_HIGH (HTTP 422): The trade would move the price more than maxPriceImpactPct (default 50%): the pool is too thin for it. Fix: Trade less, or send maxPriceImpactPct (up to 100) to allow it. - QUOTE_NEEDS_WALLET (HTTP 422): This coin's sale can only be quoted from a wallet that holds it. Fix: Send `wallet`: an address holding at least `amount` of the coin. - RATE_LIMITED (HTTP 429, retry): Too many requests from this address in the last minute. Fix: Wait (the retry-after header says how long) and slow the loop. Per minute: reads 300, quotes 120, swaps and launches 60, uploads 20. - SIMULATION_FAILED (HTTP 422, retry): The trade failed when simulated again with its minimum in place: the price moved. Fix: Retry, or allow more slippage (slippageBps). - TOO_MANY_DECIMALS (HTTP 400): The amount has more decimal places than the currency has. Fix: Round it to the currency's decimals (18 for ETH and most coins). - UNKNOWN_COIN (HTTP 404): The address has no market, launchpad or curve on Robinhood Chain. Fix: Check the address: GET /coins lists every coin with a market. - UNKNOWN_CREATOR (HTTP 404): Nobody we know of launched this coin: it was not made on a launchpad we read. Fix: GET /coins/{address} shows its launchpad. - UNKNOWN_GROUP (HTTP 404): A holder group is bundled or snipers. Fix: Ask /holders/bundled or /holders/snipers. - UNSUPPORTED_IMAGE (HTTP 415): The body is not a PNG, JPEG, GIF or WebP image. Fix: Send the raw image bytes with Content-Type image/png, image/jpeg, image/gif or image/webp. - UPLOADS_BUSY (HTTP 429, retry): Uploads are busy right now. Fix: Try again in a few minutes. - WALLET_REQUIRED (HTTP 400): A swap is built for the wallet that will send it. Fix: Send `wallet`. ## Every page on the site - [Uprally](https://uprally.co/) - [Launch a coin](https://uprally.co/launch): Launch on Doppler, Clanker, Pools.trade, Flap or Pons from one page, with a first buy in the launch, and claim what it earns you here. - [Explore](https://uprally.co/explore): Every token on Robinhood Chain, from every launchpad, as it launches and climbs. - [Is this token safe? Free Robinhood Chain honeypot check](https://uprally.co/safe): Paste any Robinhood Chain token: we simulate a buy and a sale against its live pool and read its contract. Free, no sign-in. - [What Uprally is](https://uprally.co/docs/why-market-mayhem): The people’s trading floor on Robinhood Chain. - [Get ETH onto Robinhood Chain](https://uprally.co/docs/get-eth): From Base, Arbitrum, Ethereum or an exchange. - [Read a coin before you buy](https://uprally.co/docs/read-a-coin): Who holds it, in four numbers: holders, the creator, bundled wallets and snipers. - [Launching a coin](https://uprally.co/docs/launching-a-token): On any launchpad, from one page. - [Your creator fees](https://uprally.co/docs/creator-fees): Launched a coin? Claim what it earned. - [How we make money](https://uprally.co/docs/how-we-make-money): Every fee we take, shown before you sign. - [Common questions](https://uprally.co/docs/faq): Yes or No first. - [How it works](https://uprally.co/docs): Find every coin on Robinhood Chain, see who holds it before you buy, trade it, and launch your own on any launchpad. - [Terms of Use](https://uprally.co/terms): The agreement between you and Uprally when you use this site. - [Privacy Policy](https://uprally.co/privacy): What data Uprally handles, why, and what you can do about it. ## Every page of the developer docs - [Start here](https://uprally.co/developers/): Robinhood Chain coins, who's in them, and swaps and launches built for your own wallet to sign. Free, no key, every build simulated. - [Approvals](https://uprally.co/developers/concepts/approvals/): What a sale needs approved first, once, and why a buy needs nothing. - [Fees](https://uprally.co/developers/concepts/fees/): What a swap or a launch pays, to whom, and where each figure is in the answer. - [Holders & risk](https://uprally.co/developers/concepts/holders-and-risk/): How holders, the creator, bundled wallets and snipers are counted, and what each level means. - [Launchpads](https://uprally.co/developers/concepts/launchpads/): The Robinhood Chain launchpads Uprally reads, the ones you can launch on, and their contracts. - [Network, limits and errors](https://uprally.co/developers/concepts/network/): Robinhood Chain, the contracts a swap touches, how fresh the data is, rate limits, and the one error shape. - [How a swap is found and checked](https://uprally.co/developers/concepts/swaps/): Every route a coin trades on, simulated; the one that pays most; the minimum, the deadline and the round trip. - [Errors](https://uprally.co/developers/errors/): Every error code the API can answer with, what it means, and the fix. - [A creator's fees, and the claims](https://uprally.co/developers/examples/creator-fees-mjs/): What the coins a wallet launched have earned it, and the transactions that claim it. Sends nothing. - [Launch a coin](https://uprally.co/developers/examples/launch-mjs/): Launch a coin on Doppler, Clanker, Pools.trade, Flap or Pons from your own wallet. The API stores its details, builds the launch and simulates it; your key signs each step. Without SEND=1 it only builds and prints the steps. - [The newest launches (curl)](https://uprally.co/developers/examples/new-coins-sh/): The newest launches on every Robinhood Chain launchpad, with who holds them. - [Quote a buy (JavaScript)](https://uprally.co/developers/examples/quote-mjs/): What 0.001 ETH buys of a coin right now, simulated through every route it trades on. Sends nothing. - [Quote a buy (Python)](https://uprally.co/developers/examples/quote-py/): What 0.001 ETH buys of a coin right now, simulated through every route it trades on. Sends nothing. - [Read a coin: holders, risk, chart](https://uprally.co/developers/examples/read-a-coin-mjs/): Everything Uprally knows about one coin: its market, who holds it, the bundled and sniper wallets, its creator and its last hour of 5-minute candles. Sends nothing. - [Buy or sell from your wallet](https://uprally.co/developers/examples/swap-mjs/): Buy or sell a coin from your own wallet. The API finds the best route and simulates the exact transaction; your key signs it here and never leaves this process. Without SEND=1 it only builds and prints. - [Watch every new launch](https://uprally.co/developers/examples/watch-new-coins-mjs/): Every new launch on Robinhood Chain as it lands, polled every 3 seconds. Prints each with its launchpad. - [Earn on the trades you bring](https://uprally.co/developers/quickstart/earn/): Add your own fee to every swap your app, bot or agent builds, paid in ETH in the same transaction. - [Your first swap](https://uprally.co/developers/quickstart/first-swap/): Quote a buy, build it for your wallet, send it; then sell, with the one-time approvals a sale needs. - [Launch a coin](https://uprally.co/developers/quickstart/launch/): On Doppler, Clanker, Pools.trade, Flap or Pons, from your own wallet, with a first buy in the launch; then claim what it earns you. - [A bot that buys new launches](https://uprally.co/developers/quickstart/new-launches-bot/): Every launch as it lands, filtered by who holds it, bought within the limits you set. - [Read a coin: holders, risk, chart](https://uprally.co/developers/quickstart/read-a-coin/): One coin's market, risk flags, every holder from its launch, the bundled and sniper wallets, its creator and its candles. - [A launch buyer with limits](https://uprally.co/developers/recipes/launch-buyer/): A bot that buys new launches, within limits you set: only coins whose bundled wallets and snipers hold little, a fixed amount each, at most MAX_BUYS, never a coin whose round trip loses more than MAX_ROUND_TRIP_LOSS_PCT. - [GET /chain](https://uprally.co/developers/reference/get-chain/): Robinhood Chain: the contracts a swap or launch touches, the fees, and how far Uprally has read. - [GET /coins/{address}/candles](https://uprally.co/developers/reference/get-coins-address-candles/): Price candles in USD from every trade on chain, continuous (a quiet interval is flat). - [GET /coins/{address}/creator](https://uprally.co/developers/reference/get-coins-address-creator/): Who launched it, their other launches this week, and how they trade this coin and others. - [GET /coins/{address}/holders/{group}](https://uprally.co/developers/reference/get-coins-address-holders-group/): The wallets in one group (bundled or snipers), and whether 3 or more of them sold in one transaction. - [GET /coins/{address}/holders](https://uprally.co/developers/reference/get-coins-address-holders/): Holders & risk: every holder counted from the launch block, the creator, and the bundled and sniper groups with what they hold now. - [GET /coins/{address}/traders](https://uprally.co/developers/reference/get-coins-address-traders/): Its traders by profit on it: bought, sold, held, realised and unrealised, in USD. - [GET /coins/{address}/trades](https://uprally.co/developers/reference/get-coins-address-trades/): Its latest trades on every app (curve and pool), read from the chain. - [GET /coins/{address}](https://uprally.co/developers/reference/get-coins-address/): One coin: its profile, market, launchpad curve, risk flags, contract checks and pools. - [GET /coins/new](https://uprally.co/developers/reference/get-coins-new/): Launches across every launchpad, newest first. Poll with `since`; page back with `before`. - [GET /coins](https://uprally.co/developers/reference/get-coins/): Every coin with a market, sorted, with the figures the explore page shows. - [GET /creators/{address}/fees](https://uprally.co/developers/reference/get-creators-address-fees/): What each coin a wallet launched has earned it in trading fees, and the transactions that claim it. - [GET /errors](https://uprally.co/developers/reference/get-errors/): Every error code: what it means, the fix, and whether retrying can succeed. - [GET /launch](https://uprally.co/developers/reference/get-launch/): What each launchpad takes (supply, options, picture) and what a launch on it costs and pays. - [GET /quote](https://uprally.co/developers/reference/get-quote/): What a buy or sale returns right now, simulated through every route it can take: sends nothing. - [GET /search](https://uprally.co/developers/reference/get-search/): Coins by name, ticker or address, across the whole chain. - [GET /smart-money](https://uprally.co/developers/reference/get-smart-money/): Wallets that keep making money on Robinhood coins (bots left out), and what they bought lately. - [GET /top-traders](https://uprally.co/developers/reference/get-top-traders/): The biggest winners right now: each wallet's best coin by profit among coins traded in the window. - [GET /tx/{hash}](https://uprally.co/developers/reference/get-tx-hash/): Where a transaction is: unknown, pending, confirmed or reverted. - [GET /wallets/{address}](https://uprally.co/developers/reference/get-wallets-address/): A wallet's profit and loss on Robinhood Chain coins: totals, per coin, recent trades. - [POST /launch](https://uprally.co/developers/reference/post-launch/): The unsigned steps of a launch on Doppler, Clanker, Pools.trade, Flap or Pons: the coin's details stored, the launch simulated. - [POST /media/image](https://uprally.co/developers/reference/post-media-image/): A picture for a launch: the raw image bytes as the body (PNG, JPEG, GIF or WebP, up to 5 MB). Answers its link. - [POST /swap](https://uprally.co/developers/reference/post-swap/): An unsigned swap for your wallet: the best route, simulated with its minimum, plus any approvals to send first.