Launch a token
Launch a token from code, with its image, creator wallet, first buys and launch tasks.
POST /launch creates a new token, just like the create form in the app. It needs a key with the launch scope. The token becomes a project in your account.
POST /launch only simulates unless you send "dryRun": false. A dry run checks the whole launch and sends nothing. Run one first.
Before you start#
- A key with the
launchscope. A restricted key can only send dry-run launches. - A creator wallet with enough coin to pay for the launch and any first buy.
- A picture for the token: PNG, JPEG, GIF or WebP, up to 10 MB.
A first launch#
curl -s -X POST https://api.vortexdeployer.com/api/v1/launch \
-H "Authorization: Bearer vd_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: launch-vcat-0001" \
-d '{
"launchpad": "pump",
"name": "Vortex Cat",
"symbol": "VCAT",
"description": "gm",
"imageUrl": "https://example.com/cat.png",
"creatorWalletId": "812",
"devBuySol": 0.5
}'This is a dry run, because dryRun is left out. When the answer looks right, send the same body with "dryRun": false and a new Idempotency-Key.
The body#
Required#
name— 1–32 characters.symbol— 1–10 characters.- The image — send one of:
imageUrl— a publichttpslink to the picture. The API downloads and checks it.imageBase64— the picture as base64, or adata:URL. AddimageContentType(image/png,image/jpeg,image/giforimage/webp; defaultimage/png).
- The creator — send one of:
creatorWalletId— a wallet in your account. It becomes the project's dev wallet.creatorPrivateKey— a wallet's private key. The API adds the wallet to your account first.
Where and how it trades#
launchpad— the launchpad that creates the token:pump(default),raydium_launchlab,bonk,bonkers,stonkfun,meteora_dbcorpons.ponsis on Robinhood Chain; the rest are on Solana.quoteToken— the quote token the price is counted in:sol(default),usdc,usd1,ethorstock. Each launchpad takes only some of them. See Which quotes a launchpad takes.pairToken— the address of the pair token, when the quote needs one. Every StonkFun launch and every pump.funstocklaunch needs it. Onponsit is optional.
The creator's first buy#
The dev buy is the creator wallet's own buy, sent with the launch. Use one field:
devBuySol— spent in SOL, 0–85. For SOL pairs and stock pairs.devBuyQuote— spent in the quote the creator holds, like USDC. 0–1,000,000.devBuyEth— onponsonly, in ETH, 0–10.devBuySlippageBps— 0–10000, default 500.
GET /launchpads tells you which field each quote uses (devBuyField).
Optional#
description— up to 1000 characters.twitter,telegram,website— links, up to 200 characters each.buys— up to 24 other wallets that buy in the same moment as the launch. Each is{ "walletId": "813", "amountSol": 0.3 }or{ "privateKey": "…", "amountSol": 0.2 }.amountSolis above 0 and at most 85. A wallet may appear once. Solana only. They ride the launch as one bundle.tasks— up to 20 tasks that start when the token exists. See Launch tasks.launches— 1–10. Makes the same token that many times in a row. See Several launches in one call.launchAt— launch later. See Schedule a launch.projectId— a draft project to fill in, made earlier withPOST /projects. Without it, a new project is made.mintSecret— the secret key of a token address you made yourself (a "vanity" address). Solana only, withlaunches: 1, and the address must be unused.expectedMint— the token address you expect. The launch stops if it would use another one.launchId— your own id, up to 64 characters. It comes back on every livelaunchevent for this launch.provider— where the image and token info are stored:local(default),pumpfunorpinata.computeUnitLimit(default 250,000),computeUnitPriceMicroLamports(default 50,000) — Solana fee settings.dryRun—true(default) simulates,falsesends.
Some fields belong to one launchpad. They are refused on any other:
- pump.fun:
isMayhemMode,isHolderReward,otcDesks(SOL pairs only),pumpCreatorFeeBps(1–300,stockpairs only). - StonkFun:
stonkfunMode(standard,rewardorcommunity) andstonkfunRewardTaxBps(100or300).communityworks only on a stock that offers it. On any other stock the launch is refused with a 400: "StonkFun Community Mode is not offered on SYMBOL — pick Standard or Reward, or another pair".GET /launchpads/stonkfun/quotesdoes not say which stocks offer it. - pons:
creatorFeeMode(creator,holdersorcustom),creatorFeeAddress(withcustom),creatorTaxBps,buybackEnabled.
The full list, with every limit, is in https://api.vortexdeployer.com/api/v1/openapi.json.
Launch tasks#
tasks is the list of tasks the launch creates for the new token. They work like tasks made after the launch, but you write them on the launch itself. You do not create them first.
Each task has:
type— the engine:bundle,sniper,buy,volume,antisniper,holderboost,handswitcher,fakevolume,protrader_boost,limit_order,ladder,mirror,dca,trailing_stoportokendisperser.walletIds— the wallets it uses. They must be yours, and on the key's list if it has one. It may be empty only for alimit_orderwhoseconfig.walletSourceisallorroles.config— the engine's settings. These are the same keys as in aPOST /tasksbody. Leave outmintandchain; the launch fills them in.label— optional, up to 120 characters.autostart—true(default) starts the task the moment the token exists.falseleaves it waiting on the project.
"tasks": [
{ "type": "sniper", "walletIds": ["814", "815"], "config": { "buyMode": "range", "minBuySol": 0.03, "maxBuySol": 0.05 } },
{ "type": "dca", "walletIds": ["816"], "autostart": false, "label": "later",
"config": { "side": "buy", "everyMs": 60000, "sizeUnit": "native", "sizeValue": 0.01, "maxFires": 10 } }
]Check each engine's fields on the Tasks API page and in the OpenAPI document. A field the engine does not know is ignored, and the default is used instead. For sniper and buy, the default buyMode is full_balance: every picked wallet spends almost all of its coin.
Rules:
- Every task is checked before anything is sent. A bad setting refuses the whole launch with
400 validation_failed, anddetailspoints attasks[i].config. - The launch's
dryRundecides for every task. AdryRuninsideconfigis ignored. - Most engines have no dry run. Only
sniper,buyandtokendispersercan ride a dry-run launch. Any other type, andbuys, refuse a dry run with400. To try the launch, leave those out. - A trading task leaves the creator wallet out, unless it is the only wallet you picked or
config.includeDevistrue. - A key limited to a wallet list must name
walletIds. It cannot usewalletSource.
POST /launch/affordability takes the same tasks list, so you can price the plan first.
What a launch returns#
{
"projectId": "1021",
"mint": "J11L…pump",
"creator": "6729…CE88",
"launchpad": "pump",
"quoteToken": "sol",
"pool": null,
"dryRun": false,
"signature": "3BNE…L98",
"confirmed": true,
"err": null,
"devBuyTokens": "17504000000000",
"uri": "…/metadata/….json",
"imageUri": "…/image/….png",
"tasks": [ { "type": "sniper", "taskId": "4400", "started": true } ]
}mint— the new token's mint address.signature,confirmed,err— the create transaction, as for a trade.devBuyTokens— tokens the dev buy got, in base units, ornull.uri,imageUri— where the token info and picture are stored.tasks— one entry per launch task: itstaskIdandstarted, or anerror.simulation— on a dry run only:{ "err", "unitsConsumed", "logsTail" }. A dry run hassignature: nullandconfirmed: false.
Some launches add more: bundle (the buys in the bundle), preSwap (a swap into the quote before the launch), creatorFees, otcDesks, and on pons launchBuys and the quote's quoteMint, quoteSymbol and quoteDecimals.
Several launches in one call#
With launches above 1, the API makes the same token again and again, one after another. Each launch has the same name, creator, dev buy and tasks. The answer is the first launch plus a batch report:
requestedandlanded— how many you asked for and how many were made.launches— one entry per launch.stoppedAt,stopReason— where and why the run stopped, if it did.affordable,affordabilityStop— how many launches the wallets could pay for.
Before a real run, the API counts how many launches the wallets can pay for. It makes only that many, and never fewer than one. The run also stops at the first later launch that fails. Launches already made stay up with their tasks running. A dry run tries one launch, whatever launches says.
Schedule a launch#
launchAt is a date and time with a time zone, like "2026-10-20T15:00:00Z". It must be at least 30 seconds ahead and at most 30 days ahead.
The API stores the token info at once and answers 202:
{ "scheduled": true, "taskId": "4401", "projectId": "1022", "launchAt": "2026-10-20T15:00:00Z", "uri": "…", "imageUri": "…" }Nothing is made until then. The launch waits as a task of type scheduled_launch on the project. Stop that task to cancel. launchId cannot be used with launchAt.
Which quotes a launchpad takes#
Two read calls answer this:
GET /launchpads— every launchpad, its chain, and thequoteTokenvalues it takes. For each quote it says whether apairTokenisnone,optionalorrequired, and itsdevBuyField.GET /launchpads/:launchpad/quotes— what a launch there can use right now. Each entry has the exactquoteTokenandpairTokento send.
Today the rules are:
| Launchpad | Quotes |
|---|---|
pump | sol, usdc, stock |
raydium_launchlab, bonk, bonkers | sol, usd1 |
meteora_dbc | sol |
stonkfun | stock |
pons | eth, or an approved pair token |
Stock lists change when the launchpad changes them. If a launchpad's list cannot be read, the answer is 503. Try again. An unknown launchpad is 404.
Checks before you launch#
These calls check a launch and make nothing. All need read, except POST /launch/metadata, which needs launch.
| Call | What it does |
|---|---|
GET /launch/readiness | Says if real launches are on. killSwitch: true means real sends are on. false means the kill switch is engaged: real launches are refused for everyone right now, and dry runs still work. |
GET /launch/mint-address?launchpad=pump | The token address the next launch there will get. |
POST /launch/clone | { "chain", "address" } of an existing token. Returns its name, symbol, description, links and picture, ready for a launch body. |
POST /launch/affordability | How many of launches the creator and buyers can pay for, from live balances. |
POST /launch/supply-preview | What share of the supply each first buy would get. |
POST /launch/metadata | Stores the picture and token info now. Returns uri and imageUri. |
GET /launch/pons/launch-terms | The current pons terms. |
GET /launch/otcdesks/rewards | The rewards an OTC Desks pairing can pay. |
Supply plans#
A supply plan is a saved layout of first buys, as a share of the token's supply per wallet slot.
GET /supply-plans(read) — your plans.POST /supply-plans(trade) — save one.DELETE /supply-plans/:id(trade) — remove one.POST /supply-plans/:id/mount(read) — fit a plan to wallets. SendwalletIdsand eitherlaunchpadandquoteTokenfor a new token, ormintfor a token that already trades.
{
"name": "12 wallets, 18%",
"slots": [ { "targetPercent": 1.5, "walletId": "812" }, { "targetPercent": 1.5, "role": "trading" } ],
"maxTotalPercent": 18,
"maxWalletPercent": 2
}A slot can name a walletId, or a role the wallet must have. A slot with neither takes the next wallet you send when you mount the plan. The slots may not add up to more than 100%.
Refusals#
| Status | Code | When |
|---|---|---|
400 | validation_failed | A field is missing or out of range, or a launch task's config is wrong. details names it. |
400 | bad_request | Two images or no image, two creators or none, buys on a non-Solana launchpad, or a picture that is not a real image. |
403 | key_restricted | A restricted key sent dryRun: false. |
403 | wallet_not_allowed | A wallet is not on the key's list, or a task's wallet is not yours. |
403 | forbidden | The creator wallet is not yours. |
403 | private_key_not_allowed | A wallet-list key sent a private key. |
409 | conflict | projectId already has a token. |