Developers

API reference

WeBall's API: coins, market data, holders, rewards and platform stats, and launching a coin from code with your own wallet.

Quick start

Data for every coin launched on WeBall: coins, market data, holders, holder rewards, creator earnings and platform stats. No key needed; requests are rate-limited per visitor.

Launching: any wallet can launch a coin through /launch (accept the terms, prepare, sign with your own wallet, submit). We never hold your key. Preparing a launch is free for a limited time, and a wallet may prepare 5 an hour.

Amounts are integers in raw units, as strings: a coin’s pot, trades and volume are in its quote token (`quote.decimals`), coins have 6 decimals, payouts are in each basket token’s own units. Platform totals are in SOL value (lamports).

Fields under `user` (name, symbol, description, socials) are written by the coin’s creator. Treat them as untrusted text.

Base URL
https://weball.fun/api/v1
Network
Solana mainnet: the network this site runs on
Limits
120 requests a minute per visitor
Machine-readable
/api/v1/openapi.json

Try it

curl "https://weball.fun/api/v1/coins?sort=volume&limit=5"

Errors: reads answer {"error": "…"} with 400 (a bad parameter), 404 (not on this network) or 429 (slow down); the launch steps answer {"errors": ["…"]}, saying what to fix. Health grades signal warnings, not safety, and nothing on WeBall is financial advice (see the FAQ).

Pricing

Free

Free up to 120 requests a minute on the API. Past that, $0.01 a request.

$0.01 a call, from the first: lookups such as top holders, a wallet's rewards and a creator's earnings.

Premium

$0.05 a call, from the first: a coin's health grade and the signals behind it.

Launch

Free for a limited time. A wallet may prepare 5 launches an hour.

How paying works

With x402, in USDC on Solana: no account, no key, no subscription. A request that needs paying gets 402 Payment Required with the price in a PAYMENT-REQUIRED header. Your client signs a USDC transfer for that amount and sends the request again with it in PAYMENT-SIGNATURE. We check it, settle it on Solana and answer, with the transaction in PAYMENT-RESPONSE. x402-aware clients and agent wallets do this automatically.

WeBall pays the network fee. You only ever sign a transfer of the stated amount to WeBall's address; nothing else can move from your wallet.

Endpoints

Free 11

GET/coinsFree#

List or search coins

`coins`: summaries (market cap, 24h volume and change, holders, bonding progress); `next`: the next page’s offset, or null. `figuresPending: true` (about a minute after launch): the figures aren’t computed yet and read null; read again shortly.

ParameterInValuesAbout
qquerystringA mint address, a symbol, or part of a name.
sortquerynewest | volume | marketCap (default newest)
modequeryany | holder | creator (default any)
graduatedqueryany | true | false (default any)
limitqueryinteger 1–100 (default 50)
offsetqueryinteger (default 0)
curl "https://weball.fun/api/v1/coins?sort=volume"

GET/tokensFree#

Search any Solana token

`tokens`: any token Jupiter knows, as Jupiter ranks them: `symbol`, `name` (null when the creator’s text doesn’t look like a label), `logoUrl` (our own copy), `verified` (Jupiter’s list), `tags`, `onWeBall` (`quote`: offered for pairing; `basket`: offered in holder baskets; `addedAt`: the day it was listed here), `decimals`, `tokenProgram` (spl or token-2022), `mintAuthority` and `freezeAuthority` (an address while set, null when revoked or unknown), and Jupiter’s US$ figures as numbers (`priceUsd`, `marketCap`, `liquidityUsd`, `volume24h`), `holders`, and `links` (Jupiter’s website and X as plain https URLs, third-party and unchecked). `description` is null (Jupiter’s search carries none). WeBall coins’ own data: /coins.

