Carbium API

Pump.fun Curve Quotes (fft)

Use fft=1 on Q1 to price SOL pairs with pump.fun tokens on their live bonding curve and get back a transaction that trades on pump.fun directly.

Use fft=1 when your integration trades pump.fun tokens that are still on their bonding curve. New launches are quotable within milliseconds of creation.

fft is an optional query parameter on the Q1 GET /api/v2/quote request. It keeps the Q1 parameters, the X-API-KEY header, and the Q1 response schema. When one side of the pair is SOL and the other is a pump.fun token on its bonding curve:

  • the quote is priced on the curve's live state with pump.fun's own fee math, including pump.fun's protocol and creator fees
  • with user_account, txn is an unsigned transaction that trades on pump.fun directly: buy_exact_sol_in to buy, sell to sell
  • curves quoted in another token (USDC, PUMP and others) are served too, in SOL or in their own quote token; see Curves quoted in another token

Any other pair, and any token that has graduated to PumpSwap, is answered by normal Q1 routing. On a SOL pair whose token is not a pump.fun coin, fft=1 first adds an RPC read and up to 60 ms, so send it on quotes for tokens that may be pump.fun coins.

Part of the Carbium Solana infrastructure stack.


What this page owns

This page owns the fft=1 behavior of Q1:

Surface What it does
GET https://api.carbium.io/api/v2/quote with fft=1 Prices SOL and pump.fun bonding-curve pairs on the live curve and can return a transaction that trades on pump.fun directly

Use other pages when the question changes:


When fft=1 applies

Request Answered by
src_mint is SOL, dst_mint is a pump.fun token on its bonding curve The curve: a buy through pump.fun buy_exact_sol_in
src_mint is a pump.fun token on its bonding curve, dst_mint is SOL The curve: a sell through pump.fun sell
The token has graduated to PumpSwap Normal Q1 routing
src_mint is SOL, dst_mint is a pump.fun token on a curve quoted in another token Two legs in one transaction when that quote token is served: SOL to the quote token on a DEX pool, then pump.fun buy_exact_quote_in_v2
src_mint is such a token, dst_mint is SOL Two legs: pump.fun sell_v2, then the quote token to SOL
The curve's own quote token and its pump.fun token, either way (for example USDC to the token) The curve, priced and paid in the quote token
A curve quoted in a token that is not served, or whose leg pool is unavailable right now Normal Q1 routing, usually 422 no_route
Any other pair, including token-to-token pairs Normal Q1 routing
fft missing, or any value other than 1 Normal Q1 routing

SOL means the mint So11111111111111111111111111111111111111112. Only the exact value 1 turns the curve path on; fft=true does not.

To see which path answered, check the swapInfo.label of each routePlan leg: a pump-curve leg is the curve path, alone or with one DEX leg on a curve quoted in another token. Any other route is normal routing.


Request shape

Method: GET

URL:

https://api.carbium.io/api/v2/quote

Header:

X-API-KEY: YOUR_API_KEY
Parameter Required Meaning
src_mint Yes SOL to buy, or the pump.fun token mint to sell
dst_mint Yes The pump.fun token mint to buy, or SOL to sell
amount_in Yes Raw input amount: lamports on a buy, raw token units on a sell
slippage_bps Yes Slippage tolerance in basis points
user_account No Wallet address; required for an executable txn
fft No 1 prices SOL and pump.fun bonding-curve pairs on the live curve

treasury and fee_bps keep working with fft=1. The fees table below shows how they are charged on a curve answer.


Response differences

A curve answer has the same schema as any Q1 answer. Its curve leg is the routePlan entry labeled pump-curve (the only leg on a SOL-quoted curve). These fields carry curve-specific values:

