DocsAPI

Tasks API

Create, start, edit and follow tasks from code, and read your activity feed.

A task is a job that trades for you over time, like a volume run or a ladder of sells. The API makes the same tasks as the app, and they show up in the app too.

Before you start#

  • Reading tasks needs the read scope. Creating and controlling them needs trade.
  • Creating, editing, starting and resuming need a key with no limits. A restricted key gets 403 key_restricted. Pausing, stopping and deleting work with any trade key.
  • Tasks are real by default. They send real transactions unless their config says "dryRun": true, and many types cannot do a dry run at all. See Dry runs.

Routes#

CallScopeWhat it does
GET /tasksreadYour tasks.
GET /tasks/:idreadOne task.
POST /taskstradeCreate a task.
PATCH /tasks/:idtradeChange its label, settings or wallets, even while it runs.
POST /tasks/:id/starttradeStart it.
POST /tasks/:id/pausetradePause it.
POST /tasks/:id/resumetradeGo on after a pause.
POST /tasks/:id/stoptradeStop it.
DELETE /tasks/:idtradeDelete a task that is not running.
POST /tasks/stop-alltradeStop all your running and paused tasks.
POST /tasks/:id/previewreadWhat a start would do now. Sends nothing.
GET /tasks/:id/executionsreadThe trades it sent.
GET /tasks/:id/postmortemreadHow each wallet did, and why any failed.
GET /tasks/:id/playbookreadLive state of a limit order, ladder, mirror, DCA or trailing stop.
GET /tasks/:id/mixer-ordersreadA mixer task's orders.
POST /tasks/:id/mixer-orders/:orderId/recipients/:recipientId/executetradeSkip the wait for one mixer recipient.
GET /tasks/:id/dispersereadA SOL-spreading task's wallets and progress.
GET /tasks/presets, POST /tasks/presets, DELETE /tasks/presets/:idread / tradeSaved settings.
GET /eventsreadYour activity feed.
GET /warmup/candidatesreadTokens the wallet warm-up task would trade now.

Create a task#

POST /tasks:

{
  "type": "buy",
  "mint": "7xKX…pump",
  "walletIds": ["812", "813"],
  "label": "morning buys",
  "config": {
    "buyMode": "exact",
    "walletAmounts": { "812": 0.1, "813": 0.05 },
    "minDelayMs": 2000,
    "maxDelayMs": 9000
  },
  "autostart": false
}
  • type — the engine. See Task types.
  • mint — the token's mint address.
  • walletIds — the wallets it uses. They must be yours. It may be empty only for a limit_order whose config.walletSource is all or roles.
  • config — the engine's settings. Each engine has its own fields.
  • chain — optional. Left out, it comes from the mint's address.
  • label — optional, up to 120 characters.
  • projectId — optional. Puts the task under one of your projects.
  • autostart — true starts it at once. Default false.

The answer is 201 with the task. A wallet that is not yours gets 403 forbidden. Bad settings get 400 validation_failed, and details names the field.

Check the spelling of every setting

A config field the engine does not know is ignored, and its default is used instead. Some defaults spend a lot. For buy, the default buyMode is full_balance: each wallet spends almost all its coin. Read the task back with GET /tasks/:id and check config before you start it.

Task types#

Each type's settings match its form in the app. Its docs page explains them.

typePage
buyBuy
volumeVolume
fakevolumeFake volume
holderboostHolder boost
protrader_boostPro trader boost
handswitcherHand switcher
antisniperAnti-sniper
bundleBundle
migrate_and_buyMigrate and buy
tokendisperserToken sender
mixerMixer
warmupWallet warm-up
limit_orderLimit order
ladderLadder
mirrorMirror
dcaDCA
trailing_stopTrailing stop

Some types follow special rules:

  • sniper is a launch task only. Add it to tasks on POST /launch. On a token that already trades, use buy.
  • batch is made for you by a slow POST /trade/batch. See Buy, sell & batches.
  • scheduled_launch is made for you by POST /launch with launchAt. See Launch a token.
  • devwarmup needs exactly one wallet. Starting it needs the highest fee tier, or it gets 403.
  • soldisperser, solcollector, tokencollector and sendsol move coins between your wallets.

