An exchange order ID identifies an order, while a trade or fill ID identifies an individual execution under the endpoint's rules. One order can produce several fills. Keep their relationship and documented uniqueness scope so that repeated observations do not become extra trades and separate fills do not collapse into one record.
The practical question is what to use as a ledger key when an order fills in pieces and the same execution appears in more than one response. A field called id is not enough information. Its meaning comes from the endpoint and record type.
Separate the instruction from its executions
An order is an instruction with a lifecycle. An execution records some quantity actually traded. An accepted order can have no executions yet; a canceled order can retain earlier executions. The partial-fill inventory guide covers the exposure and remainder decisions that follow.
Bybit explicitly documents multiple executions for one order. Its execution-history response separates orderId, the user-supplied orderLinkId, and execId, with execution quantity, price and fee fields. These belong to different levels of the record. Bybit V5 execution-history documentation.
| Identity | What it answers | Why it cannot replace a fill key |
|---|---|---|
| Local trading-intent ID | Which approved action led to this work? | One intent may require several orders. |
| Client order ID | Which client-labeled order should be located? | Its uniqueness and reuse rules depend on the venue. |
| Exchange order ID | Which exchange instruction owns these fills? | Several fills may share it. |
| Trade or fill ID | Which individual execution is represented? | It still needs the provider's required namespace. |
| Request or message ID | Which request or delivered message is this? | A message can contain several executions. |
Submission identity is addressed in the trading-idempotency guide. Deduplicating fills after execution cannot prevent a separate duplicate order from being submitted.
Read field names within the exact schema
Binance Spot's authenticated account trade list returns both id and orderId, alongside symbol, quantity, quote quantity and commission information. The endpoint is scoped to a specific account and symbol; querying by order ID also requires the symbol. Record that context with the result. Binance Spot account trade list.
The private stream uses different names. Its execution-report schema distinguishes lowercase i for order identity, t for trade identity and uppercase I for execution identity. It also separates last executed quantity from cumulative filled quantity. Do not map every identifier containing “execution” into the same normalized fill-ID column. Binance Spot execution-report schema.
That distinction matters for order updates without a trade. The schema illustrates a trade-ID value of -1; a parser must recognize the event's semantics and sentinel values rather than storing every order report as a fill. Preserve the original fields even after creating a normalized record, so the mapping remains inspectable.
Bybit's private execution stream makes another boundary explicit: its outer id identifies the message, while items inside data have their own execId and orderId. Multiple executions for one order can arrive in one message. Deduplicating the inner array by order ID would discard legitimate executions. Bybit private execution-stream schema.
Four fill observations, three actual fills
Consider a hypothetical spot buy for 12 ABC at a limit of 10 USDT per ABC. The invented order ID is O700. Fees are excluded to isolate identity accounting. The table is a teaching fixture, not a reproduction of either exchange's payload.
| Observation | Order ID | Fill ID | ABC filled | Price in USDT | New ABC recorded |
|---|---|---|---|---|---|
| First execution | O700 | F201 | 2 | 9.90 | 2 |
| Second execution | O700 | F202 | 3 | 10.00 | 3 |
| Repeated observation of second execution | O700 | F202 | 3 | 10.00 | 0 |
| Third execution | O700 | F203 | 5 | 10.00 | 5 |
| Final cancellation report | O700 | No new fill | 0 | — | 0 |
There is one order and three distinct fills. Gross acquired quantity is 2 + 3 + 5 = 10 ABC. Quote cost is 2 × 9.90 + 3 × 10 + 5 × 10 = 99.80 USDT. The gross weighted average is 99.80 ÷ 10 = 9.98 USDT/ABC. The confirmed cancellation leaves two requested ABC unfilled.
Counting every fill observation produces 13 ABC and 129.80 USDT, overstating both by the repeated three-unit fill. Keeping only the first row for O700 produces two ABC, losing eight legitimate units. A final “canceled” label does not make the ten filled units disappear.
Store cumulative order quantities separately as reconciliation evidence. Do not add a final cumulative ten ABC to the ten ABC already represented by individual fills. If those totals disagree, the disagreement needs investigation rather than a fabricated balancing execution.
Define the namespace before defining uniqueness
A conservative local fill namespace can include venue, production or test environment, stable account or subaccount identity, product category, instrument and the documented fill identifier. This is a design worksheet, not a claim that every exchange reuses identifiers across those dimensions or guarantees this exact tuple.
For each adapter, write down what the provider actually guarantees. If its execution identity requires additional scope, include it. If the documentation does not settle uniqueness, retain the raw observations and verify the contract before allowing an uncertain match to suppress accounting.
| Namespace check | Mistake it prevents |
|---|---|
| Stable account identity | Treating the same raw ID in two accounts as one execution |
| Environment and product | Merging a test record with a production record or another market type |
| Instrument where required | Assuming a numeric identifier is globally unique |
| Correct provider fill field | Using an order, message or sequence ID in its place |
| Parent-order association | Losing which instruction produced the execution |
Use the account identity rather than the API-key string as an accounting boundary. Rotating a credential should not create a second history of the same account. Subaccount isolation explains why account scope also matters when attributing exposure.
Store IDs without lossy numeric conversion; preserve case and significant characters. The API decimal-precision guide covers the related parsing problem. Do not assume an identifier is safe in an ordinary floating-point number merely because it contains digits.
A repeated key can reveal a conflict
When an existing scoped fill identity returns with matching economic fields, retain the new observation's source and retrieval time without adding its quantity again. When price, quantity, parent order or fee information disagrees, preserve both versions and flag the conflict. Investigate the venue's correction rules or incomplete fields before deciding which representation is authoritative.
Do not solve a parent-order conflict by quietly changing the uniqueness key until both rows fit. Nor should two executions with identical timestamp, price and quantity be merged merely because they look alike: different fill IDs may represent legitimate separate executions.
Event order is a related problem with different evidence. The order-event ordering guide addresses late status updates and cumulative truth. The bulk-order partial-success guide addresses which submitted items were accepted; a batch acknowledgement is not a fill ledger.
Verify identity without claiming complete history
Replay F202, deliver all three fills inside one message, and import a separate account's record with the same raw identifier. The expected result is unchanged O700 accounting, three distinct O700 fills and a separate record for the other account. Change F202's quantity under the same scoped identity: the expected result is a visible conflict, not an extra purchase or a silent overwrite.
These checks establish identity handling for the fixture. They do not prove that every historical execution was retrieved. Use the separate API pagination guide to document retrieval coverage, windows and continuation rules. Correctly deduplicating the records you possess cannot reveal a fill that never reached the ledger.
Editorial method: Prepared with AI assistance from official exchange documentation reviewed on 23 October 2026. The ledger and namespace worksheet are original hypothetical examples. No live-account reconciliation or KLINEO adapter test was performed; the cited venue schemas do not establish product feature support.