Field On a curve answer
routePlan[].swapInfo.label pump-curve
routePlan[].swapInfo.ammKey The token's bonding-curve address
routePlan[].swapInfo.feeAmount pump.fun's fee in lamports: its protocol fee plus the creator fee
routePlan[].swapInfo.outAmount On a sell, the SOL pump.fun pays out after its own fee and before the platform fee
feeBps Carbium-side fees in basis points: the 5 bps platform fee, plus your fee_bps when you set treasury
feeMint The SOL mint, on buys and sells: every fee on this path is paid in SOL
srcAmountIn Buy: amount_in minus the platform fee (and your fee), which is the SOL that goes into pump.fun. Sell: amount_in
destAmountOut Buy: tokens out. Sell: SOL out after pump.fun's fee and the platform fee (and your fee)
txn Base64 unsigned v0 transaction, present only with user_account

What the transaction does

txn is unsigned. user_account is the fee payer and the only signer, and the message carries a recent blockhash.

Side Instructions, in order
Buy compute-unit limit and price; SOL fee transfers; create the wallet's token account if it is missing; pump.fun buy_exact_sol_in
Sell compute-unit limit and price; pump.fun sell; SOL fee transfers

The platform fee is a plain SOL transfer inside this transaction, and so is your fee when you set treasury: one transaction, one signature.

Fees on a curve answer

Fee Charged on Paid to
Platform fee, 5 bps Buy: amount_in. Sell: the SOL pump.fun pays out Carbium, by SOL transfer in txn
Your fee (treasury + fee_bps) The same base as the platform fee The treasury wallet, by SOL transfer in txn
pump.fun protocol and creator fees The SOL that trades on the curve pump.fun, inside its own instruction; reported as feeAmount

Each SOL transfer is floor(base * bps / 10000) lamports. On this path your fee is paid in SOL even when the output is a token, no treasury token account is created, and the transaction has no carbium fee: log line: check the treasury wallet's SOL balance instead.

Curves quoted in another token

About one pump.fun launch in ten is quoted in a token other than SOL: its curve takes and pays out that token, for example USDC or PUMP. fft=1 serves these curves in two ways.

On the curve's own pair (the quote token and the pump.fun token, either way), the answer is one leg, pump-curve, priced and paid in the quote token. feeMint is the quote token's mint, and every fee is charged in it.

On a SOL pair, the answer is two legs in one transaction, when the curve's quote token is served (table below):

Side routePlan, in trade order What txn does
Buy the DEX leg (SOL to the quote token), then pump-curve wraps SOL, swaps it to the quote token on the leg pool, unwraps what is left, buys on the curve with buy_exact_quote_in_v2
Sell pump-curve, then the DEX leg (the quote token to SOL) sells on the curve with sell_v2, swaps the quote token to SOL on the leg pool, unwraps

The DEX leg's swapInfo.label is o-whirlpool, r-clmm or pump-amm, and its ammKey is the leg pool. feeMint is the SOL mint, srcAmountIn and destAmountOut are in SOL and token units as on a SOL-quoted curve, and each leg's swapInfo.feeMint names the token its feeAmount is in. Every leg carries its own minimum output, so the transaction trades in full or not at all.

Served quote tokens

Quote token mint Leg pool
pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn (PUMP) Orca Whirlpool
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v (USDC) Orca Whirlpool
3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh Orca Whirlpool
XsoCS1TfEyfFhfvj8EtZ528L3CaKBDBRqRapnBbDF2W Raydium CLMM
Xsc9qvGR1efVDFGLrVsmkzv3qi45LTBjeUKSPmx9qEh Raydium CLMM
XsDoVfqeBukxuZHWhdvWHBhgEHjGNst4MLodqsJHzoB Raydium CLMM
TTWofwAge91oFhZs7kpQdyrVRkmevgM88xijGvQFbKo Raydium CLMM
SPCXxcqXj6e5dJDVNovHN8744zkbhM2bYudU45BimGb Raydium CLMM
shib5gSoVKPjwkXrxRk7SbQFzb2R9rQB3TgQWYX4RwW Raydium CLMM, while its pool holds at least 10 SOL
DJTu7vi8norVzdVAffgvb39VP7wjKeTsgaMBJrzfxvoF Raydium CLMM
HiMSSzzwkZkrXJ4PGVJRdtfLaANeAztjjcgk5Dxe7Lwx Raydium CLMM
8J69rbLTzWWgUJziFY8jeu5tDwEPBwUz4pKBMr5rpump Pump AMM
Ai66LHZG9MCzg1WKdawwqduVAXpNDUuV8M3uyq5ppump Pump AMM
9cRCn9rGT8V2imeM2BaKs13yhMEais3ruM3rPvTGpump Pump AMM

