Your API's integer survived Python. JavaScript changed it
A valid JSON number is not a portable precision guarantee. Protect identifiers and decimal amounts with explicit wire contracts and cross-language tests.

An API returns 9007199254740993 as a JSON number. Python's standard JSON decoder can preserve that integer exactly. JavaScript's Number cannot. The request succeeds in both languages, but the JavaScript client now holds a different identifier.
Both clients may appear to have parsed a valid response. The difference only becomes visible when the identifier is compared, stored or sent back to the server. This is a wire-contract problem that type declarations alone cannot repair after precision has already been lost.
Know the receiving type
JavaScript's Number.MAX_SAFE_INTEGER is 9007199254740991, or 2^53 minus one. Above the safe-integer range, Number cannot distinguish every adjacent integer.
JSON's number syntax does not promise identical numeric precision across implementations. A schema declaring an integer describes the intended value, but consumers still need a representation that preserves the values the server actually sends.
For opaque identifiers, a documented string representation can preserve the exact value across languages. An identifier is normally compared and passed around rather than used in arithmetic. Preserve its exact spelling, including leading zeros when they are significant. Changing an existing numeric field to a string is a contract change that needs compatibility planning.
BigInt needs a serialization policy
JavaScript BigInt can represent large integers, but it does not automatically solve an already-rounded parse. Converting an inaccurate Number to BigInt preserves the inaccurate value.
MDN's BigInt reference also documents that JSON.stringify does not serialize BigInt by default. Document a wire representation and test its conversion in both directions.
If an API must retain a numeric wire format outside the safe range, use a parsing approach that preserves the original numeric value before conversion, and document its requirements for consumers. A string contract is often simpler when the field is truly an opaque identifier.
Decimal amounts are a related, separate problem
A monetary amount needs both a numeric representation and a unit. Integer minor units can work when the API documents the currency and scale. Decimal strings can work when precision and rounding rules are explicit. Do not assume every currency or financial quantity uses two decimal places.
Python's Decimal documentation explains why constructing Decimal from a decimal string differs from constructing it from an already approximated binary float. The standard JSON decoder does not automatically turn fractional numbers into Decimal unless configured to do so.
Once parsing rounds a value, converting it to an exact type cannot recover the lost digits.
Test the wire round trip
Build fixtures around representation boundaries: zero, negative values where permitted, the JavaScript safe-integer limit, values immediately beyond it, and long decimal strings. Assert the exact value after decode, encode and a subsequent request.
Run those fixtures in each supported SDK language. Include database and logging paths if those systems transform values during normal application use. Avoid comparisons that convert both sides to the same lossy type and accidentally hide the defect.