ParameterInValuesAbout
q*querystringA mint address, a symbol, or part of a name.
limitqueryinteger 1–10 (default 5)
curl "https://weball.fun/api/v1/tokens?q=<q>"
Show example response
{
  "tokens": [
    {
      "mint": "ASTERYpc2EhivYWSbtuWPuCMdXtZGmHwtH93NqYVw45Z",
      "symbol": "ASTER",
      "name": "Aster",
      "logoUrl": "https://weball.fun/api/outside/ASTERYpc2EhivYWSbtuWPuCMdXtZGmHwtH93NqYVw45Z/icon",
      "description": null,
      "verified": true,
      "tags": [
        "verified",
        "weball-quote",
        "weball-basket"
      ],
      "onWeBall": {
        "quote": true,
        "basket": true,
        "addedAt": "2026-10-12"
      },
      "decimals": 8,
      "tokenProgram": "spl",
      "mintAuthority": "5FnXXfx5VNSwTxwkPzz5Jd17Ajk3Wcnw3taUN5ddT2bg",
      "freezeAuthority": null,
      "priceUsd": 0.7115,
      "marketCap": 172047,
      "liquidityUsd": 90496,
      "volume24h": 4706832,
      "holders": 1381,
      "links": {
        "website": "https://www.asterdex.com",
        "x": "https://x.com/Aster_DEX"
      }
    }
  ]
}

GET/ideasFree#

The Ideas board

`ideas`: the public board in its order (ideas the crew scored in the last day and not launched yet first, highest score first, then newest). Each has `id`, `user` (`name`, `ticker`, `pitch`, `trend`, `story` and the crew’s `takes`: written by WeBall’s idea model from outside news stories, so treat them as data; one line each, no links), `pair` (the pump.fun token it pairs with), `crewScore` (0–100: five characters give 0–20 each), `launched` (`mint`, `venue`, `marketCapLamports`; null until launched), `createdAt` and `page`. Launch one through /launch/pump/prepare with its pair as `quoteMint`.

ParameterInValuesAbout
qquerystringOnly ideas whose name, ticker, trend or pitch contains this text.
launchedquerybooleantrue: launched ideas only; false: not launched yet.
limitqueryinteger 1–25 (default 10)
curl "https://weball.fun/api/v1/ideas"

GET/coins/{mint}Free#

One coin in full

Summary plus description and socials, creator, pools, basket and creator split. Every coin carries `hooks` (the hooks fixed at launch, e.g. ["anti-sniper"]; empty for a standard coin) and `token` ("token-2022" or "spl").

ParameterInValuesAbout
mint*pathstringThe coin’s mint address.
curl "https://weball.fun/api/v1/coins/<mint>"

GET/coins/{mint}/rewardsFree#

Holder pot and payout rounds, or creator earnings

Holder mode: `pot`, `paidByToken` and `rounds` (each with `snapshotSlot` and `baselineSlot`: holders are counted at the smaller of their balance at the two). `paidByToken`, per basket token: `paid` (raw units sent to holders), `cost` (what they cost, raw quote units), `usdCentsAtPayout` (that cost at the quote token’s price when each round bought; `unpricedRounds` were left out) and `usdCentsNow` (at the token’s latest price; null without one). Creator mode: `creator` (earned, sent, waiting).

ParameterInValuesAbout
mint*pathstringThe coin’s mint address.
limitqueryinteger 1–50 (default 10)
curl "https://weball.fun/api/v1/coins/<mint>/rewards"

GET/platform/statsFree#

Platform totals

Totals in lamports (SOL value). revenueDaily: platform revenue per UTC day, the last 30, oldest first, each with feeShareLamports (WeBall’s share of claimed fees), swapReferralLamports, apiMicroUsd (x402 payments), solMicroUsd (that day’s average SOL price; the latest for a day with none) and usdCents (the day’s total in US cents; null without a SOL price) and cumulativeUsdCents (all revenue to the end of that day). Coins launched and graduated, trades, volume, paid to holders, sent to creators (SOL value), and daily platform revenue in US cents.

curl "https://weball.fun/api/v1/platform/stats"

GET/platform/fundsFree#

Platform funds

$BALL burn, AI and platform balances (and the removed flywheel’s leftover balance).

curl "https://weball.fun/api/v1/platform/funds"

GET/hooksFree#

The hooks menu

Rules a coin can have built in, picked at launch and fixed after. `open`: this network takes launches with hooks; `hooks`: each with `id`, `name`, `line`, `group` (launch, life, games), `ends` and `status` ("live" or "coming"); `builtIn`: the fee shield, on every coin; `antiSniper`: its limit in bps of supply (100 = 1%) and its window in seconds. Pass live ids as `hooks` when you prepare a launch.

curl "https://weball.fun/api/v1/hooks"

GET/platform/burnsFree#

$BALL burns for a day

