Skip to content

Connection security

Exchange API fields: missing, null and zero

Missing properties, explicit nulls and valid zero values need different handling. Trace each state from exchange response to storage and decision.

Three ivory plinths hold an empty recess, a frosted glass block and a ceramic ring with a lime accent.
Illustration for connection security; examples in this article are educational.

Exchange API missing, null and zero fields are different observations. A missing field was not sent, null is an explicitly supplied JSON marker, and zero is a supplied value. Preserve those distinctions until the endpoint contract explains their meaning. Converting all three to zero can manufacture a balance, erase a valid identifier or invent a fill price.

The practical rule is to check presence first, validate the supplied type second, and interpret the value for that exact field third. A successfully parsed response can still leave a decision unresolved.

A field can be absent without being zero

JSON has a null value, but no separate “missing” value inside an object. Absence describes the object lacking a property. The JSON Schema null reference explicitly distinguishes null from absence, numeric zero, false and an empty string.

Here are illustrative fragments for a fictional cumulative quantity field. They are not a venue's response schema.

Raw observationWhat the transport establishesWhat still needs a contract
{}filledQty was omittedOptional response shape, partial update or missing required data?
{"filledQty": null}The property exists with JSON nullUnavailable, inapplicable, intentionally cleared or invalid?
{"filledQty": "0"}A string containing zero was suppliedIs this a permitted decimal string and a valid zero quantity?
{"filledQty": 0}Numeric zero was suppliedDoes this endpoint allow a number instead of a string?
{"filledQty": ""}An empty string was suppliedDocumented sentinel or invalid numeric input?

Zero is not automatically valid just because it parses. A cumulative executed quantity may legitimately be zero before any fill; a new order's requested quantity may require a positive amount. Similarly, null does not universally mean “unknown.” Its business meaning comes from the endpoint, product, account mode and field definition.

Keep optionality and nullability separate in the schema. An optional string may be omitted while rejecting null when present. A required nullable field must exist but may contain null. JSON Schema's required-property rules make this distinction explicit: listing a property under properties alone does not require its presence.

Conditional exchange fields are evidence, not noise

Binance Spot documents order-response fields that appear only under specified conditions. For example, icebergQty depends on that parameter having been sent, while preventedMatchId appears when an order expires through self-trade prevention. The documentation uses numeric zero as an example preventedMatchId. A presence check must therefore retain the example identifier instead of dropping it because zero is false in a truthiness test. These are Binance-specific rules from its conditional order-response field table.

An expected omission is different from a missing field that the relevant response promises. Compare the request, order type and returned response shape before declaring an integration broken. The ACK, RESULT and FULL response guide explains why a placement acknowledgement can contain less detail than another order response. Lack of fill fields alone does not establish zero execution.

Other venues use additional representations. Bybit's V5 Get Open & Closed Orders field table for GET /v5/order/realtime defines avgPrice as a string and documents an empty string when no average price exists. It also says Spot orders do not have the createType key. Those cases require different mappings within the same Bybit order-query response. The page's response example nevertheless shows avgPrice as "0" alongside zero cumulative fills. Preserve that documentation discrepancy and confirm the exact product's handling; neither representation establishes an executed price when filled quantity is zero.

For that documented avgPrice case, turning the empty string into a price of zero would change “no average price supplied” into a numerical observation. Do not import that mapping into another venue's average-price field without checking its definition.

Preserve the observation before parsing its value

A useful adapter has two stages. First, retain what arrived. Second, apply the endpoint's field rules. For a validated JSON object, classify each field in this order:

  • If Object.hasOwn(object, key) is false, record the state as missing.
  • Otherwise, if object[key] === null, record the state as null.
  • Otherwise, record the state as value and retain object[key] unchanged as the raw value.

This classification intentionally retains 0, "0", false and "" as supplied values. It does not claim they are all valid quantities. A field-specific validator must check the expected type, allowed grammar, range, unit and documented sentinel before producing a usable domain value.

Avoid a generic value || fallback default. In JavaScript it replaces numeric zero, false and the empty string, as well as null and undefined. If the fallback is zero, missing and null become indistinguishable from a supplied zero. The string "0" behaves differently because it is truthy. Nullish coalescing, value ?? 0, preserves numeric zero but still collapses null and a missing property read to the same default.

