Updates and announcements will be posted here as they become available.
2026-08-06 — Every trading endpoint now requires an API key
/swap/sol/buy and /swap/sol/sell were callable with no credentials. That
tier is gone: both now answer 401 like the rest of the API.
What changes for you
- If you send an API key today, nothing changes. Same request, same response, same fees.
- If you were calling buy/sell without a key, create one at
raze.bot and send it as
Authorization: Bearer sk_…,X-API-Key: sk_…, or?apiKey=sk_….
feeWallet /
feeBps you sent. With a key those fields are yours: set them and the fee goes
where you say, omit them and the transaction carries no platform fee and no
tip at all. Nothing is added on our side.
feeTipLamports is removed. It only ever existed to override the public
tier’s forced tip. Use tipWallet + tipLamports for a tip you control. The
field is ignored if you keep sending it — no request will break on it.
Round-trips (/swap/sol/buy-sell, /swap/sol/sell-buy) always required a key;
the docs said “auth optional”, which was wrong. They are unchanged.
2026-07-30 — Bags: launches can now configure their fees
Requested by an integrator. Until today abags launch could not say who earns
the coin’s trading fees or which fee template it launches on — both were
fixed server-side, and a launch that meant to split its fees succeeded, traded
normally, and paid the collaborator nothing.
Two new optional fields, bags only:
-
bagsFeeClaimers— the recipients, named by handle rather than address (provider,username,bps). Bags resolves a handle to that person’s embedded wallet, so someone can be paid before they have ever connected one. Providers:twitter,tiktok,kick,github,instagram,onlyfans, andsolanafor a raw address. List only the other recipients —wallets[0]keeps the remainder, so the numbers you send are the ones you give away. -
bagsConfigType— the fee template (Bags’MeteoraConfigTypeid), which decides the swap fee, the migration split, how much compounds back into liquidity and how much supply is locked.
pumpfun and bonk, which have no fee-share
config to put them in.
Two clarifications on the same platform, no behaviour change:
slippageBpsdefaults to 500 (5%) onbags, as onbonk— the later buyers’ prices are modelled exactly against the curve, so a 99% floor would be protection in name only. This was previously undocumented.- Who attaches the Jito tip inverts with the wallet count. With 1–3 wallets
the bundle has a free slot: send
jitoTipAmountSol: 0and append your own tip transaction. With 4 wallets all five slots are full and there is nowhere to append — passjitoTipAmountSoland we embed it on the last buy.
ba28db46-… (DEFAULT_96_LOCKED) explicitly, precisely so
the template cannot change under a caller when Bags changes a default. What was
missing was the ability to override our pin — which is what bagsConfigType
now does.
2026-07-30 — Bonk: bonkType: "bonkers" was selecting the wrong platform config
Reported by an integrator, verified against the chain and against letsbonk’s own
frontend bundle. If you send bonkType: "bonkers", read this.
- 🔴
bonkersresolved toBuM6KDpW…, which is letsbonk’s Balanced mode, not Bonkers. On chain that config charges 1.25% swap fee and no creator fee — identical economics tostandard, so the option changed nothing you could measure while promising the mode letsbonk’s UI describes as “This mode has creator fees”. A launch that asked for Bonkers paid 25 bps more on every swap and accrued zero creator fee. - ✅
bonkersnow resolves to82NMHVCK…— letsbonk’stechPlatformId, the mode their UI labels Bonkers: 1.00% swap fee and 0.05% creator fee. It is the only one of the three that pays the token creator. - The old target is still reachable, by its real name:
balanced. letsbonk’s own identifiers are accepted as aliases too (platformId,techPlatformId,balancedPlatformId, plusmemesandtech). - 🆕
platformConfigaccepts an explicit LaunchLab platform-config address. There are ~2000 on chain — 30 of them namedletsbonk.funalone — so no set of names can cover them. It is verified on chain before use (exists, owned by LaunchLab, carries thePlatformConfigdiscriminator), so a wrong value is a 400 rather than a silent fall back to the default. Mutually exclusive withbonkType. - 🆕
supplyandtotalBaseSellnow accept a decimal string as well as a number. They areu64, and the letsbonk UI offers supplies up to 1e18 base units — pastNumber.MAX_SAFE_INTEGER(9.007e15), so from JavaScript a numeric literal such as123456789123456789is rounded to…780before the request is even sent. Strings carry all 64 bits; letsbonk’s own frontend sends them that way. Same forvesting.totalLockedAmount, which scales withsupply. configAddressis now rejected onpumpfun,bonkandbags. It is a Meteora field and did nothing on those platforms, but it was accepted silently — even when it was not valid base58 — so “ignored” and “accepted” were indistinguishable from the response.- The
bonkTyperejection message now lists every accepted value. It used to omitletsbonk, which is both documented and accepted.
2026-07-30 — Launch on Bags (bags.fm)
Deploy API
platform: "bags"is available on/utils/sol/launch. A Bags launch is a Meteora DBC launch under Bags’ own authority, and it is the first venue here that is not built entirely on our side.- Why that matters to you. On a Bags
initialize, the poolcreator, thepayerand the vanity…BAGSbase mint are all signed by Bags. Their launch transaction therefore arrives already signed, and adding or removing a single instruction would invalidate that signature. So:- the first two transactions in the bundle are Bags-signed — pass them through untouched, do not re-serialise or re-order them;
- at most 4 wallets fit, not 5: their two transactions occupy the front of the Jito bundle;
mintKeyandmintPubkeyare rejected — the mint is theirs, and so is the…BAGSvanity suffix;- exactly one transfer of ours can ride on their launch transaction. Asking
for both a
feeWallet/feeBpsand atipWallet/tipLamportson a single-wallet launch is a 400, not a silently dropped leg. With a second wallet the tip moves to the last buy; jitoTipAmountSolon a single-wallet launch is a 400 for the same reason — both transactions are sealed. Send the tip as its own bundle transaction.
- The curve is Bags’, not yours.
supply,totalBaseSell,fundRaisingSol,fundRaisingQuote,decimals,vestingandconfigAddressare rejected, not ignored: the bonding curve and the token decimals come from Bags’ config template. Accepting those fields and dropping them would let you believe you had shaped a curve you never touched. - Bundled buys still work.
wallets[0]’s amount becomes the first buy inside Bags’ transaction; every further wallet gets its own buy, priced against the curve as the earlier buys leave it, with a 500 bps default floor. If the curve cannot be read, the launch is refused rather than sent withminimumAmountOut = 0— an unprotected bundle is a gift to whoever is watching. - Responses now carry
config, the per-token Meteora DBCPoolConfig, next tomintandpool. You need it to build any later swap of your own, and unlike the pool it is not derivable from the mint. quoteMintaccepts"SOL"(or omission) only on this platform; anything else is a 400, never a fallback.token.descriptionis required onbags— Bags rejects an empty one. It stays optional onpumpfunandbonk.
meteora_dbc and meteora_cpamm remain unimplemented. Note that meteora_dbc is
not the same product as bags: it would be a DBC launch under a config of ours,
with our fees and no Bags branding.
2026-07-29 — Launch on Bonk (Raydium LaunchLab)
Deploy API
platform: "bonk"is live on/utils/sol/launch, covering letsbonk.fun and Bonkers (bonkType). The create instruction is built in-process rather than fetched from letsbonk’s backend, so a launch with your own mint key costs zero third-party round-trips.- Bundled buys.
wallets[0]is the creator and its amount becomes a first buy fused into the create transaction; each further wallet gets its own buy, priced against the curve as the earlier buys leave it. Up to 5 wallets (the Jito bundle cap). Buy slippage defaults to 500 bps here, not pumpfun’s 9900. - The curve is yours:
supply,totalBaseSell,fundRaisingSol,decimals. Bounds are checked against the launchpad’s on-chainglobal_config, so an out-of-range curve returns a message naming the offending minimum instead of an opaquecustom program error: 0x9ca. Those minimums drift on chain, so they are read live rather than hardcoded. mintPubkeyis rejected onbonk— deliberately, not overlooked. The base mint has to sign the create, and LaunchLab has no equivalent of pump’ssign-create-tx, so an address without its secret cannot be signed by anyone. Send the 64-byte secret asmintKey, or omit both and one is generated for you. For the same reason the official…bonkvanity suffix is unavailable: it only comes from letsbonk’s own endpoint, which returns their transaction, not yours.- Launch responses now carry
pool, the derived curve address, on venues that know it before the transaction lands.
meteora_dbc and meteora_cpamm remain unimplemented.
Same day — USD1 curves, vesting, and your fee on Bonk
- USD1-quoted launches. LaunchLab keeps a separate
global_configper quote asset, soquoteMint: "USD1"selects a different config, a different pool address and a buy leg with no wrap step. Its limits are its own: the minimum raise is 5 000 USD1 against the SOL config’s 24 SOL. Buyers must already hold USD1 in their associated token account; the account is never closed. An unrecognisedquoteMintis a 400, never a silent fallback to SOL — a launch denominated in the wrong asset cannot be undone. fundRaisingQuotereplacesfundRaisingSolas the general form: whole quote tokens, whichever asset that is.fundRaisingSolstill works on SOL launches and is rejected on USD1 rather than reinterpreted.- Vesting.
vesting.totalLockedAmount/cliffPeriod/unlockPeriodmap straight onto LaunchLab’sVestingParams. The locked share is checked against the config’smax_lock_ratebefore we build anything. feeWallet+feeBpsnow work onbonk— they were being accepted and ignored. The fee is charged in the quote asset on each buyer’s raw amount, including the creator’s buy fused into the create (which differs frompumpfun, where the fused first buy is not charged). It is our own fee leg and has nothing to do with LaunchLab’s nativeshare_fee_rate, which we send as0.tipWallet/tipLamportsare honoured onbonkas onpumpfun, andjitoTipAmountSolrides the last buy only — never a create. Abonkresponse contains no lookup table at all, so a tip you attach yourself is always a visible static key.- Corrected in these docs:
jitoTipAmountSolwas documented with a0.001default. The effective default is0— omit it and no tip is embedded. - Corrected after an integrator report: several field descriptions in the request
schema stated
pumpfunbehaviour as if it were the endpoint’s behaviour, which contradicted the prose above them.quoteMint,mintKey,mintPubkey,computeUnitPriceandcomputeUnitLimitnow say what each platform does. The sweep also turned up a real defect rather than a wording one, now fixed:computeUnitPricewas documented with a 50000 default that onlypumpfunapplied. Abonklaunch that omitted the field emitted no compute-budget instruction at all — zero priority fee, and no unit limit either. bonknow emits a compute budget on every transaction. Price defaults to 50000 on both platforms. Limits default to 400000 on the create (+ fused first buy) and 120000 on each subsequent buy — ≈1.8× the measured worst case, deliberately notpumpfun’s 600000 for a buy, because Solana charges the priority fee on the units requested rather than consumed and abuy_exact_inmeasurably costs ~50000. SendcomputeUnitLimitto override.- The budget costs 52 bytes, and the widest
bonkshapes are within that of the 1232-byte wire limit. So instead of rejecting a launch that would otherwise fit, a transaction gives things up in a fixed order, recoverable losses first: a rent-reclaim instruction (theclose_accounton a SOL launch — ~0.00204 SOL of rent left in your own account, closable any time; a no-op account create on a USD1 one), then the default price, then the default limit. Stranded rent is undone with one instruction; a priority fee never attached cannot be recovered. A create with a long name, a USD1 fee leg and a tip needs all three rungs and lands at 1196 bytes with no priority fee — the server logs which rung it used. - Nothing you asked for is on that list: not the fee leg, not the tip, not the
swap, and not a
computeUnitPrice/computeUnitLimityou sent explicitly. An explicit value that cannot fit fails the request and names what to shorten, rather than quietly returning a transaction without the fee you were promised.
2026-07-28 — Streaming quotes, atomic round-trips, Phoenix perps, USDC launches
Trading API
- Streaming quotes over WebSocket.
/swap/sol/quote/streamkeeps a quote fresh on one socket: subscribe to a pair + amount and the router pushes a re-quote when the pools under your route actually move — event-driven, not a fixed poll. Thedatapayload is byte-for-byte theGET /quoteshape, route ticket included, so existing REST parsing works unchanged. - Atomic round-trips.
/swap/sol/buy-sell(SOL → token → SOL) and/swap/sol/sell-buy(token → SOL → token) put both legs of a same-mint round-trip in one transaction. The second leg is chained onto the first leg’s slippage floor, so it can never overdraw the fill; the platform percentage fee is charged once on the combined SOL volume of both legs. - The quote response documents what it was already returning:
priceImpactBps,liquidityQuote/liquidityBase(bottleneck reserves — the thinnest hop is what caps depth), the per-hoproute[], the fullroutes[]set (primary first, then the alternatives the dispatcher retries on rejection), andsplitLegs[]for split-routed quotes, whereamountOutis the SUM of legs that execute atomically.GET /quotealso documents itsmaxHops/includeDex/excludeDexfilters. /swap/sol/instructionsdocumentsserialize: true(returns a ready-to-sign unsigned v0transaction), themaxHops/includeDex/excludeDexroute filters,feeOnInputandfeeTipLamports.- Buy and sell responses carry
amountsOut— the output the built transaction actually delivers (its on-chainmin_return), index-aligned withtransactionsandnullwhere no route was found. It can sit below theamountOutof an earlier quote when the best-priced plan didn’t fit the wire and a lower-output alternative was served. - Correction in these docs: the
slippageBpsdefault on/swap/sol/buyand/swap/sol/sellis 500 (5%), not the 9990 previously shown here. The server has always applied 500 when the field is omitted — pass the value explicitly if you were relying on the documented number.
Perpetuals
- Edit collateral:
/perp/sol/collateraladds or withdraws margin on an open Jupiter position without changing its size. The position PDA is derived server-side and is never client-supplied. - Phoenix is documented as a first-class venue.
/perp/sol/marketslists Phoenix markets live from the venue (new listings need no router deploy), and the Phoenix surface is published:phoenix-position,phoenix-collateral,phoenix-deposit,phoenix-withdraw,phoenix-cancel,phoenix-cancel-bracket. Fund the cross account before ordering — an unfunded account silently 0-fills. - Phoenix-only fields on the shared endpoints:
limit_price_e6on/perp/sol/order(resting limit order; Jupiter has no user-callable limit path and rejects it with 400) andclose_pct_bpson/perp/sol/close(Phoenix closes are percent-of-position, not USD-notional). - Perp responses expose
position_request,counterandposition— the PDA counter is derived deterministically fromclient_order_id, so the same request rebuilt on another edge targets the same PDA (exactly-once on-chain). A duplicate already served by another edge answers 409.
History API — launch
These were all live on the server already; the docs simply didn’t describe them.- USDC-quoted pump.fun launches.
quoteMinton/utils/sol/launchpicks the quote asset: omit it (or"SOL") for a SOL-quoted curve, or pass the USDC mintEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v. On a USDC launch everywallets[].amountis USDC and the wallets must already hold it — there is no pre-swap, so awallets[].sourceMintthat differs fromquoteMintis rejected. Rent and tips stay in SOL. Only SOL and USDC are supported: an unparseablequoteMintsilently falls back to SOL. ?dryRun=trueis retired. The launch preview estimated the bonding curve from constants compiled into the server instead of the on-chain state the launch would actually hit, so it could disagree with the launch it was previewing — and did, on USDC-quoted launches, where it reported the same saturated token count for every input size. Rather than keep a second, hand-maintained copy of pump’s curve in sync forever, we removed it: the flag now returnssuccess: false, and theestimatefield is gone from the response envelope. It is rejected rather than ignored on purpose — a silently-droppeddryRunwould turn a preview into a real launch. To size a buy before launching, use@pump-fun/pump-sdkagainst the liveGlobalaccount. Only the estimate was ever affected: the transactions have always been built from the on-chainGlobal, and fail outright if it can’t be read.- Bring your own mint.
mintKey(bs58 64-byte secret — the server signs the create leg locally) ormintPubkey(bs58 32-byte address, e.g. a vanity mint you reserved on Pump; the mint signature comes from the Pump frontend API).mintKeywins if both are sent; omit both to let the server grind one. - Skip the IPFS round-trips.
token.metadataUriembeds an already-uploaded metadata JSON as the on-chain token URI, and an/ipfs/<cid>token.imageUrlskips the image re-pin. With both, a launch does zero IPFS round-trips — the dominant deploy latency. slippageBps(0–10000, default 9900) is documented.- The response envelope documents
stages,lookupTableAddressandisAdvancedMode. A staged launch returns preparatory bundles that must land beforetransactions, and a stage withwaitForActivation: trueneeds a slot to activate before the main bundle can resolve its lookup-table addresses. - Charity fee splits.
donationConfigIdson/utils/sol/fees/configcreates the per-mint donation escrow accounts. Note the recipient you list inshareholdersis the PDA["donation-fee-pda", mint, configId], not the bareconfigId— listing theconfigIdmakes pump.fun show a truncated wallet instead of the charity’s name.
2026-07-25 — Launch bundles: the Jito tip is yours
History API
/utils/sol/launchno longer puts a Jito tip on a create transaction. The tip only ever rides the last buy transaction of the bundle. A launch that comes back as a single transaction — a bare deploy, or a deploy fused with the creator’s own buy — now carries no tip at all.- What this means for you: if you submit a single-transaction launch straight to
sendBundle, it is rejected for having no tip. Attach your own tip first. The recommended integration for every launch is to passjitoTipAmountSol: 0and append your own transfer to a Jito tip account. - Field-name correction in these docs: the tip field is
jitoTipAmountSoland the liquidity field isinitialLiquiditySol— both end inSol, notSOL. Earlier versions of this page showed the wrong casing. Unknown keys are ignored silently, so a mis-casedjitoTipAmountSOLnever reached the server and you silently got the0.001default. - Keep the tip destination out of any address lookup table: Jito requires the tip account to be write-locked in the transaction’s static account keys, and an ALT-resolved tip makes the bundle ineligible.
2026-07-19 — /utils/sol/* moved to History API
History API
- Write utilities (
transfer,burn,distribute,consolidate,launch,fees/claim,fees/config,agent/initialize) now live onhttps://api.raze.botalongside/api/sol/*reads. Same paths and bodies as before. - Docs + OpenAPI moved under History → Utilities.
Trading API
router.raze.botis swap / quote / buy / sell / instructions / perps only. Calls tohttps://router.raze.bot/utils/sol/*will 404 after the fleet cutover — point clients atapi.raze.bot.
2026-07-15 — Perpetuals, executable swaps, and sendBundle tip policy
Trading API
- Perpetuals are live.
/perp/sol/*builds Jupiter Perps + Phoenix positions —markets,quote,order,close,tpsl,modify,cancel. Historical perp data ships under/api/sol/perp/*(fills, liquidations, positions, funding) with matching GraphQL resolvers. - Executable swaps.
POST /swap/sol/instructionsacceptsserialize: trueand returns an unsigned v0 transaction withfeePayerset to your wallet, a fresh blockhash, and address-lookup tables resolved server-side — sign and send it directly. The same endpoint addsswapMode: exactOutandmaxHops/includeDex/excludeDexroute filters. - Utilities
distribute,consolidate, andfees/configare implemented (previously stubs) and return real partially-signed transactions. Thefees/claimpump.fun creator-fee path is live; the Meteora partner/creator path is still pending. Themixerendpoint has been removed.
Solana RPC
sendBundleno longer sponsors a Jito tip. Your bundle must include its own tip transaction to a Jito tip wallet or it is rejected (-32602).sendBundlealso now requires aproorenterpriseentitlement (-32001), and the default transaction encoding isbase64.- Rate limits are now documented: per API key, per minute — 60 (free) / 300 (pro) / 1000 (enterprise), each with a daily cap.
2026-06-02 — GraphQL batch token enrichment + typed topTokens
History API — GraphQL
topTokensnow returns a typedTopTokensPage(not free-form JSON) withsort(VOLUME|TXNS),platform, andhours(1–168) — parity with RESTGET /api/sol/tokens/top.tokens(mints: [String!]!)— batch up to 500 mints; nested fields mirror REST enrichment (deploy,priceChanges,tradingVolume,metadata,holders,supply,sniperBundleStats,topTraders,ohlcv). Request only the fields you need.- Root shortcuts:
tokenMetadata,tokenHolders,tokenSupply,topTraders,sniperBundleStats. - Live board queries:
liveDeploys,liveMigrations,migratingDeploys. searchTokensandstatsreturn typedSearchToken/PlatformStatsinstead of opaque JSON.
GET /api/sol/tokens/top documents the sort query parameter (volume | txns).
References: GraphQL overview, GraphQL tokens.
2026-05-26 — Enriched trade fields + USDC-pool retrocompat fix
Streaming + History APIs
USDC-quoted Token-2022 pools (TRALALERO, Bank, others launching direct on PumpSwap with USDC as the pool’s quote) were emittingsolAmount set to the priority-fee delta (~0.0001 SOL) and avgPrice in USDC/token units. The parser now detects aggregate-level USDC pools and:
- Normalises
solAmountandavgPriceinto SOL units via the live SOL/USD price hook — old clients keep rendering price × supply correctly. - Drops the trade (rather than emitting wrong units) when the price hook hasn’t been set yet (early startup) — the trade reappears on the next price tick.
WS payload shape, REST
/api/sol/tx/parse/{sig}, GraphQL Trade type, and raze.trades columns all updated 1:1. Pre-fix rows for USDC-quoted pools may be backfilled separately; filter by quoteSymbol != '' (or source != '') to restrict to post-fix rows in the meantime.
References: GraphQL trades, AsyncAPI.
2026-05-23 — DexScreener “DEX Paid” event + enriched migration payload
Streaming API
-
New event type
dex_paidon/ws/sol. Subscribe via either:- By event type:
{"action": "subscribe", "subscriptions": ["dex_paid"]}— receive every newly-paid Solana mint. - By mint:
{"action": "subscribe", "tokenMint": "<mint>"}— receive adex_paidevent for that mint alongside trades and other events.
url,icon,header,description,links[]) so clients can render the badge and project socials without a follow-up REST call. Source: DexScreener’s public/token-profiles/{latest,recent-updates}/v1WS, filtered tochainId=solanaon the streaming bridge. Status is monotonic — oncetruefor a mint, never demoted. See the Streaming API reference for the full schema. - By event type:
-
The existing
migrationevent payload is now documented in full —data.platform,data.mint,data.quoteMint,data.pool,data.poolDex,data.slot,data.signature, plus the delay-0 reservesdata.baseReserve/data.quoteReserve. The broadcaster already coalesces pump.fun’sComplete+Migratepair into one event per(mint, kind)inside a 2-second window, so consumers see a single migration per token.
History API
-
GET /api/sol/tokens/metadata/{tokenMint}now returnsmetadata.dexPaid(boolean, nullable) andmetadata.dexscreenerUrl(string, nullable):dexPaid: true— the team paid for DexScreener Enhanced Token Info.dexPaid: false— confirmed not paid (resolved via DexScreener/orders).dexPaid: null— the backend hasn’t resolved this mint yet; an on-demand check is enqueued in the background, and the next call returns the answer.dexscreenerUrl— present when the live WS feed has delivered a profile URL for this mint (always populated for tokens that became paid while the streaming bridge was running).
/orderscalls well under the 60 req/min ceiling, so you cannot trip the upstream limit by hitting this endpoint hard.