One UTC day of $BALL burns, from our records of the on-chain burns: burned that day, totals to the end of that day, and the burn fund now. Display units as strings ($BALL in whole tokens, SOL, US dollars). burned_today_usd is the SOL the day’s burns cost, at the latest SOL price (null without a price). date, burned_today, burned_today_usd, burned_total, original_supply, burned_pct_of_supply, burn_count, last_burn_tx, burn_fund_sol.

ParameterInValuesAbout
datequerydateA UTC day, YYYY-MM-DD; today when left out.
curl "https://weball.fun/api/v1/platform/burns"

GET/coins/{mint}/tradesFree#

Recent trades, newest first

`trades`: signature, time, side, trader (the wallet whose coins moved; the fee payer when unknown), coinAmount, quoteAmount.

ParameterInValuesAbout
mint*pathstringThe coin’s mint address.
limitqueryinteger 1–100 (default 50)
beforequerydate-timeAn ISO time: trades before it (the previous page’s `next.before`).
curl "https://weball.fun/api/v1/coins/<mint>/trades"

GET/coins/{mint}/ohlcvFree#

Price candles

`candles`: time, open, high, low, close (quote token per whole coin) and volume; at most 500.

ParameterInValuesAbout
mint*pathstringThe coin’s mint address.
intervalquery1m | 5m | 15m | 1h | 4h | 1d (default 1h)
curl "https://weball.fun/api/v1/coins/<mint>/ohlcv?interval=5m"

Basic 3

GET/coins/{mint}/holdersBasic#

Top holders

`holders`: the count; `baselineSlot`: the slot the next round compares against (null before there is one); `top`: wallet, amount, shareBps of supply, and `countsNextRound`: the amount the next round would count under the holding rule (the smaller of the balance now and at the baseline). Pools, locked liquidity and WeBall’s wallets are left out.

ParameterInValuesAbout
mint*pathstringThe coin’s mint address.
limitqueryinteger 1–100 (default 20)
curl "https://weball.fun/api/v1/coins/<mint>/holders"

GET/wallets/{wallet}/rewardsBasic#

What a wallet has been paid, and is owed

`paid`: payouts with token, amount and signature; `owed`: shares below the minimum payout, carried to the next round.

ParameterInValuesAbout
wallet*pathstringA Solana wallet address.
coinquerystringOnly this coin.
limitqueryinteger 1–200 (default 50)
curl "https://weball.fun/api/v1/wallets/<wallet>/rewards"

GET/creators/{wallet}Basic#

A creator’s coins and earnings

`coins` with earnings (creator mode); `recentSends`: payments to the creator.

ParameterInValuesAbout
wallet*pathstringA Solana wallet address.
curl "https://weball.fun/api/v1/creators/<wallet>"

Premium 1

GET/coins/{mint}/healthPremium#

Health grade and signals

`grade` (A–F; null when not scored yet or over an hour old), `checkedAt`, `signals` (top10Bps, creatorUnlockedBps, creatorSoldLaunchBuy, sniperBps, bundleBps, insiderBps, washBps: shares of supply in bps, 10,000 = 100%; mintAuthority and freezeAuthority: true while still set, absent on older grades), `levels` (ok, caution or warning per signal) and `context` (holders, the creator’s other launches and graduations). Flags warnings; never a sign a coin is safe.

ParameterInValuesAbout
mint*pathstringThe coin’s mint address.
curl "https://weball.fun/api/v1/coins/<mint>/health"

Launch a coin

Any wallet can launch a coin from code, in these steps, in this order. We never hold your key: prepare returns an unsigned transaction and you sign it with your own wallet. Preparing a launch is free for a limited time. A wallet may prepare 5 launches an hour. On pump.fun (/launch/pump/…) the coin pairs with SOL, USDC or a token pump.fun lists and pays its holders 70% of every creator fee; on Meteora (/launch/prepare…) it's SOL coins without a creator lock. The MCP server has the same steps as tools.

Step 1GET/launch/termsLaunch#

Launch step 1: the terms message to sign

`version`, `signedAt` and `message`: sign `message` (UTF-8, ed25519) with the wallet within 10 minutes, then POST it back. Once per wallet per terms version.

ParameterInValuesAbout
wallet*querystringThe launching wallet.
curl "https://weball.fun/api/v1/launch/terms?wallet=<wallet>"

Step 2POST/launch/termsLaunch#

Launch step 1: accept the terms

Body: `{ wallet, version, signedAt, signature }`: `signature` is the base64 ed25519 signature of `message`.

