BALLOON
Ready on Solana

Developer docs

Programs, API, and launch reference.

Everything you need to build around Balloon: the pump.fun programs behind every coin, Balloon's launch wallet, how a launch works, and the public read API. The launch wallet on this page is read from the same configuration the site itself uses.

Network
Solana mainnet
API base URL
/api
New to pump.fun?
Read the guide

01

Programs and the launch wallet

Every Balloon coin is created by one wallet on pump.fun's own programs. Every launch, from any page of this site, goes through this wallet.

Balloon launch walletReceives the 0.1 SOL launch payment and creates every coin, so it is every coin's creator on pump.fun and receives its creator fees.
not set yet
pump.funCreates every Balloon coin and runs its bonding curve.
6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6PSolscan ↗
PumpSwappump.fun's own pool program, where a coin trades after it graduates.
pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEASolscan ↗

Balloon deploys no program of its own. The launch wallet is an ordinary wallet that pays, creates coins through PumpPortal, and claims creator fees. pump.fun revokes every coin's mint and freeze authority at creation, so nobody, Balloon included, can mint more or freeze wallets.

Solana programs and accounts Balloon builds on

System programMoves the 0.1 SOL launch payment from the launcher to the launch wallet.
11111111111111111111111111111111Solscan ↗
Memo programCarries the memo that ties each launch payment to its launch.
MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHrSolscan ↗
Wrapped SOLThe SOL side of a coin's PumpSwap pool.
So11111111111111111111111111111111111111112Solscan ↗

02

Where Balloon coins trade

Balloon has no exchange of its own. A coin trades on pump.fun's bonding curve from the moment it is created, then on PumpSwap once the curve fills, and through Jupiter and trading apps at either stage.

Every Balloon coin starts on pump.fun's bonding curve and moves to PumpSwap when the curve fills.

Where Balloon coins trade
VenueStagePriced inProgram
pump.funBonding curveEvery coin starts hereUntil the curve fillsSOL6EF8rr...wF6PSolscan ↗
PumpSwappump.fun's own poolWhere coins graduateAfter the curve fillsSOLpAMMBa...fXEASolscan ↗
JupiterAggregatorRoutes to the curve or the poolBoth stagesAny tokenJUP6Lk...TaV4Solscan ↗

pump.fun sets the curve: 30 SOL virtual against 1,073,000,000 virtual tokens, so a coin opens at about 0.000000028 SOL per token, a market cap of about 28 SOL. Every coin has a supply of 1,000,000,000 with 6 decimals.

03

How a launch transaction works

A launch is one payment the launcher signs and one create the launch wallet signs. The coin is only created after the payment is proven on chain; if the create then cannot happen, the payment goes to a refund list.

  1. 01

    Check

    GET /api/launch/status says whether launching is open, the price (0.1 SOL), and the launch wallet the payment goes to. While it is closed, nothing can be paid for.

  2. 02

    Sign in

    The launcher's wallet signs a message (POST /api/auth). Nothing is paid and no transaction is sent.

  3. 03

    Prepare

    POST /api/launch/prepare stores the picture and the coin's metadata, fixes the coin's mint address, and returns an unsigned payment: one transfer of exactly 0.1 SOL to the launch wallet with the memo balloon launch <id>.

  4. 04

    Sign the payment

    The page checks the transaction is exactly that payment, then the wallet signs it without sending. POST /api/launch/submit sends it.

  5. 05

    Prove the payment

    Before any coin is made, the server reads the confirmed payment back from the chain: the launcher paid, the launch wallet's balance rose by exactly 0.1 SOL, and the memo is there.

  6. 06

    Create the coin

    The launch wallet creates the coin on pump.fun through PumpPortal, with no dev buy, and pays pump.fun's create cost (about 0.02 SOL) out of the fee. Every retry uses the same mint, so one launch can never make two coins.

  7. 07

    Go live

    The page asks POST /api/launch/confirm every 2 to 3 seconds. The coin is live once the chain proves the create, and it appears on Balloon, usually within seconds.

  8. 08

    Optional pre-buy

    If the launcher asked for one, the page builds their own buy (POST /api/trade/build), and their wallet signs and sends it. It is not paid to Balloon.