The list changes as pools change. A SOL buy is served only when, at that moment, the leg pool can also price selling that quote token back to SOL. A SOL pair on a curve whose quote token is not served, or whose leg pool cannot be priced right now, answers like any pair without a route: 422 no_route. The curve's own pair still works.

What stays in your wallet

  • Buy: the DEX leg must return at least its minimum, up to 0.5% under its quote. The curve spends exactly that minimum, so anything the leg returns above it stays in your wallet as the quote token.
  • Sell: the curve's output goes back to SOL less a 0.5% margin, and that margin stays in your wallet as the quote token. If the curve pays out less than that, because the price moved more than about 0.5% between the quote and landing, the whole transaction fails and nothing trades: requote and send again. In a 15-minute live test, 3 of 43 such sells failed this way and each went through on the next quote.
  • Quote-token account: the first trade creates your wallet's account for the quote token (rent about 0.0015 SOL). It keeps the leftovers above; close it when you no longer need it.

The platform fee and your fee are SOL transfers, as on a SOL-quoted curve: on a buy they are charged on amount_in, on a sell on the SOL the DEX leg pays out. pump.fun's fees are charged in the quote token, and the leg pool's fee is inside its output.


Errors

Curve-path errors use a structured body. Branch on error.code; message is written for people and can change.

{
  "error": {
    "code": "fft_sell_exceeds_real_sol",
    "message": "gross 196786684 lamports above real_sol_reserves 98716048",
    "details": { "max_amount_in": "3519164087103" }
  }
}
HTTP status code Meaning First fix
422 fft_amount_too_small amount_in buys or sells nothing after fees Raise amount_in
422 fft_sell_exceeds_real_sol The sell needs more SOL than the curve holds Sell details.max_amount_in or less: the largest amount the curve can pay for right now
422 fft_buy_exceeds_real_tokens The buy asks for more tokens than the curve has left Lower amount_in
400 fft_bad_user_account user_account is not a valid Solana address Send the wallet's base58 address
500 fft_rpc_error The curve state could not be read Retry the quote
500 fft_txn_error The quote priced, but the transaction could not be built Retry the quote

details appears only on fft_sell_exceeds_real_sol. A pair that neither the curve path nor normal routing can serve answers 422 with code no_route. Auth, request-shape, and normal-routing failures keep their usual bodies; see Swap API Errors Reference.


