Buy and Sell – API
Use this to buy and sell tokens.
Supported pools
Pump.funLetsBonk.funRaydium LaunchPadPumpSwapRaydium CPMM
Endpoint
POST https://api.pumpapi.io
- Local transactions (No private key required)
- Lightning transactions⚡ (EASIER AND FASTER)
Request Body
| Field | Description |
|---|---|
publicKey | Your public key (the wallet address) |
action | "buy" or "sell" |
mint | Mint address of the token |
amount | Amount to trade. Use '100%' to sell all and get a 0.002 sol refund from the network |
denominatedInSol | "true" if amount is in SOL, "false" for token amount |
slippage | Slippage in percent (recommended: 20) |
priorityFee | Optional priority fee in SOL |
- Python
- JavaScript
- Rust
- Go
import requests
from solders.transaction import VersionedTransaction
from solders.keypair import Keypair
from solders.commitment_config import CommitmentLevel
from solders.rpc.requests import SendVersionedTransaction
from solders.rpc.config import RpcSendTransactionConfig
response = requests.post(url="https://api.pumpapi.io", data={
"publicKey": "your_public_key",
"action": "buy", # or sell
"mint": "token_address",
"amount": 0.01,
"denominatedInSol": "true",
"slippage": 20,
"priorityFee": 0.0001,
})
keypair = Keypair.from_base58_string("your_private_key")
tx = VersionedTransaction(VersionedTransaction.from_bytes(response.content).message, [keypair])
commitment = CommitmentLevel.Confirmed
config = RpcSendTransactionConfig(preflight_commitment=commitment)
txPayload = SendVersionedTransaction(tx, config)
response = requests.post(
url="https://api.mainnet-beta.solana.com/", # it's better to use Helius RPC endpoint
headers={"Content-Type": "application/json"},
data=SendVersionedTransaction(tx, config).to_json()
)
txSignature = response.json()['result']
print(f'Transaction: https://solscan.io/tx/{txSignature}')
import { VersionedTransaction, Connection, Keypair } from '@solana/web3.js';
import bs58 from "bs58";
const RPC_ENDPOINT = "Your RPC Endpoint";
const web3Connection = new Connection(
RPC_ENDPOINT,
'confirmed',
);
async function sendPumpApiLocalTransaction(){
const response = await fetch(`https://api.pumpapi.io`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"publicKey": "your_public_key", // Your wallet public key
"action": "buy", // or sell
"mint": "token_address"
"amount": 0.1,
"denominatedInSol": "true",
"slippage": 20,
"priorityFee": 0.0001,
})
});
if(response.status === 200){ // successfully generated transaction
const data = await response.arrayBuffer();
const tx = VersionedTransaction.deserialize(new Uint8Array(data));
const signerKeyPair = Keypair.fromSecretKey(bs58.decode("your_private_key"));
tx.sign([signerKeyPair]);
const signature = await web3Connection.sendTransaction(tx)
console.log("Transaction: https://solscan.io/tx/" + signature);
} else {
console.log(response.statusText); // log error
}
}
sendPumpApiLocalTransaction();
use reqwest::Client;
use solana_sdk::{
signature::{Keypair, Signer},
transaction::VersionedTransaction,
};
use bs58;
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Step 1: Ask PumpAPI for an unsigned transaction
let client = Client::new();
let res = client
.post("https://api.pumpapi.io")
.json(&json!({
"publicKey": "your_public_key",
"action": "buy", // or "sell"
"mint": "token_address",
"amount": 0.01,
"denominatedInSol": "true",
"slippage": 20,
"priorityFee": 0.0001
}))
.send()
.await?;
let tx_bytes = res.bytes().await?;
// Deserialize the transaction
let mut tx: VersionedTransaction = bincode::deserialize(&tx_bytes)?;
// Step 2: Sign the transaction locally
let secret = bs58::decode("your_private_key").into_vec()?;
let keypair = Keypair::from_bytes(&secret)?;
tx.sign(&[&keypair]);
// Step 3: Broadcast the signed transaction to an RPC node
let serialized_tx = bincode::serialize(&tx)?;
let rpc_payload = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
base64::encode(serialized_tx),
{
"encoding": "base64",
"preflightCommitment": "confirmed"
}
]
});
let rpc_res = client
.post("https://api.mainnet-beta.solana.com")
.header("Content-Type", "application/json")
.json(&rpc_payload)
.send()
.await?;
let sig_json: serde_json::Value = rpc_res.json().await?;
println!(
"Transaction: https://solscan.io/tx/{}",
sig_json["result"].as_str().unwrap_or("")
);
Ok(())
}
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"github.com/gagliardetto/solana-go"
)
func main() {
// 1. Request unsigned transaction from PumpAPI
payload := map[string]interface{}{
"publicKey": "your_public_key",
"action": "buy", // or "sell"
"mint": "token_address",
"amount": 0.01,
"denominatedInSol": "true",
"slippage": 20,
"priorityFee": 0.0001,
}
body, _ := json.Marshal(payload)
res, err := http.Post("https://api.pumpapi.io", "application/json", bytes.NewBuffer(body))
if err != nil {
log.Fatal(err)
}
rawTx, _ := ioutil.ReadAll(res.Body)
// 2. Deserialize transaction and sign
tx := new(solana.VersionedTransaction)
if err := tx.UnmarshalBinary(rawTx); err != nil {
log.Fatal(err)
}
privKey, _ := base64.StdEncoding.DecodeString("your_private_key")
kp := solana.PrivateKeyFromBytes(privKey)
tx.Sign(func(key solana.PublicKey) *solana.PrivateKey {
if key == kp.PublicKey() {
return &kp
}
return nil
})
// 3. Send signed transaction
txBytes, _ := tx.MarshalBinary()
rpcPayload := map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": []interface{}{
base64.StdEncoding.EncodeToString(txBytes),
map[string]interface{}{"encoding": "base64"},
},
}
rpcBody, _ := json.Marshal(rpcPayload)
resp, err := http.Post("https://api.mainnet-beta.solana.com", "application/json", bytes.NewBuffer(rpcBody))
if err != nil {
log.Fatal(err)
}
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Transaction: https://solscan.io/tx/%s\n", result["result"])
}
tip
Want cleaner code and faster execution? Use our ⚡ Lightning transactions
⚡ Lightning Transaction
Lightning transaction is a method of sending transactions where we broadcast the transaction on your behalf.
This approach allows for:
- 🚀 Maximum transaction speed
- 🧩 Minimal code complexity
By handling the transaction process internally, you don’t have to construct the transaction manually — we do it for you.
To use this feature, simply provide a wallet
privateKey— it’s needed to sign and broadcast the transaction on your behalf.
Request Body
| Field | Description |
|---|---|
privateKey | Your private key |
action | "buy" or "sell" |
mint | Mint address of the token |
amount | Amount to trade. Use '100%' to sell all and get a 0.002 sol refund from the network |
denominatedInSol | "true" if amount is in SOL, "false" for token amount |
slippage | Slippage in percent (recommended: 20) |
priorityFee | Optional extra fee (in SOL) to speed up your transaction and increase its chance of landing. There are two modes of operation: 1️⃣ Automatic Jito split (≥ 0.0012 SOL): If the value is 0.0012 SOL or higher, PumpAPI automatically splits it: • 90% → jitoTip (used by ~90% of validators)• 10% → priorityFee (for non-Jito validators)2️⃣ No split (< 0.0012 SOL): If the value is less than 0.0012 SOL, no split occurs. The full amount is treated as priorityFee, and the transaction is sent via SQWOS (fast non-Jito route).Minimum allowed value: 10,000 lamports (0.00001 SOL). Dynamic options: you can also let PumpAPI auto-adjust fees dynamically based on recent network data. • 'auto' / 'auto-95' → ~95% success (~0.015 SOL ≈ $3–4) • 'auto-75' → ~75% success (~0.00113 SOL ≈ $0.2–0.3) • 'auto-50' → ~50% success (~0.00022 SOL ≈ $0.04) In this mode, only the priorityFee is adjusted automatically — jitoTip is not included or estimated. If you want to use Jito alongside dynamic fees, you can still set jitoTip manually (see below). ⚠️ Note: During heavy network congestion, fees for ~75/95% success can rise significantly — even $10 per transaction. The values above reflect the state at the time of writing. To save costs and have big chances to land the transaction, consider using the minimum fee (0.00001 SOL) together with guaranteedDelivery: true (see below). |
jitoTip | Optional. Use this if you don’t want automatic priorityFee split. Example: 'jitoTip': 0.01. Minimum required to join Jito auction: 0.01 SOL. Anything below that is ignored, and the transaction is sent without Jito participation. When jitoTip is provided, your entire priorityFee remains intact (not split). |
guaranteedDelivery | Optional experimental feature "true" tells the server to rebroadcast the transaction for up to 10 seconds and respond with confirmed: true if it appears on-chain within that time. Otherwise, you receive confirmed: false. ⚠️ This affects response time: if you want an immediate reply (without confirmation of success), set this to false! |
- Python
- JavaScript
- Rust
- Go
import requests
url = "https://api.pumpapi.io"
data = {
"privateKey": "your_private_key",
"action": "buy",
"mint": "token_address",
"amount": 0.01,
"denominatedInSol": "true",
"slippage": 20,
"priorityFee": 0.0001,
}
response = requests.post(url, json=data)
print(response.json())
import axios from 'axios';
const data = {
privateKey: "your_private_key",
action: "buy",
mint: "token_address",
amount: 0.01,
denominatedInSol: "true",
slippage: 20,
priorityFee: 0.0001
};
axios.post('https://api.pumpapi.io', data)
.then(response => console.log(response.data))
.catch(error => console.error(error));
use reqwest::Client;
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let res = client.post("https://api.pumpapi.io")
.json(&json!({
"privateKey": "your_private_key",
"action": "buy",
"mint": "token_address",
"amount": 0.01,
"denominatedInSol": "true",
"slippage": 20,
"priorityFee": 0.0001
}))
.send()
.await?
.text()
.await?;
println!("{}", res);
Ok(())
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
data := map[string]interface{}{
"privateKey": "your_private_key",
"action": "buy",
"mint": "token_address",
"amount": 0.01,
"denominatedInSol": "true",
"slippage": 20,
"priorityFee": 0.0001,
}
jsonData, _ := json.Marshal(data)
resp, err := http.Post("https://api.pumpapi.io", "application/json", bytes.NewBuffer(jsonData))
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result)
}
Need help? Join our Telegram group.