Veilbound Launchpad API

List, chart and trade every coin launched on Veilbound Launchpad from your own platform. No key, no sign-up.

Base URL: https://veilbound-launchpad.fly.dev/api/public/v1

Responses are JSON. CORS is open, so it works from a browser. An error is { "error": "…" } with a 4xx status.

Limits per address, per minute: 240 reads, 90 quotes, 30 transaction builds. Over the limit you get a 429; wait 20 seconds.

What a coin here is

Quick start

1. List the coins

const api = 'https://veilbound-launchpad.fly.dev/api/public/v1';
const { pairs } = await (await fetch(`${api}/pairs?sort=marketCap&limit=50`)).json();
for (const p of pairs) console.log(p.symbol, p.market.priceUsd, p.market.marketCapUsd, p.quote.symbol);

2. Price a trade

// buy with 0.5 SOL
const q = await (await fetch(`${api}/quote?mint=${mint}&side=buy&amount=0.5¤cy=SOL&slippageBps=300`)).json();
console.log(q.receive.amount, q.receive.minimum, q.priceImpactPct);

3. Build, sign, send

const r = await (await fetch(`${api}/swap`, { method: 'POST', headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ wallet: wallet.publicKey.toBase58(), mint, side: 'buy', amount: 0.5, currency: 'SOL', slippageBps: 300 }) })).json();

const tx = VersionedTransaction.deserialize(Buffer.from(r.transaction, 'base64'));
const signed = await wallet.signTransaction(tx);
const signature = await connection.sendRawTransaction(signed.serialize());

// optional: show it on the Veilbound Launchpad tape at once
await fetch(`${api}/trades/notify`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ signature }) });

The transaction is unsigned and built for the wallet you name. Nothing is held for you: you sign it and send it through your own RPC. It expires with its blockhash, about a minute after it is built.

Endpoints