Guidance

  • Widen slippage for launch buys. Launches move fast. For buys in the first seconds after a launch, set slippage_bps between 1000 and 3000 as an explicit policy for that flow, not as a retry knob. On a buy, destAmountOutMin is the min_tokens_out that pump.fun enforces.
  • Reuse your connection. Keep your HTTPS connection to the API open between quotes: a new TLS connection per request costs about 14 ms more than a reused one. Most HTTP clients reuse connections when you keep the client (in Node, fetch does; in Python, use a requests.Session).
  • Sign and send promptly. txn is unsigned and carries a recent blockhash. Sign and submit it right after the quote. If the blockhash expires, request a new quote instead of re-signing the old bytes; see Blockhash Expiry Recovery Playbook.
  • Simulate before you send. The curve path builds txn without checking the wallet's balance, so a quote can return a transaction the wallet cannot pay for. Keep preflight on, or simulate first.
  • Keep SOL for network costs. The wallet pays the network fee, and the rent for any account the buy opens such as its token account, on top of amount_in. signatureFeeLamports, prioritizationFeeLamports, and rentFeeLamports read "0" and do not cover these. A wallet's first pump.fun buy ever also opens pump.fun's per-user volume account, about 0.00135 SOL, once per wallet.
  • Sell the full balance. Pass the wallet's raw token balance (the amount string from getTokenAccountBalance) as amount_in, with the mints swapped: src_mint is the token and dst_mint is SOL. On fft_sell_exceeds_real_sol, sell details.max_amount_in first, then requote the rest. The sell leaves the emptied token account open; close it in your own transaction to recover its rent.
  • Requote a brand-new mint. If a quote for a token launched moments ago comes back without the pump-curve label, or as a route error, its curve was not visible yet. Request the quote again.
  • Requote after a buy fails on chain. A buy can land and fail when the curve changed after the quote. Custom 2006, a seeds constraint on creator_vault, means the token's creator moved it to pump.fun fee sharing, which often happens in the first slots after a launch. Custom 6042 means the price moved past slippage_bps. Request a new quote and send its txn; do not resend the old bytes.

Worked example

Buy 0.1 SOL of a token that just launched, with slippage_bps=2000:

curl --request GET \
  --url 'https://api.carbium.io/api/v2/quote?src_mint=So11111111111111111111111111111111111111112&dst_mint=TOKEN_MINT&amount_in=100000000&slippage_bps=2000&user_account=YOUR_WALLET&fft=1' \
  --header 'X-API-KEY: YOUR_API_KEY'

Response, trimmed to the fields this page covers:

{
  "srcAmountIn": "99950000",
  "destAmountOut": "3519164015687",
  "destAmountOutMin": "2815331212549",
  "swapMode": "BaseIn",
  "slippage": "2000",
  "routePlan": [
    {
      "swapInfo": {
        "ammKey": "BONDING_CURVE_ADDRESS",
        "label": "pump-curve",
        "inputMint": "So11111111111111111111111111111111111111112",
        "outputMint": "TOKEN_MINT",
        "inAmount": "99950000",
        "outAmount": "3519164015687",
        "feeAmount": "1233952",
        "feeMint": "So11111111111111111111111111111111111111112"
      },
      "percent": "100",
      "bps": "10000"
    }
  ],
  "feeMint": "So11111111111111111111111111111111111111112",
  "feeBps": "5",
  "inputMint": "So11111111111111111111111111111111111111112",
  "outputMint": "TOKEN_MINT",
  "txn": "AQAAAAAAAAAAAAAAAAAAAAAA..."
}

How the numbers fit together:

  • amount_in is 100000000 lamports. The 5 bps platform fee is 50000 lamports, paid by a SOL transfer inside txn, so srcAmountIn is 99950000.
  • Of srcAmountIn, 1233952 lamports is pump.fun's protocol and creator fee (feeAmount), and the other 98716048 lamports buy on the curve.
  • destAmountOut is 3519164015687 raw units: 3,519,164.015687 tokens at pump.fun's 6 decimals.
  • destAmountOutMin is destAmountOut less 20%, the min_tokens_out the pump.fun instruction enforces.

Selling that balance back is the same request with the mints swapped and the token amount as amount_in:

curl --request GET \
  --url 'https://api.carbium.io/api/v2/quote?src_mint=TOKEN_MINT&dst_mint=So11111111111111111111111111111111111111112&amount_in=3519164015687&slippage_bps=1000&user_account=YOUR_WALLET&fft=1' \
  --header 'X-API-KEY: YOUR_API_KEY'

With no other trades on the curve in between, that sell answers routePlan[].swapInfo.outAmount 97482095, the SOL pump.fun pays out after its fee, and destAmountOut 97433354. The 48741 lamport difference is the 5 bps platform fee.

🔶 Start with Q1 for the base quote flow, add fft=1 for pump.fun tokens on their bonding curve, then move into Executing Swaps to sign and submit. For platform setup, start at carbium.io.