The picture and the metadata are stored in Balloon's Supabase storage, and the coin's on-chain metadata link points there. If the launch wallet is low on SOL, a paid launch waits and is created as soon as it is topped up.

04

Fees and the launch payment

The launch fee

0.1 SOL in one payment to the launch wallet, and nothing else. pump.fun's own create cost, about 0.02 SOL, is paid by Balloon out of the fee, never added on top. The launcher's wallet also pays Solana's normal network fee for this one transaction. The payment, in order:

Launch payment
ComputeBudget  compute unit limit and price      (the network fee)
System         transfer 100000000 lamports      launcher -> launch wallet (0.1 SOL)
Memo           "balloon launch <launch id>"

Creator fees

Balloon's launch wallet is every coin's creator on pump.fun, so pump.fun's creator fees from every coin go to Balloon. That is how Balloon earns. The launcher does not receive creator fees, and Balloon pays no rewards or revenue share to anyone.

Trading fees

Balloon adds no trading fee of its own. Traders pay pump.fun's normal fees, which pump.fun sets and can change. An optional pre-buy is an ordinary trade in the launcher's own wallet and is not paid to Balloon.

05

Read coins onchain

You do not need the Balloon API to follow its coins. Every Balloon coin is an ordinary pump.fun coin whose creator is the launch wallet, so its accounts are found like any pump.fun coin's. The samples below use @solana/web3.js, with mint and launchWallet as PublicKeys.

Curve and pool addresses
import { PublicKey } from "@solana/web3.js";

const PUMP = new PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");
const PUMP_SWAP = new PublicKey("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA");
const WSOL = new PublicKey("So11111111111111111111111111111111111111112");
const seed = (s: string) => Buffer.from(s, "utf8");

// The coin's bonding curve (it also holds the curve's tokens)
const [curve] = PublicKey.findProgramAddressSync([seed("bonding-curve"), mint.toBuffer()], PUMP);

// The PumpSwap pool the coin graduates into
const [poolAuthority] = PublicKey.findProgramAddressSync([seed("pool-authority"), mint.toBuffer()], PUMP);
const [pool] = PublicKey.findProgramAddressSync(
  [seed("pool"), Buffer.from([0, 0]), poolAuthority.toBuffer(), mint.toBuffer(), WSOL.toBuffer()],
  PUMP_SWAP,
);
Creator fee vault
// pump.fun keeps the creator fees of every Balloon coin here until they are claimed
const [creatorVault] = PublicKey.findProgramAddressSync([seed("creator-vault"), launchWallet.toBuffer()], PUMP);
Launch payment memo
program  MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr
memo     balloon launch <launch id>

06

API endpoints

JSON over HTTPS for coins launched on Balloon, with prices, volume, trades, holders, and candles from Balloon's own index. Reads need no key or signup.

  • Call it from your server. Responses carry no CORS headers, so a browser fetch from another site is blocked.
  • Read answers are cached for up to 15 seconds, so polling more often returns the same data. Server errors are never cached.
  • Only coins launched on Balloon and proven live on chain appear. Drafts, failed launches, and other pump.fun coins never do.
  • The API is not versioned. Fields may be added, so ignore unknown keys and expect null values.
Endpoint summary
MethodPathReturns
GET/api/coinsPaged coin list with market data
GET/api/coins/<mint>One coin by mint address
GET/api/coins/<mint>/tradesA coin's trades, newest first
GET/api/coins/<mint>/holdersA coin's top 20 holders
GET/api/coins/<mint>/candlesPrice candles in USD
GET/api/searchName, ticker, or mint lookup
GET/api/events/recentThe latest trades across all coins
GET/api/sol-priceSOL price in USD
GET/api/statsLive coins, trades, and traders
GET/api/launch/statusWhether launching is open, the price, and the launch wallet

GET/api/coins

Coins launched on Balloon. Pages use a cursor: pass nextCursor from one answer as cursor in the next. nextCursor is null on the last page.