EndpointWhat it returns
GET /pairsEvery coin launched here, with its market. Query: quote (symbol or mint), board (mainland (Veilbound), tutorial-island (the Rift), graveyard), sort (marketCap, newest, volume, holders, liquidity, change), limit (up to 200), offset.
GET /pairs/{mint}One coin, plus its safety checks, the dev's position and the top holders.
GET /pairs/{mint}/tradesIts swaps, newest first. Query: limit (up to 200), before (unix seconds; pass the previous page's next).
GET /pairs/{mint}/candlesOHLCV in the pair token. Query: interval (1m 5m 15m 1h 4h 1d), limit (up to 1000).
GET /boardEverything on the board: VEIL itself, the coins launched here and any other coin trading against VEIL.
GET /quoteThe price of a trade. Query: mint, side, amount, currency, slippageBps.
POST /swapThe unsigned transaction for that trade. JSON body: wallet, mint, side, amount, currency, slippageBps.
POST /trades/notifyJSON body: signature. Indexes a swap you just sent.
GET /launchpadHow coins launch here: pair tokens, launch types, tax range, liquidity options.
GET /creators/{wallet}A launcher's record: every coin they launched and what became of it.

Trading

FieldMeaning
sidebuy or sell.
amountFor a buy: how much of the currency to spend. For a sell: how many coins to sell.
currencyWhat a buy is paid with, or what a sell pays out: SOL, VEIL, or PAIR (the coin's own pair token). Default: SOL for a buy, PAIR for a sell.
slippageBps10 to 3000. Default 100 (1%). Below receive.minimum the transaction fails and nothing is spent.

The answer names the route. jupiter means the trade goes through the Jupiter aggregator. pool means it goes straight into the coin's own pool, which is used while a coin's opening fee is still falling and until Jupiter has indexed a new pool. In those first minutes, pay with PAIR.

What a trade costs

// GET /quote?mint=…&side=buy&amount=0.5¤cy=SOL
{
  "side": "buy", "mint": "…", "symbol": "RS4",
  "pay":     { "symbol": "SOL", "mint": "So111…", "amount": 0.5 },
  "receive": { "symbol": "RS4", "mint": "…", "amount": 2841120.5, "minimum": 2755886.9 },
  "priceImpactPct": 1.9, "feeBps": 50, "slippageBps": 300,
  "route": "jupiter", "via": ["Meteora DLMM", "Meteora DAMM v2"]
}
// POST /swap returns the same fields plus:
//   "transaction": "<base64 unsigned versioned transaction>", "lastValidBlockHeight": 123456789

Game payouts

A coin launched with a game keeps its game's share of the pump.fun creator fee in a bankroll the site holds for that coin. Pump.fun locks that share when the coin launches. Sack payouts, drops, the hoard burn, the boss raid and the throne run on their own. With the Game server game, your own server pays the winners through this API. Every payout is listed on the coin's page with its transaction.

EndpointWhat it does
GET /api/games/{mint}The coin's game: its rules, what the bankroll holds, the live state (sack fill, next drop, boss HP and damage board, the hour's throne leader), and the last 30 moves with their transactions.
POST /api/games/payoutPays a player from the bankroll. Header: x-game-key. JSON body: mint, wallet, amount (in VEIL), ref (your own id for this payout), and an optional memo.

The launcher makes the game key on the coin's page and can replace it at any time. The site keeps only its hash. Each ref is paid only once: sending the same ref again returns the first answer. One payout can be at most the coin's maxPct of the bankroll (10% by default), a day's payouts at most dayPct (50% by default), and a coin can make 500 payouts a day. The launcher's own wallet is never paid.

// POST /api/games/payout   x-game-key: vgk_…
{ "mint": "…", "wallet": "…", "amount": 2500, "ref": "match-88121" }
// → { "status": "done", "amount": 2500, "to": "…", "sig": "…", "ref": "match-88121", "at": "2026-10-31T15:02:11.000Z" }

A coin, field by field

{
  "mint": "…", "symbol": "KING", "name": "Kingsbane", "description": "…",
  "image": "https://veilbound-launchpad.fly.dev/launch/….png", "page": "https://veilbound-launchpad.fly.dev/ecosystem/king",
  "links": { "website": "…", "twitter": null, "telegram": null },
  "createdAt": 1791069094867, "liveAt": 1791069110467, "tradingOpensAt": null, "status": "live",
  "board": "mainland", "kingOfTheHill": true,
  "launch":  { "type": "seeded", "startMarketCapUsd": null, "seed": 10000000, "santaBurnedAtLaunch": 500000 },
  "token":   { "decimals": 6, "supply": 1000000000, "program": "token-2022", "mintAuthority": null, "freezeAuthority": null },
  "quote":   { "mint": "GSp4q…pump", "symbol": "VEIL", "decimals": 6, "issuerNote": null },
  "pool":    { "address": "…", "dex": "meteora-damm-v2", "liquidity": "locked", "feesCompound": false,
               "swapFeeBps": 200, "openingFee": { "startBps": 3500, "endBps": 200, "seconds": 480 }, "secondPool": null },
  "tax":     { "bps": 500, "mode": "buyback", "rateLocked": false, "santaBought": 130829, "santaBurned": 0,
               "santaPaidToHolders": 0, "holderPayouts": 0, "coinsBoughtBackAndBurned": 2461732 },
  "market":  { "priceUsd": 0.0000194, "priceQuote": 0.0406, "priceSanta": 0.0406, "marketCapUsd": 19448,
               "liquidityUsd": 18534, "volume24hUsd": 5917, "change24hPct": 337, "holders": 68, "trades": 159, "lastTradeAt": 1791080270 },
  "dev":     { "wallet": "…", "allocationPct": 6.94, "soldPct": 0, "lockedUntil": null },
  "flags":   { "snipedPct": 10.98, "bundledPct": 0 }
}

GET /pairs/{mint} adds:

FieldMeaning
safetyRead from the chain: mintRevoked, freezeRevoked, metadataFrozen, liquidityLocked, liquidityBurned, taxRateLocked.
devAlso holdsPct, lockedPct and the launch buy.
holderscount and the top ten, the pool labelled.
pool.openingFeeAlso nowBps and secondsLeft while it is still falling.

Times are unix: milliseconds on coins (createdAt, liveAt), seconds on trades and candles. Prices in market can be null for a coin that has not traded yet.

Back to the board