Skip to content

Simple Strategies

Read every playlist as a strategy

playlist is the older name for the object this page calls a strategy. It is still the name in the API: in the paths, in the request and response fields, and in the reference section under Playlists.

The two words mean the same thing — an ordered set of trigger and action steps attached to one managed account. Nothing about the behaviour changes; only the label is stale.

A future API version will rename the resource and its fields to match the concept. Until that ships, send playlist in requests and expect playlist in responses. Write your integration against strategies and let the rename be a mechanical change later.

A simple strategy in Paros is an ordered set of trigger and action steps, plus optional stop conditions, attached to one managed account. It covers the automation that does not need a rule engine behind it.

Open in the reference ↗

Every strategy on this page is the same endpoint

There is no separate create endpoint per strategy. You set strategyTemplateId and the template decides which step grammar and which validator applies. Fourteen ids exist. Thirteen are usable today; gas_manage is reserved until gas management ships.


What you would use each one for

Sweep

Money drifts. A strategy finishes a round, proceeds land in one balance, the next round needs them somewhere else, and after a week the account is a patchwork of leftovers. sweep moves balances according to the rules you set, so the account keeps the shape you chose instead of the shape the last trade left behind. Pick it when the job is housekeeping rather than trading: consolidate what is idle, leave the working balance alone, and let the same rule run again tomorrow.

Open the diagram full screen ↗

Triggered

You have a level in mind and no intention of sitting at the screen waiting for it. triggered watches a price or balance condition and runs its action the moment the condition holds: buy when the price drops under your threshold, or move funds once a balance crosses a line. Use it when the timing is the point and a fixed schedule would arrive too late.

Triggered undeploy

The exit side of the same idea. triggered_undeploy pulls deployed funds back when a condition fires, so a position you opened with triggered can close itself at the level you named. This is the template for a stop, for taking profit at a target, or for flattening before a weekend nobody wants to watch.

Open the diagram full screen ↗

Scheduled buy

Dollar-cost averaging without a cron job on your side. schedbuy buys a fixed amount on the cadence you set, so a position builds at prices spread across the period rather than at whatever the market prints on the day you finally decide. It suits accumulating a token over weeks, or splitting a large intended purchase so one bad fill does not set the entry price for all of it.

Distribute

One pile of funds, several places it has to reach. distribute splits the amount across your targets on a schedule, so each target receives its share without a run of manual transfers that someone has to remember and reconcile. A funding account paying out to several trading accounts at the start of each month is the usual shape.

Scheduled undeploy

Some capital has an end date written into it. scheduled_undeploy removes deployed funds at the time you set, which fits a fixed-term allocation, a quarter-end cleanup, or a position you only want open over a weekend. Set it when the strategy starts and the exit stops depending on a person remembering.

Open the diagram full screen ↗

Maintain

The point of maintain is the ratio, not the amount. You give it a target allocation and it corrects drift as prices move, so a book meant to sit at 60/40 is still 60/40 after one side runs. Use it instead of rebalancing by hand every time the market makes the decision for you.

Replenish

replenish tops a balance back up when it falls under a floor you set. That matters wherever an empty balance stops work: a trading balance draining as strategies place orders, a working balance that has to be funded before the next run. You choose the floor and replenish keeps it.

Open the diagram full screen ↗

Simple account transfer

simple_account_transfer moves funds from one managed account to another. Use it when the capital lives in one account and several accounts draw from it: a weekly transfer from the treasury account to each desk, or profit moving back once an account is larger than the size you want it to trade.

Internal account transfer

The same idea inside a single account. internal_account_transfer moves funds between the balances of one managed account, which is what you want when the money should not leave the account at all. It keeps a trading side funded from a storage side without an external transfer.

Open the diagram full screen ↗

Hyperliquid deposit

hyperliquid_deposit puts funds into your Hyperliquid account from the managed account. This is the funding step before anything trades on the venue, and the same strategy can bring the venue balance back up after a withdrawal or a run of losses has drawn it down.

Hyperliquid withdraw

hyperliquid_withdraw takes funds back out of Hyperliquid into the managed account. Use it to bank gains at a point you choose, or to pull collateral out before you change what the account is doing.

Hyperliquid stage funds

hyperliquid_stage_funds moves what the next Hyperliquid action will need into place before that action runs. Reach for it when the money is not where the deposit or the trade expects to find it, so the action does not fail on a balance that was never moved. Pair it with a deposit strategy when the funds start somewhere else.

Open the diagram full screen ↗


The template ids

strategyTemplateId selects the step grammar and the validator that runs on save.