`{ accepted: true }`.

curl -X POST "https://weball.fun/api/v1/launch/terms" \
  -H 'content-type: application/json' \
  -d '{ … }'

Step 3POST/launch/prepareLaunch#

Launch step 2: prepare a coin (free for a limited time)

Body: `{ creator, mint, name, ticker, description?, socials?: { x?, telegram?, website? }, image? (base64), mode: "holder" | "creator", feeBps, basket?: [{ mint, weight }], recipients?: [{ wallet, pct, label? }], buyBps?, rollIn?, hooks?: ["anti-sniper"] }`. `mint` is a fresh keypair’s address you hold, used only when our address pool is empty.

Validates and records the launch, then returns the unsigned transaction. Free for a limited time; a wallet may prepare 5 launches an hour. SOL coins without a creator lock for now. With `hooks` (live ids from /hooks, where `open`), the coin is a Token-2022 token paired with SOL. `mint`, `pool`, `transaction` (base64, unsigned), `lastValidBlockHeight`, `buy` and `mintSource`. Sign `transaction` with `creator`, and also with your `mint` keypair when `mintSource` is "browser" (when it is "pool" we add the mint signature at submit). Then POST it to /launch/submit before it expires.

curl -X POST "https://weball.fun/api/v1/launch/prepare" \
  -H 'content-type: application/json' \
  -d '{ … }'

Step 4POST/launch/submitLaunch#

Launch step 3: send the signed launch

Body: `{ mint, transaction }`: the signed transaction, base64.

`{ status: "confirmed", signature, result }`, or `{ status: "pending", signature }`: then POST /launch/confirm with the signature. Never sign and send it again.

curl -X POST "https://weball.fun/api/v1/launch/submit" \
  -H 'content-type: application/json' \
  -d '{ … }'

Step 5POST/launch/confirmLaunch#

Launch step 4: confirm a pending launch

Body: `{ mint, signature }`.

The launch once confirmed on chain; a 409 while it hasn’t landed yet (try again shortly).

curl -X POST "https://weball.fun/api/v1/launch/confirm" \
  -H 'content-type: application/json' \
  -d '{ … }'

Step 6POST/launch/pump/prepareLaunch#

Launch on pump.fun: prepare a coin (free for a limited time)

Body: `{ creator, mint, name, ticker, image (base64), description?, quoteMint? (the pair: SOL by default, USDC or a token pump.fun lists, GET /api/pump/quotes), holdersPaid?: "pair" | "basket", basket?: [{ mint, weight }], buyLamports? (string; SOL pairs only, up to 10% of supply), socials?: { website?, x?, telegram? } }`. `mint` is a fresh keypair’s address you hold: pump.fun creates the coin there.

Validates and records a pump.fun launch, then returns its unsigned transactions. Free for a limited time; a wallet may prepare 5 launches an hour (with /launch/prepare). Accept the terms first (/launch/terms). Of every creator fee: holders 70%, WeBall 12%, WeBall AI 3%, $BALL bought and burned 10%, the creator's referrer 5% (else $BALL liquidity), locked at launch. `mint`, `transactions` (one or two base64 unsigned v0 transactions: the coin and any first buy, then the fee split), `buyTokens`, `buyMaxLamports` and `sponsored` (true: WeBall pays the launch costs, within 1 SOL a day and 5 a wallet a day for a wallet holding 0.05 SOL; its sponsor is the fee payer and signs at submit, so leave its signature empty). Sign every transaction with `creator`, sign the first with your `mint` keypair too, then POST them all, in order, to /launch/pump/submit before they expire. Wallets may add compute-budget and Lighthouse instructions; anything else is refused.

curl -X POST "https://weball.fun/api/v1/launch/pump/prepare" \
  -H 'content-type: application/json' \
  -d '{ … }'

Step 7POST/launch/pump/submitLaunch#

Launch on pump.fun: send the signed launch

Body: `{ mint, transactions: [base64, …] }`: every transaction prepare returned, signed, in order.

`{ status: "confirmed", signature, result }`, or `{ status: "pending", signature }`: then poll GET /launch/pump/status. Never sign and send them again.

curl -X POST "https://weball.fun/api/v1/launch/pump/submit" \
  -H 'content-type: application/json' \
  -d '{ … }'

Step 8GET/launch/pump/statusLaunch#

Launch on pump.fun: where a launch is