Query parameters
ParameterValuesDefault
orderVOLUME_30_MIN_DESC | VOLUME_24_HOUR_DESC | NEWEST | CLOSEST_TO_GRADUATION | MARKET_CAP_DESC | PRICE_CHANGE_24_HOUR_DESC | OLDESTVOLUME_30_MIN_DESC
cursornextCursor of the previous page-
limit1 to 100, clamped25
nsfw1 includes coins flagged NSFW0
creatorA wallet; only the coins it launched-
stageall | curve | graduatedall
Request
curl "<this site>/api/coins?order=NEWEST&limit=25"
Response
{
  "items": [ { /* Coin, see API data */ } ],
  "nextCursor": "<opaque>"   // null on the last page
}
  • VOLUME_30_MIN_DESC is trending. CLOSEST_TO_GRADUATION lists coins still on their curve only.
  • An unknown order or stage, or a creator that is not a wallet address, returns 400.

GET/api/coins/<mint>

One coin. A mint that was not launched on Balloon returns 404. A database error returns 500, never a 404, so a 404 always means the coin is not here.

Request
curl "<this site>/api/coins/<mint>"
Response
{ /* Coin, see API data */ }   // 404 { "error": "No such coin here." } when not launched on Balloon

GET/api/coins/<mint>/trades

Trades from Balloon's index of the coin's curve and pool, newest first. limit is 1 to 100 and defaults to 50; page with cursor like the coin list.

Request
curl "<this site>/api/coins/<mint>/trades?limit=50"
Response
{
  "items": [ { /* Trade */ } ],   // newest first
  "nextCursor": "<opaque>"
}

GET/api/coins/<mint>/holders

The top 20 holders from the newest snapshot, taken every 10 minutes. The bonding curve and the pool are labeled, and DEV marks the wallet that launched the coin.

Request
curl "<this site>/api/coins/<mint>/holders"
Response
{ "holders": [ { /* Holder */ } ] }   // top 20 of the newest snapshot

GET/api/coins/<mint>/candles

Price candles in USD from Balloon's own indexed trades, oldest first. res is 60, 300, 900, 3600, 14400, or 86400 seconds (other values snap to the nearest); limit is 1 to 1000 and defaults to 300.

Request
curl "<this site>/api/coins/<mint>/candles?res=300&limit=300"
Response
{ "candles": [ { /* Candle */ } ] }   // oldest first, USD

GET/api/search

Lookup by name, ticker, or mint address, at most 6 coins, an exact mint or ticker first. An empty q returns no coins. Limited to 60 searches a minute per address.

Request
curl "<this site>/api/search?q=<name, ticker or mint>"
Response
{ "coins": [ { /* Coin */ } ] }   // at most 6

GET/api/sol-price

The SOL price in USD, from Jupiter with DexScreener as the fallback. Returns 503 when no source answers.

Request and response
curl "<this site>/api/sol-price"

{ "usd": <number> }

GET/api/stats

Live coins launched on Balloon, the indexed trades on them, and the distinct wallets that traded them. Zeros when the database cannot be read.

Request and response
curl "<this site>/api/stats"

{ "coins": <number>, "trades": <number>, "traders": <number> }

GET/api/events/recent

The latest trades across all Balloon coins, newest first, each with its coin. limit is 1 to 50 and defaults to 20; nsfw=0 leaves out coins flagged NSFW.

Request and response
curl "<this site>/api/events/recent?limit=20"

{ "trades": [ { /* Trade, with its coin */ } ] }

GET/api/launch/status

Whether launching is open, with a plain reason while it is not, the price, and the launch wallet. Never cached.

Request and response
curl "<this site>/api/launch/status"

{
  "open": <true or false>,
  "reason": "<plain words while closed, else null>",
  "feeSol": 0.1,
  "createCostSol": 0.02,   // paid by the launch wallet out of the fee
  "totalSol": 0.1,
  "launchWallet": "<address or null>"
}

Errors and limits

Error responses
StatusWhen
400An unknown order or stage, or a creator that is not a wallet. The body is {"error": "..."}.
404The coin was not launched on Balloon.
429Too many requests, for example more than 60 searches a minute. Wait a moment and try again.
500The data could not be read just now. Try again in a moment.
503sol-price only: no price source answered.

