Create Token
Create tokens on Pump.fun directly through our API — in a single request. This is an extension of the Trade API: everything that works there works here too.
Endpoint​
POST https://api.pumpapi.io
Parameters​
| Parameter | Required | Description |
|---|---|---|
name | Yes | Token name |
symbol | Yes | Token ticker symbol |
imageURL | No | Token image URL. Without it, Pump.fun won't display your token — only bots will be able to trade it. You can host images on prnt.sc, imgur.com, or imgbb.com, or simply copy an image URL from Google Images. |
description | No | Token description |
website | No | Project website URL |
telegram | No | Telegram channel/group link |
x | No | X (Twitter) profile link |
uri | No | Custom metadata URI. If provided, imageURL, description, website, telegram, and x are ignored |
mayhemMode | No | Default: false |
cashbackToTradersEnabled | No | Default: false. If true, trading fees are earned by traders, not you |
mintRef | No | When using Jito Bundles or Actions, you don’t yet know the token address assigned to you (unless you provide mintPrivateKey). To handle this, within a single request you can set "mintRef": "any value" (the default is "0") and reuse it across related transactions inside the same Jito Bundle or Actions. When buying the token, specify "mintRef": "the_value_you_set_earlier", and the backend will understand which token you’re referring to. Works within a single request; a second request requires providing the mint address. |
mintPrivateKey | No | Custom mint address key. By default we generate tokens with the pump ending — you don't need to set this |
amount | No | Amount of SOL to buy as dev on launch |
Basic Example​
- Python
- JavaScript
- Rust
- Go
import requests
url = "https://api.pumpapi.io"
data = {
"privateKey": "base58_private_key",
"action": "create",
"name": "PumpApi",
"symbol": "PAPI",
"description": "Fast API for Pump.fun, Raydium, Meteora",
"imageURL": "https://pumpapi.io/img/pumpapi_logo.webp",
"website": "https://pumpapi.io",
"telegram": "https://t.me/YOUR_TG",
"x": "https://x.com/realpumpapi",
"amount": "0.0001",
"denominatedInQuote": "true",
"priorityFee": "0.00002001",
}
response = requests.post(url, json=data)
print(response.json())
import axios from 'axios';
const data = {
privateKey: "base58_private_key",
action: "create",
name: "PumpApi",
symbol: "PAPI",
description: "Fast API for Pump.fun, Raydium, Meteora",
imageURL: "https://pumpapi.io/img/pumpapi_logo.webp",
website: "https://pumpapi.io",
telegram: "https://t.me/YOUR_TG",
x: "https://x.com/realpumpapi",
amount: "0.0001",
denominatedInQuote: "true",
priorityFee: "0.00002001",
};
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": "base58_private_key",
"action": "create",
"name": "PumpApi",
"symbol": "PAPI",
"description": "Fast API for Pump.fun, Raydium, Meteora",
"imageURL": "https://pumpapi.io/img/pumpapi_logo.webp",
"website": "https://pumpapi.io",
"telegram": "https://t.me/YOUR_TG",
"x": "https://x.com/realpumpapi",
"amount": "0.0001",
"denominatedInQuote": "true",
"priorityFee": "0.00002001"
}))
.send()
.await?
.text()
.await?;
println!("{}", res);
Ok(())
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
data := map[string]interface{}{
"privateKey": "base58_private_key",
"action": "create",
"name": "PumpApi",
"symbol": "PAPI",
"description": "Fast API for Pump.fun, Raydium, Meteora",
"imageURL": "https://pumpapi.io/img/pumpapi_logo.webp",
"website": "https://pumpapi.io",
"telegram": "https://t.me/YOUR_TG",
"x": "https://x.com/realpumpapi",
"amount": "0.0001",
"denominatedInQuote": "true",
"priorityFee": "0.00002001",
}
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)
}
Multi-Wallet Launch​
You can launch your token and buy from multiple wallets in a single request, using either Jito Bundles or Actions. Both are supported — pick whichever fits your strategy:
- Jito Bundles — each buy is a separate transaction inside an atomic bundle. To outside observers the buys look unrelated, but no one can sandwich between them. Supports up to 5 transactions per bundle.
- Actions — all buys are packed into one transaction. Slightly cheaper, but on-chain everyone can see all the buys are connected. Limited to ~4–5 swaps per tx on Pump.fun due to Solana's tx size limit.
In both cases, use "mintRef": "0" on the create action to set a temporary token reference, then reuse the same mintRef on every buy so the backend knows which mint you're referring to.
- Jito Bundles (recommended)
- Actions
{
"jitoTip": 0.00001,
"transactions": [
{
"privateKey": "dev_wallet_key",
"action": "create",
"name": "PumpApi",
"symbol": "PAPI",
"imageURL": "https://pumpapi.io/img/pumpapi_logo.webp",
"mintRef": "0",
"initialTradeAction": "buy",
"amount": 0.5, # dev buy
"denominatedInQuote": true,
"slippage": 99
},
{
"privateKey": "wallet_b_key",
"action": "buy",
"mintRef": "0",
"amount": 0.3,
"denominatedInQuote": true,
"slippage": 99
},
{
"privateKey": "wallet_c_key",
"action": "buy",
"mintRef": "0",
"amount": 0.3,
"denominatedInQuote": true,
"slippage": 99
},
{
"privateKey": "wallet_d_key",
"action": "buy",
"mintRef": "0",
"amount": 0.3,
"denominatedInQuote": true,
"slippage": 99
},
{
"privateKey": "wallet_e_key",
"action": "buy",
"mintRef": "0",
"amount": 0.3,
"denominatedInQuote": true,
"slippage": 99
}
]
}
See the Jito Bundles page for full details.
{
"privateKey": "base58_fee_payer_key",
"actions": [
{
"privateKey": "dev_wallet_key",
"action": "create",
"name": "PumpApi",
"symbol": "PAPI",
"imageURL": "https://pumpapi.io/img/pumpapi_logo.webp",
"mintRef": "0",
"amount": 0.1,
"denominatedInQuote": true,
"priorityFee": 0.00002
},
{
"privateKey": "wallet_b_key",
"action": "buy",
"mintRef": "0",
"amount": 0.9,
"denominatedInQuote": true,
"slippage": 99,
"priorityFee": 0.00002
},
{
"privateKey": "wallet_c_key",
"action": "buy",
"mintRef": "0",
"amount": 0.9,
"denominatedInQuote": true,
"slippage": 99,
"priorityFee": 0.00002
}
]
}
You can also change the txSigner (the wallet that pays the fee) by setting privateKey at the top level — useful to avoid copy-traders. See the Actions page for full details.
Local Transactions​
Local (unsigned) transactions are supported too — just send publicKey instead of privateKey to receive an unsigned transaction, sign it on your side, and broadcast it yourself. See the Trade API page for local transaction code examples.
Cashback​
If you launched with cashbackToTradersEnabled: false (the default one, no need to pass it), creator trading fees can be withdrawn using the claimCashback method.
Custom Metadata URI​
This step is entirely optional. By default, we host your token metadata on our server so you can create a token with a single request.
If you want to use the standard Pump.fun method, you can upload your icon and metadata to IPFS yourself, then pass the resulting URI as "uri" when creating the token. When uri is set, the imageURL, description, telegram, and x fields are ignored.
Show IPFS upload example
- Python
- JavaScript
- Rust
- Go
import requests
# Define token metadata
uri_data = {
"name": "PumpApi",
"symbol": "PAPI",
"description": "Fast API for Pump.fun, Raydium, Meteora",
"twitter": "https://x.com/realpumpapi",
"telegram": "https://t.me/YOUR_TG",
"website": "https://pumpapi.io",
"showName": "true"
}
# Load your image
# Windows:
# with open("C:\\Users\\Admin\\Pictures\\coin_logo.webp", "rb") as f:
# file_content = f.read()
# Linux / macOS:
with open("/path/to/coin_logo.webp", "rb") as f:
file_content = f.read()
coin_logo = {"file": ("coin_logo.webp", file_content, "image/webp")}
# Upload to IPFS via Pump.fun
response = requests.post("https://pump.fun/api/ipfs", data=uri_data, files=coin_logo)
uri = response.json()["metadataUri"]
# Use the URI when creating your token
data = {
"privateKey": "base58_private_key",
"action": "create",
"name": "PumpApi",
"symbol": "PAPI",
"uri": uri,
"amount": "0.0001",
"priorityFee": "0.00002001",
}
response = requests.post("https://api.pumpapi.io", json=data)
print(response.json())
import axios from 'axios';
import fs from 'fs';
import FormData from 'form-data';
const uriData = {
name: "PumpApi",
symbol: "PAPI",
description: "Fast API for Pump.fun, Raydium, Meteora",
twitter: "https://x.com/realpumpapi",
telegram: "https://t.me/YOUR_TG",
website: "https://pumpapi.io",
showName: "true",
};
const form = new FormData();
Object.entries(uriData).forEach(([k, v]) => form.append(k, v));
form.append("file", fs.createReadStream("/path/to/coin_logo.webp"), "coin_logo.webp");
const ipfsRes = await axios.post("https://pump.fun/api/ipfs", form, {
headers: form.getHeaders(),
});
const uri = ipfsRes.data.metadataUri;
const data = {
privateKey: "base58_private_key",
action: "create",
name: "PumpApi",
symbol: "PAPI",
uri,
amount: "0.0001",
priorityFee: "0.00002001",
};
const response = await axios.post("https://api.pumpapi.io", data);
console.log(response.data);
use reqwest::{Client, multipart};
use serde_json::json;
use std::fs;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let file_bytes = fs::read("/path/to/coin_logo.webp")?;
let part = multipart::Part::bytes(file_bytes).file_name("coin_logo.webp");
let form = multipart::Form::new()
.text("name", "PumpApi")
.text("symbol", "PAPI")
.text("description", "Fast API for Pump.fun, Raydium, Meteora")
.text("twitter", "https://x.com/realpumpapi")
.text("telegram", "https://t.me/YOUR_TG")
.text("website", "https://pumpapi.io")
.text("showName", "true")
.part("file", part);
let ipfs_res: serde_json::Value = client
.post("https://pump.fun/api/ipfs")
.multipart(form)
.send()
.await?
.json()
.await?;
let uri = ipfs_res["metadataUri"].as_str().unwrap();
let res = client
.post("https://api.pumpapi.io")
.json(&json!({
"privateKey": "base58_private_key",
"action": "create",
"name": "PumpApi",
"symbol": "PAPI",
"uri": uri,
"amount": "0.0001",
"priorityFee": "0.00002001"
}))
.send()
.await?
.text()
.await?;
println!("{}", res);
Ok(())
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
// Upload to IPFS
var b bytes.Buffer
w := multipart.NewWriter(&b)
for k, v := range map[string]string{
"name": "PumpApi", "symbol": "PAPI",
"description": "Fast API for Pump.fun, Raydium, Meteora",
"twitter": "https://x.com/realpumpapi",
"telegram": "https://t.me/YOUR_TG",
"website": "https://pumpapi.io",
"showName": "true",
} {
w.WriteField(k, v)
}
f, _ := os.Open("/path/to/coin_logo.webp")
defer f.Close()
fw, _ := w.CreateFormFile("file", "coin_logo.webp")
io.Copy(fw, f)
w.Close()
ipfsResp, _ := http.Post("https://pump.fun/api/ipfs", w.FormDataContentType(), &b)
var ipfsResult map[string]interface{}
json.NewDecoder(ipfsResp.Body).Decode(&ipfsResult)
uri := ipfsResult["metadataUri"].(string)
// Create token
data := map[string]interface{}{
"privateKey": "base58_private_key",
"action": "create",
"name": "PumpApi",
"symbol": "PAPI",
"uri": uri,
"amount": "0.0001",
"priorityFee": "0.00002001",
}
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)
}
Response Format​
| Request type | Response |
|---|---|
| Single transaction | {"signature": "...", "createdMints": ["mint_address_1"], "err": ""} |
| Jito Bundle (up to 5 txs) | {"signatures": ["...", "..."], "createdMints": ["mint_address_1"], "err": ""} |
createdMints— array of mint addresses for every token created in the request. If you create multiple tokens in one Jito Bundle, you'll get multiple entries here.erris an empty string""on success, or the error message on failure.
Need help? Join our Telegram group.