Buy orders
Place a buy order to get compute time on a pool.--max-rate is the most you’ll pay in dollars per
node-hour; 1 node is 8 GPUs. You can also use --max-price to set a maximum total for the order
instead.
--allow-standing.
--allow-partial to let it fill part of
the requested nodes or time window instead, which leaves the order partially_filled.
Pin to a SKU
You pin every order to a single SKU; the order fills only on that SKU. Pass--instance-sku <id> to pick one directly.
sf orders create without --instance-sku opens an interactive picker that shows every
registered SKU’s name, ID, and properties. In non-interactive mode (--no-input), --instance-sku
is required. Run sf skus list to browse them beforehand. See
SKUs for the full model.
Sell orders
Sell back compute time you own.Sell orders are not guaranteed to fill. Use
--allow-standing to keep the order on the orderbook
until a buyer matches.Sell fees
When a sell order executes, SF Compute deducts a variable platform fee from the fill price. You receive the fill price minus the fee as credits. The CLI shows the estimated fee before you confirm an order. Buy orders have no fees.Holds
Placing an order reserves what a fill would need, so a match can always settle. A buy order holds credits equal to its worst case, the limit price across the full requested window and node count. Your available balance is what remains after open holds. Placement fails with an insufficient-balance error when your available balance can’t cover the hold. A sell order instead reserves the pool allocation it offers, so the same compute can’t be sold twice. When a fill executes, you pay the fill price and SF Compute releases the unused part of the hold. Cancelling the order or letting its remaining window elapse releases the rest.Order statuses
A standing order (buy or sell) rests until it fills, you cancel it, or its window fully elapses. As
the current time passes the order’s start, it keeps matching only over the un-elapsed remainder of
its window. It matches at its original per-node-hour limit price. The order’s total value shrinks as
time elapses.
Once the whole window has elapsed the order stops matching and moves to
cancelled; there is no
separate expiry or time-to-live field. This lapse timing is current behavior, not a guarantee.
Check an order
Look up a single order by ID.List orders
List orders in the active workspace.--all.
--created-after and --created-before accept a datetime, Unix timestamp, or a duration like 24h
or 7d. A duration means that long ago (24 hours or 7 days, respectively). You can also use
--since and --until as aliases.
Cancel an order
Cancel an order that hasn’t fully filled yet.204 No Content on the API). A
matching batch already in progress can still land a fill before the state flips to cancelled. Poll
GET /v2/orders/{id} until it does.
Cancellation removes only the unfilled remainder from the orderbook and keeps the fills that
executed before it. Once the order is cancelled, its fills and
filled_allocation_schedule_delta are final and remain readable on the order in both get and list
responses.
Time formats
Order start and end times must be hour-aligned, or any minute up to the end of the next hour. The finest granularity is 1 minute. The end must be after the start. The start can reach at most 5 minutes into the past, and the end at most 10 years into the future. The CLI rounds a time you enter to a valid boundary and notes when it does. Orders that startnow
begin immediately. See the Orders API reference for the
full list of schedule constraints. The CLI accepts several time formats.
nowfor the current timein 6horin 2dfor relative timestomorrowormar 15for natural language dates2025-03-15T10:00:00Zfor ISO 8601- Unix timestamps
1h, 7d, 2w.
Allocation schedule deltas
allocation_schedule_delta describes how many nodes an order requests or offers during one or
more time intervals.
start_at and end_at set the segment’s time
bounds, while node_count specifies how many nodes apply during that interval. Multiple entries
can describe different node counts over adjacent intervals.
Schedule entries describe half-open intervals [start_at, end_at): the node count applies at
start_at, but not at end_at. Adjacent entries therefore meet without overlapping. All segments
on an order refer to that order’s single instance_sku.
In responses, a non-empty array always ends with a terminator entry whose end_at is null and
node_count is 0, marking the schedule as open-ended and empty after the last segment. A schedule
with no capacity is returned as an empty array. Requests carry only the closed [start_at, end_at)
segments you submit and omit this terminator.
Orders are submitted with one node count over one delivery window, so
allocation_schedule_delta normally contains one segment. filled_allocation_schedule_delta
describes the portion that has executed so far and may contain multiple segments when different
parts of the order fill over different intervals. Subtract the filled node count from the
requested or offered node count at each instant to get the capacity that remains on the book.
For a buy, every filled segment adds to the destination pool’s allocation schedule; for a sell, it
removes that segment. An orderbook fill reports the exact schedule segment that traded. To
calculate the compute represented by a schedule, sum node_count × duration_hours across its
entries.
API examples
These worked examples use the/v2 order endpoints; see the
Orders API reference for the full request and response
schemas. Timestamps are Unix epoch seconds, and prices are strings in dollars per node-hour.
Create a buy order with POST /v2/orders. The request body includes the following fields.
sideisbuyorsell.poolaccepts a pool ID or resource path.skutakes a SKU ID.allocation_schedule_deltais a single time range.
pending state; poll GET /v2/orders/{id} for the resolved
state. The trailing zero entry marks the end of the schedule.
side set to sell, and its response has the same shape.
GET /v2/orders/{id}. Once filled, state is filled, filled_at is set,
and filled_allocation_schedule_delta covers the filled portion. fills lists each execution with
the price actually paid (here below the buy’s limit).
GET /v2/orders. Each entry in data is a full order object; pass the returned
cursor as starting_after to page forward.
POST /v2/orders/{id}/cancel, which returns 204 No Content.