`{ mint, status: "prepared" | "sending" | "confirmed" | "abandoned", page }`: `page` is the coin’s page once it’s confirmed.

ParameterInValuesAbout
mint*querystringThe coin’s mint.
curl "https://weball.fun/api/v1/launch/pump/status?mint=<mint>"

Webhooks

Signed POSTs to your URL when a coin launches, graduates or pays out. Each call below is signed by the wallet that owns the webhooks; no key. Events, the delivery format, the signature check and a manager are on the developers page.

POST/webhooks/createWebhooks#

Create a webhook

Body: `{ wallet, time, signature, url, events: string[], mints?: string[] }`. Message fields: `URL: <url>`, `Events: <comma list>`, `Coins: <comma list or all>`.

A signed POST to `url` for each event: `coin.launched`, `coin.graduated`, `payout.paid`. Up to 5 webhooks per wallet, each for every coin or up to 20. Signed by the owner wallet: `wallet`, `time` (ISO, within 5 minutes) and `signature` (base64 ed25519 over the exact message: lines `WeBall webhooks`, `Action: <action>`, `Wallet: <wallet>`, then the action’s fields, then `Time: <time>`; see /developers#webhooks). `{ webhook, secret }` (201). Keep `secret`: it is shown only now, and every delivery carries `WeBall-Signature: t=<unix>,v1=<hex HMAC-SHA256 of "<t>.<body>">` made with it.

curl -X POST "https://weball.fun/api/v1/webhooks/create" \
  -H 'content-type: application/json' \
  -d '{ … }'

POST/webhooks/listWebhooks#

List your webhooks

Body: `{ wallet, time, signature }`.

Signed by the owner wallet: `wallet`, `time` (ISO, within 5 minutes) and `signature` (base64 ed25519 over the exact message: lines `WeBall webhooks`, `Action: <action>`, `Wallet: <wallet>`, then the action’s fields, then `Time: <time>`; see /developers#webhooks). `{ webhooks: [{ id, url, events, mints, status, createdAt, lastSuccessAt, failingSince, pausedAt, deliveries7d }] }`.

curl -X POST "https://weball.fun/api/v1/webhooks/list" \
  -H 'content-type: application/json' \
  -d '{ … }'

POST/webhooks/deleteWebhooks#

Delete a webhook

Body: `{ wallet, time, signature, id }`. Message field: `Webhook: <id>`.

Signed by the owner wallet: `wallet`, `time` (ISO, within 5 minutes) and `signature` (base64 ed25519 over the exact message: lines `WeBall webhooks`, `Action: <action>`, `Wallet: <wallet>`, then the action’s fields, then `Time: <time>`; see /developers#webhooks). `{ deleted: id }`. Nothing more is sent to it, including retries already queued.

curl -X POST "https://weball.fun/api/v1/webhooks/delete" \
  -H 'content-type: application/json' \
  -d '{ … }'

POST/webhooks/enableWebhooks#

Re-enable a paused webhook

Body: `{ wallet, time, signature, id }`. Message field: `Webhook: <id>`.

A webhook whose deliveries all fail for 3 days is paused. Signed by the owner wallet: `wallet`, `time` (ISO, within 5 minutes) and `signature` (base64 ed25519 over the exact message: lines `WeBall webhooks`, `Action: <action>`, `Wallet: <wallet>`, then the action’s fields, then `Time: <time>`; see /developers#webhooks). `{ webhook }`, active again; events from now on are delivered.

curl -X POST "https://weball.fun/api/v1/webhooks/enable" \
  -H 'content-type: application/json' \
  -d '{ … }'

POST/webhooks/testWebhooks#

Send a test ping

Body: `{ wallet, time, signature, id }`. Message field: `Webhook: <id>`.

Sends one `webhook.test` event now, signed like a real one; at most one every 30 seconds per webhook. Signed by the owner wallet: `wallet`, `time` (ISO, within 5 minutes) and `signature` (base64 ed25519 over the exact message: lines `WeBall webhooks`, `Action: <action>`, `Wallet: <wallet>`, then the action’s fields, then `Time: <time>`; see /developers#webhooks). `{ delivered, status, error }`: whether your URL answered 2xx.

curl -X POST "https://weball.fun/api/v1/webhooks/test" \
  -H 'content-type: application/json' \
  -d '{ … }'

Not financial advice. Memecoins can go to zero.