Conversion can erase distinctions too: JavaScript's Number(null) and Number("") both produce zero. Validate before conversion. For decimal-string amounts, preserve their original text through this classification; the API decimal-precision guide covers the separate arithmetic boundary.

An internal representation can carry a presence state, raw value, interpreted status and reason. Add the endpoint, product and observation time. For example, state=value, raw="", status=unavailable, reason=no_average_price can describe a documented empty-string sentinel without pretending the venue literally sent JSON null.

Worked example: zero fills do not imply a zero fill price

Consider a hypothetical order for ten base units. Its fictional summary contract accepts decimal strings for cumulative filled quantity and quote value. Quote value means execution notional before fees. Null means the particular measurement is unavailable in that observation. Omission means that observation supplies no measurement for the field. These definitions are illustrative, rather than Binance or Bybit wire-format claims.

For this example, an average execution price can be calculated only when both measurements are known and filled quantity is positive:

Average fill price = cumulative quote value / cumulative filled quantity

ObservationFilled quantityQuote valueDefensible result
Initial response omits both fieldsMissingMissingExecution quantity and average remain unestablished
Fresh summary before any execution"0""0"Known zero fills; average is undefined because division would be 0/0
Fresh summary after a partial fill"2""198"Two units filled; average is 99 quote units per base unit
Later observation supplies null for bothNullNullCurrent measurements are unavailable; do not replace them with zero

The partial-fill calculation is 198 / 2 = 99. The unfilled quantity at that confirmed point is 10 − 2 = 8 base units. These synthetic numbers demonstrate field handling, not trading performance.

The last row does not undo the confirmed fill. Keep the earlier two-unit observation in history with its timestamp, while marking the new measurement unavailable. Showing the last known average of 99 is possible if the interface labels its age; silently presenting it as a fresh observation would conceal the information gap.

Likewise, the initial omission cannot justify submitting a replacement ten-unit order. That decision needs authoritative order and execution state. A parser default supplies no evidence that the earlier instruction left nothing filled or open.

Carry the distinction through storage and display

Preserving states in the API client is insufficient if the next layer deletes them. A database column containing only a nullable number may merge “not included in this message” with “explicitly returned null.” Preserve a state or provenance field when those cases lead to different decisions. Check the SDK, serializer, queue and cache as well as the first decoder.

Define update semantics separately. In a sparse update, omission might leave a previous observation untouched; in a complete snapshot, a required omission might invalidate that record. An explicit null might clear a field or signal unavailability. Neither rule follows from JSON alone. Apply only the behavior documented for that message contract.

Use distinct display language where it matters: “0 filled,” “average unavailable” and “not supplied in this response” convey different information. Do not add zero-valued observations to an accounting series just to make a chart continuous. A confirmed zero balance also answers a different question from an unavailable balance read; the available-versus-total balance guide explains the scope needed before either amount supports sizing.

Validate the decision, not just the parser

For each field used by an automated decision, document four things: when it must appear, whether null is permitted, which values are valid, and what action remains possible when it is unavailable. An optional descriptive label may leave an order view usable. Missing quantity evidence can block sizing or reconciliation that depends on that quantity.

Build fixtures around the actual boundary:

FixtureValidation outcome to require
Expected conditional field omittedAccept the documented shape without inventing a value
Required measurement omittedFlag the missing evidence and stop dependent calculation
Explicit nullApply that field's nullable contract; retain the marker
Valid zero in the documented typePreserve zero and allow only its documented meaning
Empty string or wrong typeRecognize a documented sentinel or report invalid input
Previously known value followed by missing or nullPreserve history and apply explicit freshness/update rules

Run these fixtures through persistence and output, then inspect the resulting decision. A test that merely confirms JSON parsing cannot catch a fabricated zero introduced later. Keep the fixtures with the exchange API contract tests, so a changed response can be checked against the assumptions it affects.

Start with one cumulative quantity, one conditional identifier and one unavailable-price field in your integration. Trace each from raw response to stored record to displayed value and decision. The repair is complete when absence, explicit null and valid zero retain their distinct evidence, and each decision follows the field's documented meaning.

Keep the context with the example.

Each worked example is illustrative, with its sources and assumptions in the article. Read our editorial standards for authorship, verification and corrections.