Template id What it does
sweep Moves balances according to the rules you set
triggered Runs an action when a condition fires
schedbuy Buys on a schedule
distribute Distributes funds across targets on a schedule
scheduled_undeploy Removes deployed funds on a schedule
triggered_undeploy Removes deployed funds when a condition fires
maintain Holds a target allocation, rebalancing as balances drift
replenish Tops up a balance when it falls below a floor
simple_account_transfer Moves funds between managed accounts
internal_account_transfer Moves funds within one account
hyperliquid_deposit Deposits into Hyperliquid
hyperliquid_withdraw Withdraws from Hyperliquid
hyperliquid_stage_funds Stages funds ahead of a Hyperliquid action

gas_manage is the fourteenth id. It is reserved and not usable yet, so it is not listed above.


The shape of a strategy

Three parts, and they are independent of each other. The steps decide what happens. The stop conditions decide when it all ends. The account binding decides where the money can move.

Open the diagram full screen ↗


Create a strategy

Open ↗

POST /api/playlists
{
  "accountId": "{id}",
  "customerId": "{customerId}",
  "name": "Top up USDC when low",
  "description": "Keeps the trading account funded",
  "strategyTemplateId": "replenish",
  "status": "draft",
  "steps": [],
  "stopConditions": [],
  "metadata": {},
  "alertSettings": {}
}

Required: accountId, customerId, name, steps, strategyTemplateId. status is optional and defaults to draft behaviour.


Steps

steps is an ordered array. Each entry carries four fields:

Field Detail
order Position in the array. Unique and ascending within a strategy
stepType trigger or action
type The step type, for example instant
config Object whose shape depends on the step type

An instant trigger runs immediately and looks like this:

{ "order": 1, "stepType": "trigger", "type": "instant", "config": { "type": "instant" } }

Time triggers carry a startDate. Balance and price triggers carry a threshold and an operator.

Triggers come before the actions they gate. A body that breaks the template's grammar comes back as a 400 with details naming the failing path.


Stop conditions

stopConditions is an array of conditions that end the strategy. Each one carries:

Field Detail
scope What the condition watches. Must reference a valid scope
type The condition type, for example END_DATE
config Condition settings, such as stopAt
actionOnTrigger What happens when the condition fires
enabled Set false to keep a condition configured but inactive

A disabled condition is not validated on save and does not fire at run time.


Read, update, delete

Open ↗

GET    /api/playlists
GET    /api/playlists/{id}
PUT    /api/playlists/{id}
DELETE /api/playlists/{id}

List query parameters are all optional: page, limit, status, strategyState, strategyTemplateId, accountId, customerId, search, orderBy, orderDirection.

PUT accepts the same fields as create, all optional. Send only what changes. DELETE returns 400 when the strategy cannot be deleted in its current state; pause it instead.


Pause and resume

Open ↗

POST /api/playlists/{id}/pause
POST /api/playlists/{id}/resume

Both take an optional body with reason, stepInTriggerCategory and stepInReason. Pause stops a running strategy without deleting its configuration, which is the right move when you want the setup back later.


Monitoring

Open ↗

GET /api/playlists/{id}/stop-condition-progress
GET /api/playlists/{id}/stop-condition-history?limit={n}
GET /api/playlists/{id}/alert-settings
PUT /api/playlists/{id}/alert-settings

stop-condition-progress reports how close each stop condition is to firing. stop-condition-history returns past firings. The alert settings endpoints read and replace the notification configuration for that strategy.


Validation on save

These rules run on create and update, and they are the most common cause of a 400.

Rule Detail
End date must be in the future An enabled END_DATE condition whose config.stopAt is in the past is rejected. The failing path is stopConditions[i].config.stopAt
Start date must not be in the past A time trigger startDate in the past is rejected, at the top level or inside a composite branch
A bare date is read as a day YYYY-MM-DD counts as past only after that whole day has ended
Disabled conditions are skipped A condition with enabled: false is not validated at all
Format is checked before the date The YYYY-MM-DDTHH:mm format check fires before the past-date refinement, so an absolute UTC timestamp copied from another strategy is rejected even when the instant is still ahead

Only API requests are validated

Internal service callers bypass these checks, so a strategy created by the platform is not held to the same rules. Your own 400 means your own body, and details names the field.

Respond to the path, do not guess

When the validator rejects a body, details names the failing path. Read the path and fix that field. Rewriting the date format by hand and retrying is how the same 400 comes back twice.


Ordering

Steps must satisfy the template's grammar. Triggers precede the actions they gate, order values are unique and ascending within the array, and a stop condition must reference a valid scope.

For a worked deposit inside a longer sequence, see step 4 of the Trading Call Flow.