Create, buy, and sell pump.fun tokens on Solana with a simple REST API. We build the transaction, you sign it. 1% fee per trade. No broken transactions, no missing accounts, no outdated instruction layouts.
PumpPortal is dead. Their transactions fail because they use outdated instruction layouts. We use the current 17-account buy/sell format and build transactions that actually land.
Current 17-account instruction layout. Correct PDA derivations. Transactions that actually land on Solana mainnet.
1% fee visible as a separate instruction in your wallet popup. No hidden charges. No API keys needed.
POST your parameters, get a serialized transaction back. Sign with any Solana wallet and send. Works with JS, Python, or any language.
Major upgrade — full post-graduation coverage, persistent trade history, and dev-trade intelligence. Everything backward compatible.
PumpSwap AMM trades now flow through the same WebSocket feed and OHLCV endpoint as bonding-curve trades. Bonding + graduated = one unified history per token. No more dead charts after graduation.
New /api/v1/ohlcv/:mint endpoint. Server-side SQL bucketing, all 9 resolutions (1s → 1d), sub-100ms response. Replaces clunky client-side trade aggregation.
subscribeDevBuy WebSocket method joins existing dev_sell. Includes isInitialBuy flag to distinguish launch bundles from post-launch market buys. Plus new /api/v1/dev-trades/:mint for historical dev activity.
Trades now stored in Postgres with 7-day retention. Buffer + token metadata + PumpSwap pool cache all survive restarts. Charts no longer reset on deploy.
Token endpoint now returns pumpFunMarketCapSol — the canonical pump.fun value used by tools like Axiom. No more ~3% mismatch between your UI and theirs.
Create + dev-buy transactions are now ALT-optimized — 1064 bytes vs. 1724 before, well under Solana's 1232 byte limit. Bundled launches always land.
Buy / sell endpoints now auto-detect whether a mint is legacy SPL or Token-2022 (which pump.fun uses for new tokens). No more silent failures on freshly graduated tokens.
PumpSwap events whose pools haven't been resolved yet (cold cache) are now parked and replayed automatically. Combined with response caching, 100 concurrent users hit RPC ~12×/min total.
fromCreation alias still returned alongside the more precise reachedBufferStart.Three steps to trade pump.fun tokens programmatically.
POST your wallet public key and trade details to our API endpoint.
We build the complete Solana transaction (including the 1% fee instruction) and return it as base64.
Deserialize the transaction, sign it with your wallet, and submit it to the Solana network.
const res = await fetch("https://your-api-domain.com/api/v1/buy", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
publicKey: wallet.publicKey.toBase58(),
mint: "TokenMintAddress...",
solAmount: 0.5,
slippageBps: 1000 // 10%
}),
});
const { transaction, pool } = await res.json();
console.log("Routed via:", pool); // "pump" or "jupiter"
// Deserialize, sign, and send
const tx = Transaction.from(Buffer.from(transaction, "base64"));
const signed = await wallet.signTransaction(tx);
const sig = await connection.sendRawTransaction(signed.serialize());API keys are optional. Without a key, you get 1% fee and 60 req/min. Link your wallet to get a key and unlock reduced fees for token holders.
Connect your Phantom wallet and sign a message to prove ownership. No transaction, no cost. Your private key never leaves your device.
No key needed. 1% fee, 60 req/min.
0.5% fee, 180 req/min, whale alerts.
0% fee, 600 req/min, all intelligence.
Once you have a key, send it as the X-API-Key header in every request. Server detects your tier and applies the correct fee in the transaction.
// JavaScript / TypeScript
const res = await fetch("https://pump4dev.fun/api/v1/buy", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "p4d_your_api_key_here" // ← THIS makes you VIP/Holder tier
},
body: JSON.stringify({
publicKey: wallet.publicKey.toBase58(),
mint: "TokenMintBase58",
solAmount: 0.5,
slippage: 10,
}),
});
const { transaction, pool } = await res.json();
// If you hold 3M+ tokens, the returned tx has 0% fee instruction.
// If you hold 500K+, it has 0.5% fee.
// Without the X-API-Key header, you get the default 1% fee.curl -X POST https://pump4dev.fun/api/v1/buy \
-H "Content-Type: application/json" \
-H "X-API-Key: p4d_your_api_key_here" \
-d '{"publicKey":"YourWallet","mint":"TokenMint","solAmount":0.5,"slippage":10}'Important: The API works fine without a key — you just pay the default 1% fee. The key only signals to our server which tier you belong to (Free / Holder / VIP). Your wallet's token balance is checked every 30 minutes; if you hold enough$P4Dtokens, your tier auto-upgrades and the next request gets reduced fees.
Check your tier anytime: GET /api/v1/auth/key with your X-API-Key header returns your wallet, current tier, token balance, and benefits.
All endpoints are relative to this base URL.
https://your-api-domain.com/api/v1All responses are JSON. All POST endpoints accept application/json except IPFS upload which uses multipart/form-data.
Complete reference for all available endpoints.
/api/v1/createCreate a new pump.fun token with optional dev buy. Two modes: pass metadataUri directly, or pass imageUrl and we auto-upload to IPFS for you (single-request token creation). Balance is pre-checked.
// Option A: Auto-upload (recommended — single request)
{
"publicKey": "YourWalletBase58Address",
"name": "My Token",
"symbol": "MTK",
"imageUrl": "https://i.imgur.com/abc.png",
"description": "My awesome token",
"twitter": "https://x.com/mytoken",
"telegram": "https://t.me/mytoken",
"website": "https://mytoken.com",
"devBuyAmount": 0.1 // SOL, optional (0 = no dev buy)
}
// Option B: Provide your own metadata URI
{
"publicKey": "YourWalletBase58Address",
"name": "My Token",
"symbol": "MTK",
"metadataUri": "https://ipfs.io/ipfs/Qm...",
"devBuyAmount": 0.1
}
// Also supports PumpPortal-style params:
// "amount" + "denominatedInSol": "true" instead of "devBuyAmount"
// "imageURL" (capital) also works{
"transaction": "base64_serialized_transaction...",
"mint": "NewTokenMintBase58Address",
"metadataUri": "https://ipfs.io/ipfs/Qm..."
}/api/v1/buyBuy tokens with SOL. Auto-detects bonding curve vs PumpSwap/Raydium and routes accordingly. Balance is pre-checked before building the transaction. Supports both Pump4Dev and PumpPortal parameter formats.
{
"publicKey": "BuyerWalletBase58",
"mint": "TokenMintBase58",
"solAmount": 0.5, // SOL to spend
"slippageBps": 1000, // optional, default 10% (1000 bps = 10%)
"pool": "auto", // "pump", "jupiter", or "auto" (default)
"priorityFee": 0.00005 // optional, SOL for tx priority
}
// PumpPortal-compatible format also works:
// "amount": 0.5, "denominatedInSol": "true", "slippage": 10{
"transaction": "base64_serialized_transaction...",
"pool": "pump" // "pump" (bonding curve) or "jupiter" (graduated)
}/api/v1/sellSell tokens for SOL. Auto-detects pool. Token balance is pre-checked. Supports tokenAmount (string bigint) or amount with denominatedInSol: false.
{
"publicKey": "SellerWalletBase58",
"mint": "TokenMintBase58",
"tokenAmount": "1000000000", // string! (bigint, 6 decimals)
"slippageBps": 1000, // optional, default 10%
"pool": "auto", // "pump", "jupiter", or "auto"
"priorityFee": 0.00005 // optional
}
// PumpPortal-compatible:
// "amount": 1000, "denominatedInSol": "false", "slippage": 10{
"transaction": "base64_serialized_transaction...",
"pool": "pump" // "pump" or "jupiter"
}/api/v1/token/:mintGet token info including bonding curve state, price, graduation progress, and market cap. Pass the mint address as a URL parameter.
{
"mint": "TokenMintBase58",
"bondingCurve": {
"address": "BondingCurveBase58",
"complete": false,
"progress": 45.2,
"virtualTokenReserves": "...",
"virtualSolReserves": "...",
"realTokenReserves": "...",
"realSolReserves": "...",
"tokenTotalSupply": "...",
"price": 0.000042,
"marketCapSol": 42.5
},
"graduated": false,
"dexPool": null
}/api/v1/tokensGet a list of tokens. Use filter param to switch between newest, tokens approaching graduation (80%+ progress), or recently migrated tokens. Perfect for building 3-column terminals (new / pre-migration / post-migration).
// Query parameters:
// filter — "newest" (default) | "graduating" | "migrated"
// limit — Max tokens (default 50, max 100)
// sort — "newest" or "marketcap" (only for filter=newest)
// Examples:
// GET /api/v1/tokens?filter=newest&limit=50
// GET /api/v1/tokens?filter=graduating&limit=20
// GET /api/v1/tokens?filter=migrated&limit=20// filter=newest
{
"filter": "newest",
"tokens": [
{
"mint": "...", "name": "...", "symbol": "...",
"uri": "...", "creator": "...",
"price": 0.000042, "marketCapSol": 42.5, "progress": 45.2
}
],
"total": 50
}
// filter=graduating (tokens at 80%+ progress)
{
"filter": "graduating",
"tokens": [
{
"mint": "...", "name": "...", "symbol": "...",
"marketCapSol": 280.5, "bondingCurveProgress": 92.3,
"holders": 145, "totalBuys": 320, "totalSells": 47
}
],
"total": 12
}
// filter=migrated (recently graduated)
{
"filter": "migrated",
"tokens": [
{
"mint": "...", "name": "...", "symbol": "...",
"marketCapSol": 450, "graduatedAt": 1712345678,
"totalBuys": 580, "finalHolders": 234
}
],
"total": 8
}/api/v1/trades/:mintGet historical trades for a token from in-memory buffer (max 500 per token). Use this to initialize charts, then subscribe to subscribeTokenTrade WebSocket for live updates.
// URL: /api/v1/trades/TokenMintBase58?limit=500&from=&to=
//
// Query parameters:
// limit — Max trades (default 500, max 500)
// from — UNIX timestamp (seconds), only trades after
// to — UNIX timestamp (seconds), only trades before{
"mint": "TokenMintBase58",
"trades": [
{
"signature": "tx_signature",
"txType": "buy", // or "sell"
"traderPublicKey": "...",
"solAmount": 0.5,
"tokenAmount": 1000000,
"marketCapSol": 45.2,
"priceSol": 0.0000005,
"newSolReserves": 32.5,
"newTokenReserves": 760000000,
"timestamp": 1712345700
}
],
"count": 423,
"hasMore": false // true if buffer might have evicted older trades
}
// Use this to build candlestick charts:
// 1. Fetch /trades/:mint (historical)
// 2. Aggregate to OHLC by timeframe (1m/5m/1h)
// 3. Subscribe to subscribeTokenTrade WS for live updates/api/v1/dev-trades/:mintHistorical dev_buy / dev_sell events for a token's creator. Useful for plotting DB/DS markers on charts (Axiom-style) without maintaining your own DB. Includes the create+buy launch bundle (flagged via isInitialBuy).
// URL: /api/v1/dev-trades/TokenMintBase58?limit=100
//
// Query parameters:
// limit — Max trades (default 100, max 1000)
//
// Note: returns empty array if we don't have a creator on record (token born
// before our indexer). Sorted ascending by timestamp.{
"mint": "TokenMintBase58",
"creator": "CreatorWalletBase58",
"trades": [
{
"signature": "tx_signature...",
"type": "buy", // or "sell"
"solAmount": 5.0,
"tokenAmount": 50000000,
"priceSol": 0.0000001,
"marketCapSol": 35.0,
"isInitialBuy": true, // launch bundle (★ marker)
"timestamp": 1712345678
},
{
"signature": "tx_signature...",
"type": "buy",
"solAmount": 1.2,
"tokenAmount": 8500000,
"priceSol": 0.00000014,
"marketCapSol": 92.0,
"isInitialBuy": false, // post-launch market buy (DB marker)
"timestamp": 1712348900
}
],
"count": 2
}/api/v1/ohlcv/:mintServer-side bucketed OHLCV candles for any resolution. Sourced from our 7-day Postgres trade store + live in-memory buffer for the in-progress bucket. Covers both bonding-curve and post-graduation PumpSwap trades through one endpoint. Sub-100ms response even for 5000 candles.
// URL: /api/v1/ohlcv/TokenMintBase58?resolution=1m&from=...&to=...
//
// Query parameters:
// resolution — required: 1s | 15s | 30s | 1m | 5m | 15m | 1h | 4h | 1d
// from — UNIX timestamp (seconds), default: now - 24h
// to — UNIX timestamp (seconds), default: now{
"mint": "TokenMintBase58",
"resolution": "1m",
"from": 1712345000,
"to": 1712348600,
"candles": [
{
"timestamp": 1712345040, // bucket start, UNIX seconds
"open": 0.0000005,
"high": 0.0000007,
"low": 0.00000048,
"close": 0.00000065,
"volume": 12.5, // SOL volume in bucket
"trades": 23 // number of trades aggregated
}
],
"count": 60,
"truncated": false, // hit the 5000-candle cap
"reachedBufferStart": true, // requested range extends past our oldest data
"earliestAvailable": 1712340000,
"source": "postgres" // postgres | buffer
}
// Sparse output — only buckets containing at least one trade are returned.
// Consumers handle their own forward-fill / gap rendering.
// Prices are SOL per token; volume is SOL. Convert to USD client-side./api/v1/claim-feeClaim creator trading fees for a specific token you created. Pump.fun rewards creators with a portion of trading fees. Returns a transaction to sign.
{
"publicKey": "CreatorWalletBase58",
"mint": "TokenMintBase58"
}{
"transaction": "base64_serialized_transaction...",
"creatorVault": "VaultAddressThatHoldsFees"
}/api/v1/claim-feesClaim creator fees from ALL your tokens at once. Automatically finds all tokens you created that have claimable fees and batches claims into transactions (max 5 per tx).
{
"publicKey": "CreatorWalletBase58"
}{
"transactions": ["base64_tx_1...", "base64_tx_2..."],
"tokens": [
{ "mint": "Token1Mint", "sharingConfig": "...", "creatorVault": "..." },
{ "mint": "Token2Mint", "sharingConfig": "...", "creatorVault": "..." }
],
"totalTokens": 2,
"message": "Found 2 token(s) with claimable fees. 1 transaction(s) to sign."
}/api/v1/bundleExecute multiple buy/sell actions in a single request. Each action returns a separate transaction. Supports up to 10 actions. Different wallets can be used per action.
{
"actions": [
{
"action": "buy",
"publicKey": "Wallet1Base58",
"mint": "TokenMintBase58",
"solAmount": 0.5,
"slippageBps": 1000,
"pool": "auto"
},
{
"action": "buy",
"publicKey": "Wallet2Base58",
"mint": "TokenMintBase58",
"solAmount": 1.0
},
{
"action": "sell",
"publicKey": "Wallet3Base58",
"mint": "TokenMintBase58",
"tokenAmount": "1000000000"
}
]
}{
"results": [
{ "index": 0, "action": "buy", "transaction": "base64...", "pool": "pump" },
{ "index": 1, "action": "buy", "transaction": "base64...", "pool": "pump" },
{ "index": 2, "action": "sell", "transaction": "base64...", "pool": "pump" }
],
"total": 3,
"success": 3,
"failed": 0
}/api/v1/auth/linkLink your wallet to Pump4Dev and receive an API key. Sign a message containing 'Pump4Dev' with your wallet to prove ownership. Holders of the Pump4Dev token get reduced or zero fees.
{
"publicKey": "YourWalletBase58",
"signature": "base58_ed25519_signature",
"message": "Link wallet to Pump4Dev API — 2025-04-11T..."
}
// The message must contain "Pump4Dev" (anti-phishing).
// Sign the message with your wallet (Phantom: signMessage).
// Signature must be base58-encoded.
// ── Tier System ──
// Free (no key): 1% fee, 60 req/min
// Holder (500K+): 0.5% fee, 180 req/min, whale alerts
// VIP (3M+): 0% fee, 600 req/min, all intelligence
// After linking, use your key in all requests:
// Header: X-API-Key: p4d_a1b2c3d4e5...{
"apiKey": "p4d_a1b2c3d4e5f6...",
"wallet": "YourWalletBase58",
"message": "Wallet linked successfully."
}
// GET /api/v1/auth/key — check your tier & balance
// POST /api/v1/auth/key — regenerate key
// DELETE /api/v1/auth/key — revoke key
// All require X-API-Key header./api/v1/ipfs/uploadUpload token metadata (image + JSON) to IPFS via Pinata. Returns a metadata URI for /create. Note: you can skip this entirely by using imageUrl in /create instead.
// Content-Type: multipart/form-data
//
// Fields:
// file — Image (PNG, JPEG, GIF, WEBP, max 5MB)
// name — Token name
// symbol — Token symbol
// description — Token description (optional)
// twitter — Twitter URL (optional)
// telegram — Telegram URL (optional)
// website — Website URL (optional){
"metadataUri": "https://ipfs.io/ipfs/QmHash..."
}Real-time stream of new tokens, trades, and migrations. Connect via WebSocket and subscribe to the events you need. Compatible with PumpPortal protocol.
ws://your-api-domain.com/wsSend JSON messages to subscribe/unsubscribe to event streams.
// New tokens — get notified when any token is created on pump.fun
{ "method": "subscribeNewToken" }
// Trades — get buy/sell events for specific token(s)
{ "method": "subscribeTokenTrade", "keys": ["TokenMint1", "TokenMint2"] }
// Migrations — get notified when tokens graduate to PumpSwap/Raydium
{ "method": "subscribeMigration" }
// ── Intelligence Alerts ──
// Whale alerts — notified when any trade >= 5 SOL
{ "method": "subscribeWhaleAlerts" }
// Dev sell detection — notified when token creator sells (rug pull warning)
{ "method": "subscribeDevSell" }
// Dev buy detection — notified when token creator buys (launch bundle or post-launch)
{ "method": "subscribeDevBuy" }
// King of the Hill — notified when token hits 90%+ bonding curve
{ "method": "subscribeKoth" }
// Graduating soon — trades on tokens at 80%+ bonding curve progress
{ "method": "subscribeGraduatingSoon" }
// Unsubscribe (all methods)
{ "method": "unsubscribeNewToken" }
{ "method": "unsubscribeTokenTrade", "keys": ["TokenMint1"] }
{ "method": "unsubscribeMigration" }
{ "method": "unsubscribeWhaleAlerts" }
{ "method": "unsubscribeDevSell" }
{ "method": "unsubscribeDevBuy" }
{ "method": "unsubscribeKoth" }
{ "method": "unsubscribeGraduatingSoon" }Events you receive after subscribing.
// New token created
{
"txType": "create",
"signature": "tx_signature...",
"mint": "TokenMintBase58",
"name": "Token Name",
"symbol": "TKN",
"uri": "https://ipfs.io/...",
"traderPublicKey": "CreatorWallet",
"marketCapSol": 30,
"timestamp": 1712345678
}
// Trade (buy or sell) — enriched with intelligence data
{
"txType": "buy", // or "sell"
"signature": "tx_signature...",
"mint": "TokenMintBase58",
"traderPublicKey": "TraderWallet",
"solAmount": 0.5,
"tokenAmount": 1000000,
"marketCapSol": 45.2,
"vTokensInBondingCurve": 650000000,
"bondingCurveProgress": 52.3, // % to graduation
"volume5m": 12.5, // SOL volume last 5 min
"holders": 42, // unique buyers
"isWhale": false, // true if >= 5 SOL
"isDevSell": false, // true if creator is selling
"isDevBuy": false, // true if creator is buying from market
"isKoth": false, // true if >= 90% progress
"timestamp": 1712345700
}
// Token graduated (migrated to PumpSwap/Raydium)
{
"txType": "migration",
"signature": "tx_signature...",
"mint": "TokenMintBase58",
"timestamp": 1712345800
}
// ── Intelligence Alerts ──
// Whale alert (>= 5 SOL trade)
{
"type": "whale_buy", // or "whale_sell"
"mint": "TokenMintBase58",
"name": "Token Name",
"symbol": "TKN",
"traderPublicKey": "WhaleWallet",
"solAmount": 15.5,
"marketCapSol": 120.0,
"timestamp": 1712345700
}
// Dev sell (creator selling their tokens — rug pull warning)
{
"type": "dev_sell",
"mint": "TokenMintBase58",
"name": "Token Name",
"symbol": "TKN",
"creatorPublicKey": "CreatorWallet",
"solAmount": 5.2,
"tokenAmount": 50000000,
"marketCapSol": 80.0,
"timestamp": 1712345700
}
// Dev buy (creator buying their own token).
// isInitialBuy: true → this is the create+buy launch bundle.
// Size = "skin in the game" (5 SOL = serious, 0.05 SOL = bot)
// isInitialBuy: false → post-launch market buy (creator adding/accumulating)
{
"type": "dev_buy",
"mint": "TokenMintBase58",
"name": "Token Name",
"symbol": "TKN",
"creatorPublicKey": "CreatorWallet",
"solAmount": 5.0,
"tokenAmount": 50000000,
"marketCapSol": 35.0,
"isInitialBuy": true,
"timestamp": 1712345700
}
// King of the Hill (approaching graduation, >= 90%)
{
"type": "koth",
"mint": "TokenMintBase58",
"name": "Token Name",
"symbol": "TKN",
"progress": 92.5,
"marketCapSol": 180.0,
"timestamp": 1712345700
}const ws = new WebSocket("ws://your-api-domain.com/ws");
ws.onopen = () => {
// Subscribe to new token creations
ws.send(JSON.stringify({ method: "subscribeNewToken" }));
ws.send(JSON.stringify({ method: "subscribeMigration" }));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.txType === "create") {
console.log("New token!", data.name, data.symbol, data.mint);
// Auto-subscribe to trades for this token
ws.send(JSON.stringify({
method: "subscribeTokenTrade",
keys: [data.mint]
}));
}
if (data.txType === "buy" || data.txType === "sell") {
console.log(data.txType, data.solAmount, "SOL", "MC:", data.marketCapSol);
}
if (data.txType === "migration") {
console.log("Token graduated:", data.mint);
}
};Full working examples in JavaScript and Python.
import { Connection, Transaction } from "@solana/web3.js";
const API = "https://your-api-domain.com";
const connection = new Connection("https://api.mainnet-beta.solana.com");
// ═══════════════════════════════════════════════════
// CREATE TOKEN
// ═══════════════════════════════════════════════════
async function createToken(wallet) {
// 1. Upload metadata to IPFS
const formData = new FormData();
formData.append("file", imageFile);
formData.append("name", "MyToken");
formData.append("symbol", "MTK");
formData.append("description", "My awesome token");
const ipfsRes = await fetch(`${API}/api/v1/ipfs/upload`, {
method: "POST",
body: formData,
});
const { metadataUri } = await ipfsRes.json();
// 2. Get serialized transaction
const res = await fetch(`${API}/api/v1/create`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
publicKey: wallet.publicKey.toBase58(),
name: "MyToken",
symbol: "MTK",
metadataUri,
devBuyAmount: 0.1, // optional initial buy
}),
});
const { transaction, mint } = await res.json();
// 3. Sign and send
const tx = Transaction.from(Buffer.from(transaction, "base64"));
const signed = await wallet.signTransaction(tx);
const sig = await connection.sendRawTransaction(signed.serialize());
console.log("Token created!", mint, sig);
}
// ═══════════════════════════════════════════════════
// BUY TOKEN
// ═══════════════════════════════════════════════════
async function buyToken(wallet, mint, solAmount) {
const res = await fetch(`${API}/api/v1/buy`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
publicKey: wallet.publicKey.toBase58(),
mint,
solAmount,
pool: "auto", // auto-detects bonding curve vs PumpSwap/Raydium
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.error);
}
const { transaction, pool } = await res.json();
console.log("Routed via:", pool); // "pump" or "jupiter"
const tx = Transaction.from(Buffer.from(transaction, "base64"));
const signed = await wallet.signTransaction(tx);
await connection.sendRawTransaction(signed.serialize());
}
// ═══════════════════════════════════════════════════
// SELL TOKEN
// ═══════════════════════════════════════════════════
async function sellToken(wallet, mint, tokenAmount) {
const res = await fetch(`${API}/api/v1/sell`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
publicKey: wallet.publicKey.toBase58(),
mint,
tokenAmount: tokenAmount.toString(), // must be string
}),
});
const { transaction } = await res.json();
const tx = Transaction.from(Buffer.from(transaction, "base64"));
const signed = await wallet.signTransaction(tx);
await connection.sendRawTransaction(signed.serialize());
}import requests
import base64
from solders.transaction import Transaction
from solders.keypair import Keypair
API = "https://your-api-domain.com"
def buy_token(keypair: Keypair, mint: str, sol_amount: float):
# Get serialized transaction from API
res = requests.post(f"{API}/api/v1/buy", json={
"publicKey": str(keypair.pubkey()),
"mint": mint,
"solAmount": sol_amount,
})
data = res.json()
if "error" in data:
print(f"Error: {data['error']}")
return
# Deserialize, sign, and send
tx_bytes = base64.b64decode(data["transaction"])
tx = Transaction.from_bytes(tx_bytes)
tx.sign([keypair])
# Submit to Solana RPC
rpc = requests.post("https://api.mainnet-beta.solana.com", json={
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
base64.b64encode(bytes(tx)).decode(),
{"encoding": "base64"}
]
})
print("Signature:", rpc.json()["result"])
# Usage
keypair = Keypair.from_base58_string("your_private_key")
buy_token(keypair, "TokenMintAddress...", 0.5)Buy a token in one request. Works from any language.
curl -X POST https://your-api-domain.com/api/v1/buy \
-H "Content-Type: application/json" \
-d '{"publicKey":"YourWallet","mint":"TokenMint","solAmount":0.5,"slippage":10,"pool":"auto"}'
# Returns: { "transaction": "base64...", "pool": "pump" }
# Decode, sign with your wallet, send to Solana RPC.import requests, base64
from solders.transaction import Transaction
from solders.keypair import Keypair
API = "https://your-api-domain.com"
keypair = Keypair.from_base58_string("your_private_key")
res = requests.post(f"{API}/api/v1/buy", json={
"publicKey": str(keypair.pubkey()),
"mint": "TokenMintBase58",
"solAmount": 0.5,
"slippage": 10,
})
data = res.json()
tx = Transaction.from_bytes(base64.b64decode(data["transaction"]))
tx.sign([keypair])
rpc = requests.post("https://api.mainnet-beta.solana.com", json={
"jsonrpc": "2.0", "id": 1,
"method": "sendTransaction",
"params": [base64.b64encode(bytes(tx)).decode(), {"encoding": "base64"}]
})
print("TX:", rpc.json()["result"])use reqwest::Client;
use serde_json::json;
#[tokio::main]
async fn main() {
let client = Client::new();
let res = client
.post("https://your-api-domain.com/api/v1/buy")
.json(&json!({"publicKey":"YourWallet","mint":"TokenMint","solAmount":0.5,"slippage":10,"pool":"auto"}))
.send().await.unwrap();
let data: serde_json::Value = res.json().await.unwrap();
println!("Pool: {}, tx length: {}", data["pool"], data["transaction"].as_str().unwrap().len());
// Decode transaction, sign with keypair, send to RPC
}package main
import ("bytes"; "encoding/json"; "fmt"; "net/http")
func main() {
body, _ := json.Marshal(map[string]interface{}{
"publicKey": "YourWallet", "mint": "TokenMint",
"solAmount": 0.5, "slippage": 10, "pool": "auto",
})
resp, _ := http.Post("https://your-api-domain.com/api/v1/buy", "application/json", bytes.NewBuffer(body))
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println("Pool:", result["pool"])
// Decode result["transaction"], sign, send to Solana RPC
}Simple and transparent. The fee is a separate SOL transfer instruction visible in your wallet confirmation popup.
| Operation | Fee | Details |
|---|---|---|
| Create (no dev buy) | 0.001 SOL | Flat fee |
| Create + Dev Buy | 1% | 1% of dev buy SOL amount |
| Buy | 1% | 1% of SOL spent |
| Sell | 1% | 1% of SOL received |
Minimum fee: 10,000 lamports (0.00001 SOL). The fee is always a SystemProgram.transfer instruction — fully visible and verifiable in your wallet popup before you sign.
The API is free to use with fair rate limits.
Requests per minute
60
Rate limit by
IP
Auth required
No
Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Hold Pump4Dev tokens to get reduced fees and higher rate limits. Link your wallet via POST /api/v1/auth/link.
| Tier | Tokens | Fee | Rate Limit |
|---|---|---|---|
| Free | No key needed | 1% | 60/min |
| Holder | 500,000+ | 0.5% | 180/min |
| VIP | 3,000,000+ | 0% | 600/min |
Important details for advanced integrations.
All transactions are Legacy format (not VersionedTransaction) to support partialSign with the server-generated mint keypair on create.
pump.fun uses SPL Token (not Token-2022). All buy/sell instructions reference TOKEN_PROGRAM_ID.
The API automatically detects whether a token is on the bonding curve or has graduated to PumpSwap/Raydium. With pool "auto" (default) we route via bonding curve or Jupiter. You can force "pump" or "jupiter" explicitly.
Default slippage is 10% (1000 bps). Range: 1-5000 bps. For volatile tokens, consider higher slippage.
Sell amounts must be strings representing raw token amount (6 decimals). E.g., 1000 tokens = "1000000000".
Transactions include compute budget: 250K units for create, 150K for buy/sell. Priority fee: 50,000 microLamports.
All errors return a standardized JSON response with an error code and human-readable message.
{
"error": "INSUFFICIENT_SOL",
"message": "Have: 0.5 SOL, need: ~1.02 SOL (includes 1% fee + tx fees)"
}| Code | HTTP | Description |
|---|---|---|
| INVALID_PUBLIC_KEY | 400 | Invalid or missing wallet address |
| INVALID_MINT | 400 | Invalid or missing token mint address |
| INVALID_AMOUNT | 400 | Amount must be a positive number |
| INSUFFICIENT_SOL | 400 | Not enough SOL for trade + fees |
| INSUFFICIENT_TOKENS | 400 | Not enough tokens to sell |
| TOKEN_GRADUATED | 410 | Token migrated to PumpSwap/Raydium |
| TOKEN_NOT_FOUND | 404 | Token or bonding curve not found |
| NO_FEES_AVAILABLE | 404 | No creator fees to claim |
| INVALID_API_KEY | 401 | API key not found or revoked |
| RATE_LIMITED | 429 | Too many requests |
| RPC_ERROR | 502 | Solana RPC connection failed |
| JUPITER_ERROR | 502 | Jupiter swap API failed |
| IPFS_ERROR | 502 | IPFS/Pinata upload failed |
Monitor API availability and performance.
{
"status": "ok", // "ok" or "degraded"
"uptime": 3600,
"rpc": {
"connected": true,
"latency": 45, // ms
"slot": 312456789
},
"timestamp": "2025-04-12T..."
}{
"status": "operational",
"version": "1.0.0",
"uptime": 3600,
"rpc": { "connected": true, "latencyMs": 45, "slot": 312456789 },
"websocket": { "streaming": true, "tokensTracked": 847 },
"features": {
"trading": true,
"createToken": true,
"jupiterRouting": true,
"whaleAlerts": true,
"devSellDetection": true,
"kothAlerts": true,
"graduatingSoon": true,
"tierSystem": true
}
}