{"openapi":"3.1.0","info":{"title":"StonkFun Developer API","version":"2.0.0","description":"Launch tokens and read platform data. Launches are non-custodial: the creator signs their own fee payment and the platform never holds a private key. Paths under /api/public/v1 return a {data, meta} envelope and coded errors. Paths under /api/v2 return the body without an envelope, return errors as {error: string}, and send no CORS headers: call them from a server."},"servers":[{"url":"https://www.stonkfun.xyz"}],"tags":[{"name":"Data","description":"Tokens, launches, pairs and rewards."},{"name":"Revenue","description":"Platform revenue, buybacks and burns."},{"name":"Launch","description":"Create tokens programmatically."},{"name":"Fees","description":"Read and claim creator fees."}],"paths":{"/api/v2/launches/recent":{"get":{"tags":["Data"],"summary":"Recent launches","description":"Launches from the last windowMs milliseconds (10 minutes), read from the launch records. Use it to show a launch before the pool sweep includes it. Each pool has pending: true. Market figures come from the latest indexed chain state, or from the opening market cap when there is none yet. status is never graduated, and liquidityUsd is absent. The body is {pools, degraded, network, windowMs, page, generatedAt}. A page can hold fewer than limit pools before the end, because hidden launches are removed. degraded: true means the read failed and pools is empty: try again.","parameters":[{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to desc (newest first). Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/launches/{mint}":{"get":{"tags":["Data"],"summary":"Get one launch","description":"The launch record for a mint, in the pool shape, with pending: true. Works at any age of the launch. Market figures are calculated as in /launches/recent, so for a token that trades already, GET /api/public/v1/tokens/{mint} is more complete. The body is {pool, degraded, network, generatedAt}. Answers 200 with pool: null when the platform did not launch the mint. degraded: true means the read failed: try again.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/tokens/{mint}/socials":{"get":{"tags":["Data"],"summary":"Token social links","description":"The website, twitter and telegram links of a token, as its token page shows them. Each key is absent when the token has no such link. An address that is not valid gives {}.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/tokens/{mint}/rewards":{"get":{"tags":["Data"],"summary":"Token reward totals","description":"Lifetime holder-reward totals of a reward coin. The body is {mint, mode, quote, basis, rewards, base, generatedAt}. rewards holds quote-token amounts. base holds what the launch paid in its own token, and is null when it never did. A standard launch gives mode: \"standard\" with null rewards. basis is \"ledger\" or \"snapshot\", the source of the totals. basis: \"awaiting-snapshot\" means the totals are not built yet, and rewards is null: try again in one minute. The figures that change on each payout are on /tokens/{mint}/rewards/pending. walletsPaid counts the distinct wallets ever paid in that asset. Fee recipient payouts are not in these totals: see /tokens/{mint}/rewards/fee-recipients. Each *Raw field is an integer string. Each *Tokens field is null when the decimals are not known.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/tokens/{mint}/rewards/holders":{"get":{"tags":["Data"],"summary":"Token rewards paid to holders","description":"Lifetime totals of what the holders of a reward coin were paid. The body is {mint, mode, quote, basis, rewards, base, generatedAt}. These are the /tokens/{mint}/rewards totals, which do not include fee recipient payouts. rewards is {distributedRaw, distributedTokens, payoutCount} in the quote token. base is the same in the launch token with an asset field, and is null when no holder was paid in it. mode has the same meaning as on /tokens/{mint}/rewards. basis is \"ledger\". basis: \"awaiting-ledger\" means the totals are not built yet, and rewards is null: try again in one minute. Each *Raw field is an integer string. Each *Tokens field is null when the decimals are not known.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/tokens/{mint}/rewards/fee-recipients":{"get":{"tags":["Data"],"summary":"Token rewards paid to fee recipients","description":"What a StandardV2 launch paid its fee recipients, and one page of its recipient wallets. The body is {mint, quote, shareBps, recipientCount, rewards, base, rows, page}. shareBps is the share of the transfer fee all recipients take together. recipientCount is the number of current recipients. rewards is what they were paid in the quote token, and base what they were paid in the launch token, null when nothing was. Each paid figure is {distributedRaw, distributedTokens, payoutCount, lastPayoutAt}, delivered payouts only. Each row is {wallet, isCreator, slot, shareBps, asset, quote, base}. isCreator is true for the wallet that launched the token. shareBps and asset are null for a wallet that is no longer a recipient. A quote recipient can also be paid in the launch token. A launch with no fee recipients answers 404. Each *Raw field is an integer string. Each *Tokens field is null when the decimals are not known.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to asc: current recipients in slot order, then former ones. Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/tokens/{mint}/rewards/pending":{"get":{"tags":["Data"],"summary":"Token rewards not yet paid","description":"What holders of a reward coin are owed and have not received. The body is {mint, mode, quote, pending, base, generatedAt}. In pending, undistributedRaw is in the pot and not yet allocated. queuedRaw is allocated, and its funding transfer has not landed. inFlightRaw is in the distribution wallet, and waits for delivery or for the holder to open a token account. strandedRaw cannot be delivered and waits for an admin. What holders are owed is undistributedRaw + queuedRaw + inFlightRaw. base gives the same figures, without undistributed, in the launch's own token, and is null when they are all zero. What is owed to fee recipients is not in these figures. Each *Raw field is an integer string, with a *Tokens field next to it.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/tokens/{mint}/rewards/payouts":{"get":{"tags":["Data"],"summary":"Token reward payouts","description":"One page of the payouts delivered to holders of a reward coin. The body is {rows, page}. Each row is {signature, holder, assetMint, amountRaw, amountTokens, createdAt}. One signature can pay many holders. assetMint is the quote token, or the launch mint for a payout in the launch's own token. amountTokens is null when the decimals are not known. Fee recipient payouts are not in the rows: see /tokens/{mint}/rewards/fee-recipients.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to desc (newest first). Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/rewards/launches":{"get":{"tags":["Data"],"summary":"Reward totals by launch","description":"One page of lifetime reward totals, one row for each launch and the asset it paid. The body is {asset, sort, basis, rows, page}. Each row is {mint, asset, distributedRaw, distributedTokens, payoutCount, walletsPaid, lastPayoutAt}. asset is {mint, symbol, decimals}. walletsPaid counts the distinct wallets ever paid in that asset. sort=distributed orders by distributedTokens and leaves out rows whose decimals are not known. Amounts in different assets are compared as token counts, not by value. sort=recent orders by lastPayoutAt. Totals include payouts up to about one minute old. basis: \"awaiting-backfill\" means the totals are not built yet, and rows is empty.","parameters":[{"name":"asset","in":"query","required":false,"description":"Defaults to quote. base lists rewards paid in the launch's own token.","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"Defaults to distributed. desc gives the largest or the newest first.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to desc (newest first). Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/rewards/payouts":{"get":{"tags":["Data"],"summary":"Reward payouts, all launches","description":"One page of the payouts delivered to holders of every reward coin. The body is {rows, page}. Each row is {signature, launchMint, holder, assetMint, amountRaw, amountTokens, createdAt}. One signature can pay many holders and several launches. amountTokens is null when the decimals are not known.","parameters":[{"name":"asset","in":"query","required":false,"description":"Defaults to quote. base lists payouts made in the launch's own token.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to desc (newest first). Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/revenue/summary":{"get":{"tags":["Revenue"],"summary":"Lifetime revenue totals","description":"Lifetime fee revenue, buybacks and burns of the platform, with the configuration they come from. The body is {totals, coverage, config, generatedAt}. Totals are in USD at the time of each event. There is no live price here: multiply token amounts by priceUsd from /revenue/platform-token. totals.stonkBurnedTokens counts all platform tokens destroyed, from all sources.","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/revenue/daily":{"get":{"tags":["Revenue"],"summary":"Daily revenue series","description":"One row for each UTC day, from the first day with ledger activity to today. A page is limit consecutive days, and days with no activity are rows of zeros. The body is {network, days, page, generatedAt}. There are no running totals: add the days up, oldest first, or use /revenue/summary for lifetime totals.","parameters":[{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to desc (newest first). Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/revenue/buybacks":{"get":{"tags":["Revenue"],"summary":"Buyback ledger","description":"One page of platform-token buybacks. The body is {rows, page}.","parameters":[{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to desc (newest first). Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/revenue/burns":{"get":{"tags":["Revenue"],"summary":"Burn ledger","description":"One page of one burn ledger. The body is {rows, page}. A source that is not in the list answers 400, and so does a cursor issued for the other source.","parameters":[{"name":"source","in":"query","required":false,"description":"Defaults to buyback.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to desc (newest first). Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/revenue/platform-token":{"get":{"tags":["Revenue"],"summary":"Platform token price","description":"The live price, market cap and supply of the platform token. The body is {platformTokenMint, priceUsd, marketCapUsd, supplyTokens, generatedAt}. Each figure is null when its chain read failed.","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/revenue/platform-token/history":{"get":{"tags":["Revenue"],"summary":"Platform token price history","description":"The median price of each day that had a priced buyback, and the supply figures to calculate past FDV. The body is {days, supplyTokens, burnedTokensLifetime, originalSupplyTokens, page, generatedAt}. A page covers limit calendar days, and a day with no buyback is not in days, so a page can be short or empty before the end. Use the price of the day before, not zero. Supply on a day = originalSupplyTokens minus the stonkBurnedTokens of /revenue/daily summed up to that day.","parameters":[{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25. A value out of range is clamped.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Defaults to desc (newest first). Send the same order with every cursor.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"page.nextCursor from the previous response. Omit it for the first page. A cursor from a different endpoint or order answers 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v2/revenue/platform-token/split":{"get":{"tags":["Revenue"],"summary":"Fees paid in the platform token","description":"What launches quoted in the platform token paid, and where it went: the burned share and the treasury share. The base* fields are the fees of the platform token's own pool. baseIncomeBurned says if those are burned. sweptTokens covers both income streams together and you cannot divide it between them.","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tokens":{"get":{"tags":["Data"],"summary":"List and search tokens","description":"Every token with a live platform pool, with market data. Works without a key at a lower rate limit. V3 reward tokens additionally carry transferFee.bps (a Token-2022 transfer tax paid to holders — use the Token-2022 program for their accounts) and, while in the buyback rankings, flywheel.active. Community Mode tokens carry communityMode.shareBps: the share of every holder payout that goes to holders of the quote token instead. StandardV2 tokens carry feeRecipients.shareBps: the share of the transfer tax paid to the fee recipients set at launch (the creator by default) before holders.","parameters":[{"name":"q","in":"query","required":false,"description":"Search name, symbol or mint.","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"Defaults to marketCap.","schema":{"type":"string"}},{"name":"mode","in":"query","required":false,"description":"Filter by fee model.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by graduation status.","schema":{"type":"string"}},{"name":"quoteMint","in":"query","required":false,"description":"Filter by paired token.","schema":{"type":"string"}},{"name":"category","in":"query","required":false,"description":"Filter by pair category, e.g. xstock.","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Defaults to 1.","schema":{"type":"string"}},{"name":"pageSize","in":"query","required":false,"description":"1-100, defaults to 25.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/tokens/{mint}":{"get":{"tags":["Data"],"summary":"Get one token","description":"Live market data plus the launch record, when the platform launched it. V3 reward tokens carry the same optional transferFee, communityMode, feeRecipients and flywheel fields as /tokens.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/tokens/{mint}/burns":{"get":{"tags":["Data"],"summary":"Token burn history","description":"Totals and recent burns of this token by the platform fee sweep.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/tokens/{mint}/rewards":{"get":{"tags":["Data"],"summary":"Token holder rewards","description":"Distribution totals for a reward coin. Standard launches answer with mode \"standard\" and a null rewards object. Amounts under \"rewards\" are quote-token amounts; the separate \"base\" object carries what the launch paid holders in its OWN token, and is null when that has never happened.\n\nDeprecated. Use GET /v2/tokens/{mint}/rewards and GET /v2/tokens/{mint}/rewards/pending instead. v2 splits the figures: lifetime totals are on /rewards and the undistributed, queued, inFlight and stranded figures are on /rewards/pending. Each base object is null on its own. v2 does not read the chain, so quote.decimals and the *Tokens fields are null where v1 read the decimals from the mint account. Before the totals are first built, v2 gives basis: \"awaiting-snapshot\" where v1 gives 503.","deprecated":true,"parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/tokens/{mint}/airdrop":{"get":{"tags":["Data"],"summary":"Token launch airdrop","description":"The airdrop a token launched with, if any: what share of supply was carved out of the pool, how many wallets received it, and where those wallets came from. Reads the frozen snapshot taken at quote time, so it is the drop that was actually paid for rather than a live balance scan. A token that launched without one answers airdrop: null, which is not an error — most tokens have no airdrop.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/tokens/{mint}/fees":{"get":{"tags":["Fees"],"summary":"Creator claimable fees","description":"Trading fees currently claimable by the creator of a standard (fee coin) launch, in both the base and quote token. Needs no wallet, so a dashboard can show what is waiting before anyone connects. Reward coins and pump launches return claimable: null with a reason rather than an error. LaunchLab launches answer the same way for a different reason: a standard one accrues creator fees, a share of the platform fee that is FORWARDED to the creator automatically, with nothing to claim by signature, and a reward one distributes the mint’s transfer tax to holders and has no creator fees. Where a LaunchLab creator does have a claimable balance it is quote-side only, and scope: \"creator-quote-vault\" says the amount covers every launch that creator has against this quote token, not this one alone.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/tokens/{mint}/fees/claim/prepare":{"post":{"tags":["Fees"],"summary":"Step 1: prepare a fee claim","description":"Returns an UNSIGNED transaction that pays the creator their claimable trading fees, plus the amounts it will collect. Sign it with the wallet holding this launch’s Fee Key NFT — on a LaunchLab launch there is no Fee Key NFT and the creator wallet itself signs, draining its per-quote fee vault — and post it to /fees/claim/submit. Non-custodial: the claim is only valid signed by that wallet and pays that wallet’s own token accounts, so no platform key signs anything and a claim prepared for a token you do not own is unusable. Standard (fee coin) launches only — reward coins and pump launches answer 403. 409 when nothing is claimable yet. Expires after 90 seconds; just prepare again, fees keep accruing.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["creatorWallet"],"properties":{"creatorWallet":{"type":"string","description":"The creator wallet holding the Fee Key NFT. It must be the fee payer of the transaction you sign."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/tokens/{mint}/fees/claim/submit":{"post":{"tags":["Fees"],"summary":"Step 2: submit the signed claim","description":"Relays the signed claim and waits for confirmation, answering with the transaction signature. Fees land directly in the creator’s token accounts. Only the exact transaction issued by /prepare is relayed — instructions are checked against the recorded intent. Idempotent per intentId: an intent already relayed returns its original signature with alreadySubmitted: true, so a retry after a timeout cannot claim twice.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["creatorWallet","intentId","signedTransaction"],"properties":{"creatorWallet":{"type":"string","description":"The same wallet passed to /prepare."},"intentId":{"type":"string","description":"From /fees/claim/prepare."},"signedTransaction":{"type":"string","description":"The transaction from /fees/claim/prepare, signed by the creator wallet."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/tokens/{mint}/backing":{"get":{"tags":["Data"],"summary":"Token backing value","description":"USD permanently locked behind a pump-launched token, summed from the platform’s own locked positions. Pump launches only: every other launch — Raydium CLMM and LaunchLab alike — answers 400 invalid_request rather than a zero, since backing is not a thing those have. Check launchpad from /tokens/{mint} before calling.","parameters":[{"name":"mint","in":"path","required":true,"description":"Token mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/launches":{"get":{"tags":["Data"],"summary":"List launches","description":"The launch ledger, newest first. Filter by creator to find your own. Launches built directly against the venue appear here too, once adopted, under launchpad \"launchlab\" — no payment of ours exists for those, so they are read here or from /api/v2/launches/{mint} rather than by polling a payment signature.","parameters":[{"name":"creator","in":"query","required":false,"description":"Filter by creator wallet.","schema":{"type":"string"}},{"name":"mode","in":"query","required":false,"description":"Filter by fee model.","schema":{"type":"string"}},{"name":"since","in":"query","required":false,"description":"Only launches at or after this time.","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Defaults to 1.","schema":{"type":"string"}},{"name":"pageSize","in":"query","required":false,"description":"1-100, defaults to 25.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/pairs":{"get":{"tags":["Data"],"summary":"List launchable pairs","description":"Quote tokens a new launch can be paired against. Call this first — quoteMint must be one of these. Two different gates apply and both are reported: `launchable` is this platform’s own rule (retired categories and mints are false), while `launchLabReady` says whether Raydium has created the on-chain GlobalConfig a LaunchLab launch needs. A pair can be launchable but not yet LaunchLab-ready; constructing a launch against one of those fails on-chain. `launchLabReady` is absent rather than false when the venue is off or the probe could not run. `communityMode` says whether a Community Mode launch can pair against the token, the same answer as `communityMode.offeredOnThisQuote` in GET /launchlab/pricing; it is absent while the venue is off. `standardV2Enabled` says whether StandardV2 launches are enabled on this deployment. When it is true, every LaunchLab-ready pair accepts a StandardV2 launch.","parameters":[{"name":"category","in":"query","required":false,"description":"Filter by category.","schema":{"type":"string"}},{"name":"launchable","in":"query","required":false,"description":"Set true to exclude retired categories.","schema":{"type":"string"}},{"name":"launchLabReady","in":"query","required":false,"description":"Set true to return only pairs with a live LaunchLab config on-chain.","schema":{"type":"string"}},{"name":"communityMode","in":"query","required":false,"description":"Set true to return only pairs a Community Mode launch can pair against.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/rewards":{"get":{"tags":["Data"],"summary":"Rewards overview","description":"Lifetime payout totals per reward coin plus recent distribution transactions. \"launches\" and \"recentDistributions\" are quote-token amounts only; rewards paid in a launch's own token appear in \"baseDistributions\" and \"recentBaseDistributions\". In those two, \"decimals\" and the token amount are null together when the launch record cannot be resolved — read the raw amount instead of scaling it yourself. \"launches\" and \"baseDistributions\" are sorted by amount distributed and paged together by \"page\" and \"pageSize\"; each reports its own total in \"launchesPagination\" and \"baseDistributionsPagination\", and a page past its end is empty. Symbol and decimals for every quote mint in the response are in \"quotes\", keyed by mint (and in the \"quote\" object of each row). total and totalPages are null: read pages until one has fewer than pageSize rows. Rows whose decimals are not known are left out.\n\nDeprecated. Use GET /v2/rewards/launches and GET /v2/rewards/payouts instead. v2 pages each list with a cursor (page.nextCursor) instead of page numbers, and asks for quote and base totals separately with asset=quote|base. v2 gives walletsPaid where v1 gives holderCount, and one payout row per holder where v1 groups recent distributions by signature.","deprecated":true,"parameters":[{"name":"limit","in":"query","required":false,"description":"Recent distributions, 1-100, defaults to 25.","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Defaults to 1.","schema":{"type":"string"}},{"name":"pageSize","in":"query","required":false,"description":"1-1000, defaults to 100.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/revenue":{"get":{"tags":["Revenue"],"summary":"Platform revenue and burns","description":"Fee revenue, buybacks and burns.\n\nDeprecated. Use GET /v2/revenue/summary and GET /v2/revenue/buybacks and GET /v2/revenue/burns instead. v2 does not return burns.totalValueUsdAtBurn, burns.burnCount, burns.mintCount, the burn totals of sources other than buyback and quote-revenue, config.buybacksEnabled or config.buybackBurnEnabled.","deprecated":true,"parameters":[{"name":"limit","in":"query","required":false,"description":"1-100, defaults to 25.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/revenue/history":{"get":{"tags":["Revenue"],"summary":"Daily revenue series","description":"Whole daily history in one response, keyed by UTC day, in USD. dailyRevenue is quote-token fees claimed to the treasury valued at claim time, and sums to the \"Total revenue\" figure on the /revenue page; dailyHoldersRevenue is the share spent buying the platform token back and burning it; dailyProtocolRevenue is the remainder. Fees earned by creator and reward-holder positions are claimed directly from Raydium and are not included. A coverage block reports ledger rows that carry no USD price and therefore count as zero. No date parameter by design — fetch once and index locally.","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/stats":{"get":{"tags":["Data"],"summary":"Platform stats and config","description":"Aggregate totals plus the thresholds and switches a client needs, so your UI tracks the platform instead of hardcoding it. config.paidLaunchesEnabled and config.launchLabEnabled together say which launch path is live: the two-call /launches flow, the transaction you build yourself, or both. Read them before offering a launch button.","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/launches/{paymentSignature}":{"get":{"tags":["Launch"],"summary":"Launch status","description":"Poll this after a \"processing\" response until status is \"completed\".","parameters":[{"name":"paymentSignature","in":"path","required":true,"description":"Signature of the fee payment.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/launchlab/platforms":{"get":{"tags":["Launch"],"summary":"Platform ids for a launch you build yourself","description":"The LaunchLab program id and the PlatformConfig id each launch mode attributes to: `platform.standard` for an untaxed mint, `platform.reward` for a taxed one, and `platform.community` for a Community Mode launch. `community` is absent where Community Mode is not configured. These are the same values as `platform` in GET /launchlab/pricing. A platform id can change, so read it on every build.","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/launchlab/pricing":{"get":{"tags":["Launch"],"summary":"Curve pricing for a launch you build yourself","description":"Everything needed to size and attribute a LaunchLab launch you construct YOURSELF, instead of through /launches/prepare: the exact raw totalFundRaisingB to pass so the launch opens and graduates at the same market caps as one launched here, the caps that raise produces, the virtual reserves the program will derive from it, and the remaining create-instruction constants. The raise is a RAW amount in the quote’s own decimals — reusing Raydium’s 85-SOL lamport constant on another quote is the mistake this endpoint exists to prevent. `platform.standard` / `platform.reward` are the platform ids to attribute the create to; standard mode is deprecated, so build new launches as StandardV2. and `modes.reward.transferFeeBps` the holder-tax tiers this platform publishes. `allowConfig` carries the per-platform allow-config account to always append (read-only) before the curve-rule account; a platform that restricts its quote configs refuses an initialize without it, and one that does not ignores it. `allowConfig.available[mode]` is false when that on-chain configuration refuses this quote now, and null when it could not be read. A mode that is not available is left out of `allowConfig.required`. `curveRule` carries the per-platform rule account to append as the LAST (read-only) account of the initialize instruction: once a platform enforces its launch shape on-chain, an initialize without it is refused outright (6018), and one outside the published shape is refused too (6025) — append it now and both futures are covered. A pool built to exactly this shape is adopted automatically once it lands — same token page, same fee forwarding, same holder rewards as a launch made through the API; one built to any other shape is left alone, which for a taxed mint means nobody ever collects the tax. Prices move, so a raise is only as current as prices.observedAt; nothing is reserved by calling this. To launch a reward token in Community Mode, build it on `platform.community`, with that platform's `allowConfig` and `curveRule` accounts: the platform is what makes the mode. `communityMode.offeredOnThisQuote` says whether Community Mode is offered on this quote. `communityMode.quotes` is deprecated and will be removed: get the list from GET /pairs?communityMode=true. Payouts in the launch's own token go to its own holders only; the community share applies to payouts in the quote. `standardV2Enabled` says whether StandardV2 launches are enabled on this deployment. While it is true, build a StandardV2 launch on `platform.standardV2` with a rate in `modes.standardV2.transferFeeBpsRange`; its transfer fee goes to the pool creator first.","parameters":[{"name":"quoteMint","in":"query","required":true,"description":"Mint address of the quote token to price against, from GET /pairs.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/launchlab/intent":{"post":{"tags":["Launch"],"summary":"Record fee recipients for a StandardV2 launch you build yourself","description":"Records who is paid the transfer fee of a StandardV2 launch you build yourself, before you create its mint. Without it the launch pays its creator 100% of the fee, in the quote, and its holders get none of it. List up to 10 recipients, each with its share in bps and the token it is paid in, and set holderShareBps to the share holders get. The recipient shares and holderShareBps must add up to exactly 10000. Sign this text with the MINT keypair, lines joined with `\\n`, and send the signature base58-encoded:\n\n```\nstonkfun launch intent v2\nmint: <mint>\nissued: <issuedAt, exactly as sent>\nfeeRecipient 0: <recipient> <shareBps> <quote|base>\nfeeRecipient 1: ...\nholders: <holderShareBps>\n```\n\nissuedAt must be within the last 10 minutes. Recipients can only be recorded once, before the mint exists: the same request again answers 200, a different one 409, and so does a mint that already exists. Read the result back with GET /launchlab/intent/{mint} before you send the create.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mint","issuedAt","feeRecipients","holderShareBps","signature"],"properties":{"mint":{"type":"string","description":"The address of the mint keypair you will create the launch with."},"issuedAt":{"type":"string","description":"When you signed, as an ISO-8601 time. Signed exactly as sent."},"feeRecipients":{"type":"string","description":"1 to 10 entries, in slot order. Every field is required: there is no default recipient, because the creator is not known yet. No wallet may appear twice, and platform and exchange wallets are refused."},"holderShareBps":{"type":"string","description":"The share of the transfer fee that goes to holders, in bps, from 0 to 9999. With the recipient shares it must add up to exactly 10000."},"signature":{"type":"string","description":"The mint keypair’s Ed25519 signature of the text above, base58-encoded."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}},"/api/public/v1/launchlab/intent/{mint}":{"get":{"tags":["Launch"],"summary":"Read back the fee recipients recorded for a mint","description":"The fee recipients recorded for a mint, before and after it launches, with `status`: `none`, `recorded` (waiting for the launch), `applied` (launched as StandardV2 with exactly these recipients), `ignored` (launched on another platform, so they are not used) or `mismatch`. `holderShareBps` is the share holders get. Send the create only once this shows what you asked for.","parameters":[{"name":"mint","in":"path","required":true,"description":"The mint address.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"meta":{"type":"object"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","forbidden","not_found","method_not_allowed","conflict","rate_limited","internal","service_unavailable"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retryAfterSeconds":{"type":"integer"}}}}}}}}}}}}}