whistle
Start
Developer API

Build on Whistle.

A free, open JSON API with everything on the board: live musters, launched coins, every squad, every delivery and every fee payout. No key, no sign up. Every request below is live, so press Send and you'll get real data.

01

Basics

  • Base URL https://usewhistle.fun/api/v1
  • Read only. Every endpoint is GET and returns JSON. Starting a coin or chipping in happens with your wallet on the site.
  • Open. No key. CORS is open, so you can call it from a browser, a bot or a server.
  • Units. SOL as plain numbers, times as unix milliseconds, raw token amounts as strings (6 decimals), addresses as base58.
  • Versioned. Fields under v1 won't be renamed or removed. New fields may be added.
02

Endpoints

List coins

GET/api/v1/coinscached 5s

Every coin on the board, newest first. Filter by status to watch live musters or launches. Drafts that were never paid aren't listed.

curl -s "https://usewhistle.fun/api/v1/coins"

Get a coin

GET/api/v1/coins/{id}cached 3s

One coin with its full squad: every wallet, what it put in, what was accepted and refunded, its tokens, its delivery transaction and whether it was linked. Also every fee payout.

curl -s "https://usewhistle.fun/api/v1/coins/coin%20id"

Look up a mint

GET/api/v1/coins/mint/{mint}cached 3s

Is this token a Whistle coin? Returns the full coin with isWhistle: true, or a 404 with isWhistle: false. Made for terminals and bots that see a token address first.

curl -s "https://usewhistle.fun/api/v1/coins/mint/token%20mint"

Stats

GET/api/v1/statscached 15s

Totals across Whistle: coins by status, SOL that went into launched pots, squad wallets and creator fees paid back to squads.

curl -s "https://usewhistle.fun/api/v1/stats"

Rules

GET/api/v1/rulescached 5m

The constants every coin runs on (caps, minimums, timers, fees, curve) and the LaunchLab program and Whistle platform addresses. Read straight from the file the server enforces.

curl -s "https://usewhistle.fun/api/v1/rules"
03

The coin object

The list returns the base fields. Single coin and mint lookups add squad, linkedPairs and payouts.

idstringCoin id. The coin page is url.
name, ticker, descriptionstringAs set by the starter. Ticker is uppercase, 2 to 10 characters.
imagestringAbsolute URL to the coin image.
linksobjectwebsite, twitter, telegram and tweet, each a URL or null.
statusstringSee the lifecycle below.
starteraddressWallet that started the coin.
potaddressThe coin's pot address. Chip ins go here, and it's the creator of the pool on-chain.
mint, pooladdress | nullNull until the whistle. The mint is never revealed early.
createdAt, opensAt, closesAt, launchedAtunix ms | nullWhen it was drafted, when the muster opened and closes, and when it launched.
potSolnumberSOL in the pot. Live while mustering, then the accepted amount that bought.
walletsnumberWallets in the pot.
entryPriceSolnumber | nullSOL per token everyone in the pot paid.
tokensBoughtstring | nullRaw token amount the pot bought (6 decimals), as a string.
whistleTxsignature | nullThe block zero transaction that created the pool and bought.
failReasonstring | nullWhy a pot refunded.
marketobject | nullLive LaunchLab curve: priceSol, marketCapSol, raisedSol, goalSol, progress (0 to 1), graduated.
squadarrayDetail only. wallet, committedSol, acceptedSol, refundSol, tokens, linked, group, deliveryTx, starter.
linkedPairsarrayDetail only. Pairs of wallets Whistle found funding each other.
payoutsarrayDetail only. at, sol, recipients, claimTx, payTx for every creator fee payout.
04

Status lifecycle

mustering → settling → launched or refunded. Musters run 10 minutes from the start fee.

awaiting_feeDrafted, start fee not paid yet. Never listed; only visible by id.
musteringOpen for chip ins until closesAt.
settlingMuster closed. The whistle is being blown, or refunds are going out.
launchedPool created, block zero bought, tokens delivered (or in delivery). mint and pool are set.
refundedDidn't reach the minimums. Every chip in was sent back.
cancelledDraft expired unpaid. Never listed.
05

Recipes

Alert on every new muster

// Alert on every new muster (poll every 10s)
const seen = new Set();
setInterval(async () => {
  const { coins } = await fetch("https://usewhistle.fun/api/v1/coins?status=mustering").then((r) => r.json());
  for (const c of coins) {
    if (seen.has(c.id)) continue;
    seen.add(c.id);
    const closes = new Date(c.closesAt).toLocaleTimeString();
    console.log(`$${c.ticker}: ${c.wallets} wallets, ${c.potSol} SOL, closes ${closes} ${c.url}`);
  }
}, 10_000);

Label Whistle coins in a terminal or bot

// Label Whistle coins in your terminal or bot
async function whistleInfo(mint) {
  const r = await fetch(`https://usewhistle.fun/api/v1/coins/mint/${mint}`);
  if (r.status === 404) return null; // not a Whistle coin
  const c = await r.json();
  return {
    squadWallets: c.squad.length,
    linked: c.squad.filter((w) => w.linked).length,
    entryPriceSol: c.entryPriceSol,
    devIsPot: true, // the "dev" wallet is c.pot, not a person
  };
}

Why this matters: on a Whistle coin the creator wallet is the pot, and its block zero buy is the whole squad buying together. The guide explains how that reads on terminals.

06

Errors and limits

  • Errors come back as { "error": "..." } with status 400 (bad input), 404 (not found) or 500.
  • Caching. Responses are cached at the edge for a few seconds (shown on each endpoint), so polling faster than that returns the same data. Every 5 to 10 seconds is plenty.
  • Fair use. No hard limit today. Keep it to a request every few seconds per endpoint and it'll stay that way.
  • Source of truth is the chain. Every amount here links to a transaction you can check on any explorer.