Skip to main content
A fill is one trade between one of your orders and another participant’s order. Every fill on your account appears in two places:
Build fill processing on /executions. The execution sequence is the durable record of new fills on your account. Use /fills to browse history or to backfill fills from before sequencing began. Do not build exactly-once processing on /fills.
Fills from a placement, whether it matched immediately or later while resting, are on /executions by the time D1 responds to the request that caused them. The placement response shows the order’s state but not its fills, so take fills from the feed.

GET /mm/v1/executions

string
default:"0"
Return executions with executionSequence greater than this value. 0 (or leaving it out) starts from the beginning. Must be a plain non-negative integer: no sign, leading zeros, decimals or exponent, and no larger than 9007199254740991.
integer
default:"100"
1–100.
No other parameters are accepted.

Execution fields

Every field except executionSequence is exactly the same as the matching /fills record. The response never includes your counterparty’s account, order or sequence.

Sync semantics

  • Strictly ascending. Every execution on a page has executionSequence > after, in ascending order.
  • No gaps, no repeats, no late arrivals. D1 assigns sequence numbers one after another, in the same transaction that creates the fill. A new fill always gets a higher number than every fill you can already see, so a lower number never shows up after you have read a higher one.
  • nextAfter is the checkpoint to send as after next time: the last sequence on the page, or your after unchanged if the page is empty. It never goes backwards.
  • hasMore: true means more executions are ready now, so request again straight away. hasMore: false means you are caught up, so poll again later.
  • One stream per account. Sequences are specific to your account. Both of your active API keys read the same stream.
  • Reads are safe to retry. Reading the feed changes nothing. Repeating a request with the same after returns the same executions, plus any new ones if the earlier page was not full.

Checkpointing and reconnects

Your checkpoint is the last executionSequence you have fully processed and stored durably. It is the only state you need to resume.
Rules:
  1. Process in order. Apply executions in ascending executionSequence.
  2. Persist nextAfter only after the whole page has been processed. If processing fails partway through, do not advance the checkpoint. Retry from the last durable value.
  3. Be idempotent on fillId. If your process crashes after applying executions but before saving the checkpoint, you will receive those executions again on restart. Ignore any fillId you have already applied. A good approach is to store the checkpoint in the same transaction as the fills it covers.
  4. On errors, keep the checkpoint. Never skip ahead.
    • 429: wait the Retry-After seconds, then retry the same after.
    • 500: back off and retry the same after.
    • 401 / 403: stop and alert. Retrying will not fix a revoked key, a suspended account or a missing scope. See Errors.
Never set the checkpoint from serverTimeMs, createdAtMs, or the highest sequence you have seen. Use only the nextAfter of a page you have finished processing.

Reference consumer loop

Older fills without a sequence

Fills created before D1 started numbering executions have no executionSequence and will never get one. /executions starts at your first numbered fill, so it is complete only from that point on. If your account traded before then, load those earlier fills once from /fills, then use /executions for everything after.

Fills (history and backfill)

GET /mm/v1/fills: fill history, newest first.
integer
default:"50"
1–100.
string
nextCursor from the previous page. See Pagination.
Returns { fills, nextCursor, limit, serverTimeMs }. Each fill has the same fields as an execution, except executionSequence: fillId, orderId, instrumentId, role, side, price, quantity, premium, executionIndex and createdAtMs. Fills are sorted by creation time, which is not the order in which they were committed. A fill can therefore appear behind one you have already paged past. That is fine for browsing history, but it is why live sync should use /executions.