07

API data reference

Coin fields

Coin fields
FieldTypeMeaning
mintstringThe coin's mint address.
name, symbolstringSet by the launcher. Not unique.
imageUrlstring or nullThe picture, stored by Balloon.
descriptionstring or nullThe coin's bio, up to 512 characters.
createdAtISO 8601When the coin was created.
graduatedAtISO 8601 or nullWhen the curve filled. Null while on the curve.
twitterUrl, telegramUrl, websiteUrlstring or nullLinks the launcher gave.
imageFlag"NSFW" | nullSet by hand when a picture is flagged.
creatorPersonThe wallet that launched it on Balloon. The on-chain creator is the launch wallet.
poolsPool[]Empty while on the curve; the PumpSwap pool once graduated.
feesEarnedSolnumberCreator fees this coin has earned for the launch wallet, all time, in SOL.
statsCoinStatsMarket data, below.

Market data

Prices come from the newest indexed trade or market read, times the current SOL price. A number nobody has measured yet is null, never a guess.

Market data fields
FieldMeaning
graduatedPercentageBonding curve progress, 0 to 100; 100 once graduated.
priceSol, priceUsdPrice per token in SOL and USD.
marketCapUsd, marketCapAthUsdMarket cap, and the highest it has been. The high only ever goes up.
mcapChange24HPercent change against the last trade at least 24 hours old (a younger coin: against the curve's opening price); DexScreener's for graduated coins.
volume24HUsd, volumeChange24H24 hour volume in USD from indexed trades, and its percent change.
holdersWallets in the newest holder snapshot. The curve and the pool are not counted.

Trades, holders, and candles

Balloon reads every live coin's trades every minute and takes holder snapshots every 10 minutes. A busy coin can take a few minutes to catch up, so show times and prefer the chain when it matters.

Types
type Trade = {
  id: string;            // "<signature>:<event index>"
  direction: "BUY" | "SELL";
  solAmount: number;
  tokenAmount: number;
  timestamp: string;     // ISO 8601
  signature: string;
  trader: Person;
  isDeployer: boolean;   // the launcher's own trade
  coin?: { mint: string; symbol: string; imageUrl: string | null; imageFlag: "NSFW" | null };
};

type Holder = {
  owner: Person;
  amount: number;
  percentage: number;    // of total supply
  label: "BONDING_CURVE" | "POOL" | "DEV" | null;   // DEV = the launcher
};

type Candle = { time: number; open: number; high: number; low: number; close: number; volume: number };
// time in unix seconds; prices and volume in USD

type Person = {
  address: string;       // a Solana wallet
  twitterUsername: string | null;   // always null: no X linking
  twitterName: string | null;
  twitterProfileImageUrl: string | null;
};

Displaying coin data safely

  • Names, tickers, and descriptions are arbitrary user input. Escape them and never inject them as HTML.
  • Tickers are not unique and impersonation is common. Show the mint address next to the name.
  • Balloon accepts only JPEG, PNG, and GIF pictures. Still never render SVG from any token source; it can carry script.
  • websiteUrl, twitterUrl, and telegramUrl are supplied by the launcher. If you make them clickable, use rel="noopener noreferrer nofollow".
  • Link each coin to /token/<mint> and credit the source as “Coin data from Balloon”.

08

SDK and launching from code

Balloon has no SDK. The read API above and the chain are the supported ways to build on Balloon coins, and launches go through the Launch page.

  • The launch routes (POST /api/launch/prepare, submit, and confirm) serve this site's own pages. They need a signed-in wallet session and the x-balloon: balloon header, refuse requests from other sites, and may change at any time.
  • Sign-in (POST /api/auth) and the trade builder (POST /api/trade/build) are internal routes of the same kind, not a public API.
  • Every Balloon coin is a normal pump.fun coin, so any tool that reads or trades pump.fun coins works with it.
  • Balloon never holds a launcher's keys. Every launch payment is signed in the launcher's own wallet.
Open Launch