Public API
Launch and read Runitup tokens from a bot, an agent, or your own app.
Runitup has a public API so you can launch a token from a script, a trading bot, an AI agent, or your own front-end. A token launched this way is identical to one launched on the website: same factory contract, same 70/20/10 fee split, same permanently locked liquidity.
No API key. No sign-up. Nothing here moves money or exposes anything private, so there is nothing to gate.
We never touch your keys
The API builds your transaction. It does not send it. You sign with a key Runitup never sees and broadcast it yourself. There is no endpoint that launches a token for you, and there never will be — that would mean holding your private key, which would turn one break-in into everyone's loss.
Using it from an AI agent
There's a ready-made skill file — drop it into Claude Code, OpenCode, Hermes, OpenClaw or anything else that loads markdown skills, and the agent knows the whole flow without you explaining it:
https://runitup.fun/skills/runitup/SKILL.mdFor Claude Code, save it as .claude/skills/runitup/SKILL.md in your project (or
~/.claude/skills/ to have it everywhere). Most other frameworks take the raw URL directly.
There's also an llms.txt at the root, which is what agents look for when they want to find their way around a site on their own.
The flow
POST /api/v1/launch/preparewith your token's details- Sign and send the
approvaltransaction it returns, if there is one - Sign and send the
launchtransaction - Read the token address from the
TokenLaunchedevent in the receipt - Optionally
POSTan image and description to the metadata endpoint
Get the current rules
curl https://runitup.fun/api/v1/configReturns the chain, contract addresses, and the live launch rules — the fee, the supply bounds, the starting market cap. Read these rather than hardcoding them; they're read from the contract on every request and can change.
Prepare a launch
curl -X POST https://runitup.fun/api/v1/launch/prepare \
-H 'Content-Type: application/json' \
-d '{
"name": "My Coin",
"symbol": "MYC",
"totalSupply": "1000000000",
"creatorAddress": "0xYourWallet",
"devBuyUsdc": "25",
"venue": "uniswap-v3"
}'| Field | Required | Notes |
|---|---|---|
name | yes | Up to 64 characters |
symbol | yes | Up to 16 characters |
totalSupply | yes | Whole tokens, as a string. "1000000000" is one billion |
creatorAddress | yes | The wallet that will sign |
devBuyUsdc | no | ETH of your own token to buy at launch. "25" is $25 |
feeRecipients | no | Defaults to creatorAddress. Multiple addresses split evenly |
venue | no | uniswap-v3 (default), sushi-v3 or uniswap-v4 |
Amounts are decimal strings, not raw integers — write "25" for $25, not "25000000". Values
coming back are raw integers as strings, because a JSON number would silently round a supply of
1e21.
Pairing is not available through this endpoint
A launch made here is always quoted in ETH. There is no quoteToken field, and that is
deliberate rather than an omission.
Pairing against USDG or a tokenized stock means the dev buy is paid in that asset, which the
factory pulls with transferFrom — so the creator has to approve the spend in a separate
transaction first. This endpoint returns one unsigned transaction and has no way to express
"approve, then launch". Emitting a single transaction that reverts on a missing allowance would be
worse than not offering it.
To launch against another quote asset, use the launch form, which sequences the approval for you. Tokens launched either way are identical afterwards.
You get back:
{
"chainId": 5042002,
"transactions": {
"approval": { "to": "0x36…", "data": "0x095ea7b3…", "value": "0" },
"launch": { "to": "0x60…", "data": "0x1f6a5b96…", "value": "0" }
},
"cost": {
"launchFeeUsdc": "1000000",
"totalUsdcRequired": "26000000",
"sufficientBalance": true
}
}approval is null when your allowance is already enough. When it isn't null, send it first and
wait for it to confirm — the factory pulls ETH from your wallet, and the launch reverts with
transfer amount exceeds allowance if you skip it.
sufficientBalance is reported, not enforced. If it's false the transaction is still built, on
the assumption you're about to fund the wallet.
Send it
import { createWalletClient, http, parseEventLogs } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const wallet = createWalletClient({ account, transport: http(RPC_URL) });
const { transactions } = await fetch(".../api/v1/launch/prepare", { ... }).then(r => r.json());
if (transactions.approval) {
const hash = await wallet.sendTransaction(transactions.approval);
await publicClient.waitForTransactionReceipt({ hash });
}
const hash = await wallet.sendTransaction(transactions.launch);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
// TokenLaunched in the receipt logs carries your new token's addressAdd an image and description
These aren't on-chain, so they're a separate call after the launch confirms:
curl -X POST https://runitup.fun/api/tokens/0xYourToken/metadata \
-H 'Content-Type: application/json' \
-d '{ "name":"My Coin", "ticker":"MYC", "totalSupply":"1000000000000000000000000000",
"creatorAddress":"0xYourWallet", "imageUrl":"https://…", "description":"…",
"ammVenue":"uniswap-v3", "launchType":"quick" }'Do this straight after launching. It makes your token appear on the site immediately rather than waiting for the indexer, and sets the venue so the first buys route correctly.
Reading data
These are open too, and need nothing:
| Endpoint | Returns |
|---|---|
GET /api/tokens | Every live token with price, market cap, volume |
GET /api/tokens/{address} | One token, plus holders and recent trades |
GET /api/tokens/{address}/candles?interval=1h | OHLC price history |
GET /api/activity | Recent launches and trades across the platform |
GET /api/statistics | Platform totals |
GET /api/wallet/{address}/portfolio | A wallet's holdings |
Errors
Validation failures return 400 with the offending field named:
{ "error": "invalid_request", "field": "totalSupply",
"message": "totalSupply must be between … raw units (18 decimals)." }Parameters are checked against the live contract rules, so a request that returns 200 should
not revert for a reason we could have caught. Gas, balance and network conditions are still yours
to handle.