Buy, sell & batches
Single buys and sells, many-wallet batches, and what a slow batch turns into.
Trades from the API use the same swap engine as the Trade Panel: the same routing, platform fee and ledger. Each needs the trade scope.
Pick the wallet#
Every trade names one wallet:
walletId— a wallet already in your account (see Wallets, portfolio & PnL).privateKey— a key you hold. It is imported into your account as a wallet the first time and reused after that, exactly like importing on the Wallets page. The key is never sent back by the API.
Buy#
POST /buy
{
"mint": "7xKX…pump",
"walletId": "812",
"amountSol": 0.05,
"slippageBps": 1500,
"dryRun": false
}| Field | |
|---|---|
mint | Token address |
walletId or privateKey | Exactly one |
amountSol or amountRaw | Exactly one. amountSol is in the chain's coin (SOL, or ETH on EVM chains); amountRaw is its smallest unit as a string |
slippageBps | 1–10000. Falls back to the key's default slippage |
chain | Optional; worked out from the mint when left out |
poolAddress, dex | Optional: force a pool or venue |
computeUnitLimit, computeUnitPriceMicroLamports | Optional Solana priority settings |
dryRun | true simulates the trade and sends nothing. Default false |
A sent trade returns:
{
"confirmed": true,
"signature": "zeG4fznpHbhHbMHZp9XfMLKm6kqNQWq5XifHhFK2ubTPfG8C32GQ69SxKLbv8jtawmzKEzva42XT2D9Ym2hFxoH",
"err": null,
"poolAddress": "6NihTYwWoTQcMVimRA2wFxFoGxZwTFvefCVJ44UYTLoN",
"dex": "pump_fun",
"expectedOut": "326807208282",
"landedOut": null,
"nativeReceipt": null,
"minOut": "326807208282"
}| Field | |
|---|---|
confirmed | true once the transaction landed on chain |
signature | The on-chain signature (null if nothing was sent) |
err | The chain error if it failed, else null |
poolAddress, dex | The pool and venue the swap used |
expectedOut | Tokens the quote expected, in base units |
landedOut | Tokens actually received once known, else null |
minOut | The minimum accepted after slippage |
nativeReceipt | On a sell, coin received once known, else null |
A simulation (dryRun: true) sends nothing and returns the quote plus the simulated transaction result:
{
"dryRun": true,
"poolAddress": "6NihTYwWoTQcMVimRA2wFxFoGxZwTFvefCVJ44UYTLoN",
"dex": "pump_fun",
"expectedOut": "35254150228",
"minOut": "35254150228",
"simulation": { "err": null, "unitsConsumed": 108524, "logsTail": ["…"] }
}Sell#
POST /sell takes the same body, but the amount is one of:
percentage— 0–100 of what the wallet holds right now.amountRaw— token base units.
amountSol is refused on a sell. A wallet holding none of the token returns 422 with code: "unprocessable".
The response is the same shape as a buy.
Batch#
POST /trade/batch trades one token from many wallets at once.
{
"mint": "7xKX…pump",
"side": "buy",
"walletIds": ["812", "813", "814"],
"amountMode": { "type": "uniform", "amountRaw": "20000000" },
"intervalMs": [0, 400],
"dryRun": false
}amountMode.type | |
|---|---|
uniform | amountRaw for every wallet |
individual | amountsRaw: one per wallet, in the same order |
token_percentage | percentage of each wallet's balance (sells; a restricted key can't use it on buys) |
intervalMs is [min, max]: a random wait between wallets. Up to 500 wallets, no repeats.
A batch that runs at once returns a per-wallet report:
{
"source": "api",
"side": "buy",
"mint": "7xKX…pump",
"requested": 2,
"successful": 2,
"failed": 0,
"totalInput": "20000000",
"totalOutput": "705570950744",
"results": [
{
"walletId": "812",
"ok": true,
"signature": "2CykMFSe…budB",
"confirmed": true,
"amountIn": "10000000",
"expectedOut": "352902292117",
"landedOut": null,
"minOut": "352902292117",
"err": null
}
]
}Slow batches become a Buy task#
A call can't stay open for minutes. When walletIds × max interval is over 60 seconds:
- A buy starts as a Buy task with the same wallets, amounts and pacing. The response is
202:
{
"taskId": "1932",
"status": "started",
"task": { "id": "1932", "type": "buy", "status": "running" }
}Follow it with GET /tasks/1932, or on the tasks stream.
- A sell is refused with
400andcode: "bad_request". Use shorter intervals, or split it into several batches.
With a daily cap, the whole batch counts against today the moment the task starts.
Without dryRun: true, buys and sells are sent on chain immediately. There is no confirmation step.
Convert#
Convert is the Wallets page's Convert dialog: one wallet's token to SOL or USDC (or back) through the Jupiter rail — a wallet-level swap for tidying balances, not a curve trade. It spends only network fees and the token accounts the route opens.
| Method & path | Scope | Does |
|---|---|---|
POST /convert/assets | read | { "walletIds": [ … ] } → every token the wallets hold with a balance per wallet, plus the destinations you can convert into |
POST /convert/quote | read | The quote for one conversion |
POST /convert | trade | Do it |
{ "walletId": "812", "inputMint": "EPjF…Dt1v", "outputMint": "So111…112", "all": true, "slippageBps": 100, "dryRun": true }Send amountRaw (base units) or "all": true, never both. dryRun defaults to true. Wrapped SOL is a token here ("wrapped-sol"): unwrap it to SOL first, then convert. The assets read scans each wallet on chain and can take a while for many wallets.
Burn and lock#
POST /tokens/burn burns part of one wallet's bag, POST /tokens/lock locks it until a date. Both need trade and rehearse by default.
{ "walletId": "812", "mint": "7xKX…pump", "amount": "25", "amountType": "percentage", "dryRun": true }amountTypeistokens(a token amount) orpercentage(of the wallet's balance).amountis a decimal string.- Lock also takes
unlockDays(down to one hour,1/24) or a UnixunlockTimestamp, and an optionalname. - The answer is
{ "ok", "signature", "burnedAmount" | "lockedAmount", "dryRun", "error" }. A wallet with nothing to burn answersok: falsewith the reason, not a500.
Creator fees#
GET /tokens/creator-fees?mint=… (read) is what the token's creator can claim on each venue: { "mint", "creatorWalletId", "creatorAddress", "venues": [ { "venue", "claimable", "quoteMint", "coolingDown" } ] }. POST /tokens/creator-fees/claim (trade) claims them: { "mint": "…", "dryRun": false } → { "ok", "signature", "claimed": [ { "venue", "amount" } ] }. The creator wallet must be one of yours.
See also#
- Limits, retries & errors: retry a trade safely with
Idempotency-Key, and every errorcode - Platform fees & tiers