Dry runs#

Types such as buy, migrate_and_buy, warmup, tokendisperser and mixer take "dryRun": true inside config. The task walks through its steps and sends nothing. Its trades show up as simulated.

These types have no dry run: volume, bundle, antisniper, holderboost, handswitcher, fakevolume, protrader_boost, limit_order, ladder, mirror, dca and trailing_stop. They refuse "dryRun": true with 400 validation_failed. Start them with small amounts first.

POST /tasks/:id/preview shows what a start would do right now, from live balances. Nothing moves. A type with no preview, like the ones above, gets 400.

Control a task#

A task's status is one of:

  • idle — made, not started.
  • running — working now.
  • paused — waiting for resume.
  • completed — done.
  • failed — stopped by an error. lastError says why.
  • stopped — stopped by you.
  • timeout — ran out of time.

start, pause, resume and stop answer with the task. A call that does not fit the status, like pause on a stopped task, gets 409 conflict. A finished task can be started again.

PATCH /tasks/:id takes label (null clears it), config and walletIds. Send at least one. A running task picks up the change in place.

DELETE /tasks/:id works only when the status is idle, completed, failed, stopped or timeout. Otherwise it gets 409, so stop the task first. The answer is { "ok": true, "id": "6186" }. The task leaves your lists, but its trades stay in your history.

POST /tasks/stop-all stops all your running and paused tasks. One failure does not block the rest:

{ "requested": 3, "stopped": ["6186", "6190"], "failed": [ { "id": "6201", "error": "…" } ] }

Read a task#

GET /tasks answers { "tasks": [ … ] }.

  • Filter with ?status= or ?type=.
  • Page with ?limit= (1–500, default 200) and ?offset=. The full count is in X-Total-Count.
  • ?status=active lists your running and paused tasks, with no paging.
  • ?mint= lists the tasks on one token, with no paging.

A task looks like this:

{
  "id": "6186",
  "type": "buy",
  "status": "running",
  "running": true,
  "chain": "solana",
  "mint": "7xKX…pump",
  "label": "morning buys",
  "projectId": null,
  "walletIds": ["812", "813"],
  "config": { "buyMode": "exact", "…": "…" },
  "lastError": null,
  "createdAt": "2026-09-16T01:09:24.500Z",
  "updatedAt": "2026-09-16T01:09:24.531Z",
  "startedAt": "2026-09-16T01:09:24.531Z",
  "stoppedAt": null
}

GET /tasks/:id/executions answers { "executions": [ … ] }, newest first. Each row has:

  • walletId, side (buy or sell), signature, confirmed, err and createdAt;
  • amountIn and amountOut, in base units;
  • outcome — filled, pending, failed or simulated.

Take up to 500 rows with ?limit= (default 50). For older rows, send the last row's id as ?before=.

A task that is not yours answers 404, as if it did not exist.

Presets#

A preset saves a task's settings under a name.

  • GET /tasks/presets — answers { "presets": [ … ] }.
  • POST /tasks/presets — send { "name": "fast buys", "type": "buy", "config": { … } }. The name is 1–64 characters. Saving under a name you already used replaces that preset. Answers 201 with { "preset": … }.
  • DELETE /tasks/presets/:id — answers { "deleted": "…" }, or 404.

A preset's settings are not checked when you save it. They are checked when you send them in POST /tasks.

Events#

GET /events is your activity feed: every task change and every trade, one row each, newest first.

{
  "events": [
    { "id": "918273", "ts": "2026-09-16T20:11:02.000Z", "category": "execution", "type": "task_execution",
      "severity": "success", "taskId": "6605", "mint": "7xKX…pump", "walletId": "812", "title": "Buy landed", "data": { } }
  ],
  "nextBefore": "918200"
}
  • Filter with category (task or execution), taskId, mint or severity (info, success, warn, error).
  • limit is 1–200, default 50.
  • For the next older page, send nextBefore back as ?before=. It is null on the last page.

GET /warmup/candidates?chain=solana&limit=20 lists the tokens the warm-up task would trade right now.

Follow a task live#

Subscribe to the tasks topic on the live stream with a read key. You get your tasks now, then every change as it happens. This beats asking GET /tasks again and again.

See also#