Integrate
Integrate Robin Hook
Let your users launch, buy and sell from your own app: unsigned transactions with quotes and simulation.
Your app can let its users launch, buy and sell Robin Hook tokens without sending them to robinhook.lol. The transaction API works out the exact calls the Robin Hook site would make and hands them back unsigned: your user signs them in their own wallet, in your interface. Robin Hook never holds keys or funds and never sends anything for anyone.
Earn on the trades you bring
referrer. On tokens that run the Referral hook, a share of every buy you route goes to that address, paid by the hook on-chain.How it works
- Your app sends what the user wants (a trade or a launch) with the user's address as
from. - The API reads the chain: is the token on its curve or in its Uniswap v4 pool, what does the amount return right now, which approvals are missing, is the signed price fresh enough.
- It answers with
steps: the transactions to send, in order, each with a plain-Englishdescription. A slippage floor from the live quote is written into every trade. - When nothing has to happen first, the final step is simulated from
from(aneth_call). A trade or launch that would revert is refused with the reason instead of being returned. - Your app shows the descriptions, the user signs, you send the steps one by one.
Rules
- Base URL
https://robinhook.lol/api/v1. No key and no sign-up. CORS is open, so a browser on your domain can call it directly. - Amounts are decimal strings in whole units (
"1.5"ETH,"1000"tokens). Raw values come back too, as…Rawfields. - Robinhood Chain only (
chainId4663, on every answer). Tokens launched on Robin Hook v2. - Rate limits per IP: quotes 60 a minute, trade transactions 30, launch transactions 10. Above that, HTTP 429 with a
retry-afterheader. Bodies over 16 KB are refused. - Answers to
/tx/*are never cached: ask again right before your user signs.
Quote
GET /api/v1/quote?token=0x…&side=buy|sell&amount=1.5[&from=0x…]
What amount returns right now: the quote asset in for a buy, the token in for a sell. On the curve the quote runs every hook (cuts, extra fees, refusals) through the lens contract, for from when you pass it. In the pool it comes from Uniswap's V4 quoter. When a hook would refuse the trade, refused holds the reason. Cached 5 seconds.
Buy or sell
POST /api/v1/tx/trade
{ "token": "0x…", "side": "buy", "amount": "0.05", "from": "0x…",
"slippageBps": 300, "referrer": "0x…" }| Field | Meaning |
|---|---|
token | The Robin Hook token. |
side | buy pays the token's quote asset (ETH, USDG, HOOK, a stock…); sell pays the token. |
amount | What is paid, in whole units. |
from | The wallet that will sign. Its balance and approvals are checked, and the trade is simulated from it. |
slippageBps | Optional, 10 to 5000. Default 100 (1%) on the curve, 300 (3%) in a pool, as on the site. |
referrer | Optional: your address, for tokens with the Referral hook. |
Before graduation the trade goes to the launchpad (buyWithData / sellWithData); after, to the Robin Hook router (buy / sell, with a 10-minute deadline). An ERC-20 buy, or a sell in the pool, may need an approve first: it comes back as the first step, for the exact amount. Once it is mined, ask again.
{
"chainId": 4663,
"from": "0x7149…614d",
"token": { "address": "0x898D…8Dc7", "symbol": "HOOK" },
"quoteAsset": { "address": "0x0000…0000", "symbol": "ETH", "decimals": 18 },
"venue": "pool", // "curve" before graduation, "pool" after
"side": "buy",
"amountIn": "0.05",
"amountOut": "15004.159…", // live quote
"slippageBps": 300,
"minAmountOut": "14554.034…", // the floor written into the transaction
"referrer": null,
"deadline": 1791468918, // pool trades only
"steps": [
{ "kind": "buy", "description": "Buy at least 14554.03 HOOK for 0.05 ETH",
"to": "0xC8B2…651a", "data": "0xa3fb5bee…", "value": "50000000000000000" }
],
"simulation": { "ok": true, "reason": null }
}Launch
POST /api/v1/tx/launch
{
"from": "0x…",
"name": "My Token",
"symbol": "MYT",
"description": "…",
"image": "https://…/logo.png", // https only, hosted by you
"quote": "0x0000000000000000000000000000000000000000", // ETH (default)
"creatorFeeBps": 100, // 1%
"modules": [
{ "id": 2, "config": { "burnBps": "1.5" } }, // Auto burn 1.5% of every buy
{ "id": 19 } // Nth-buy pot, all defaults
],
"devBuy": "0.5" // optional first buy, in the quote asset
}Hooks are chosen by id from the hook catalog (GET /api/hooks/catalog, only active ones). Each hook's config uses the param keys of its catalog entry, in the param's display unit: percent for bps and supplyBps, whole quote units for quote, whole tokens for tokens, and minutes, hours or days as named. A param you leave out takes its default. Values are checked against the same bounds as the launch form, then the hook validates them again on-chain. At most 8 hooks.
The value to send is the launch fee, plus the first buy when the quote is ETH. Tokens paired with a stock or another signed-price coin may need a priceUpdate step first (a price signed by Robin Hook's price service, checked by the feed contract). The new token's address is in the TokenLaunched event of the launch receipt.
Signing with viem
import { createWalletClient, custom, defineChain } from 'viem';
const robinhoodChain = defineChain({
id: 4663,
name: 'Robinhood Chain',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: { default: { http: ['https://rpc.mainnet.chain.robinhood.com'] } },
});
const API = 'https://robinhook.lol/api/v1';
const wallet = createWalletClient({ chain: robinhoodChain, transport: custom(window.ethereum) });
const [from] = await wallet.requestAddresses();
// 1. Ask for the transactions (nothing is sent yet)
const res = await fetch(`${API}/tx/trade`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ token: '0x…', side: 'buy', amount: '1.5', from, referrer: YOUR_ADDRESS }),
});
const tx = await res.json();
if (!res.ok) throw new Error(tx.message); // plain English, safe to show
// 2. Show tx.steps[i].description to the user, then send each step in order
for (const s of tx.steps) {
const hash = await wallet.sendTransaction({ account: from, to: s.to, data: s.data, value: BigInt(s.value) });
await publicClient.waitForTransactionReceipt({ hash });
// after an approval, ask the API again: the trade gets a fresh quote and simulation
if (s.kind === 'approve') break;
}Errors
| HTTP | error | When |
|---|---|---|
| 400 | bad_request | A field is missing, malformed, or out of bounds. message says which. |
| 404 | not_found | Not an Robin Hook v2 token. |
| 409 | graduating | The curve is full and the pool is opening; try again in a moment. |
| 413 / 415 | too_large | Body over 16 KB, or not JSON. |
| 422 | refused, would_revert, insufficient_balance, no_output | The trade or launch would fail on-chain; message has the reason (a hook rule, the balance, the slippage). |
| 429 | rate_limited | Too many requests from your IP; wait retry-after seconds. |
| 503 | chain_read_failed | Robinhood Chain couldn't be read; nothing is guessed. Retry. |
Keep your users safe
- Show every step's
descriptionbefore the wallet opens, and check thattois an Robin Hook contract from Contracts or the token's quote asset (for an approval). - Never send a step to another chain: every step is for chainId 4663.
- Ask for a fresh answer right before signing; quotes move and pool trades expire after 10 minutes. Curve trades carry no deadline (the launchpad takes none), so don't hold a signed curve trade back: only its
minAmountOutbounds it. - Show
minAmountOutnext to the amount, and keepslippageBpslow (the defaults are 1% on the curve and 3% in a pool). A launch answer lists every hook with the exact values it will be frozen with: show them too, they can't be changed later. - Robin Hook tokens can carry rules (sell taxes, caps, market hours). Show the token's hooks from the catalog.
Prefer contracts directly?
Everything the API does can be done on-chain: the addresses and signatures are in Contracts and the agent skill file, and each hook's config ABI is in the catalog. The API saves you the curve or pool choice, the quote, the slippage floor, the config encoding and the simulation.