The Money shape
Every monetary amount on the public API uses one shape:
The same shape is used in request bodies, response bodies, and webhook payloads. There is no second representation (no base units, no integer minor units, no separate
assetAmount envelope).
Amount as a string
Amounts are always JSON strings, never numbers. JavaScript and most JSON parsers lose precision on values like0.1 + 0.2; representing money as Number is unsafe for any asset with more than 15 significant digits (e.g. 1.000000000000000001 ETH cannot round-trip through a JS number).
Strings sidestep this entirely. Use a decimal library (BigNumber.js, decimal.js, Python Decimal, Go shopspring/decimal) to do arithmetic.
Input precision
Requests accept up to the asset’s precision. Padding with trailing zeros is optional.
Inputs with more fractional digits than the asset allows are rejected at request validation:
- Leading sign (
"+1","-1") - Leading zero on the integer part (
"01.00") - Scientific notation (
"1e6") - Trailing dot with no fractional digits (
"1.")
Output precision
Responses and webhook payloads always emit amounts at the asset’s exact precision (canonical exact-scale form). The amount you sent as"1" USD will come back as "1.00". The amount you sent as "1.5" USDC will come back as "1.500000".
This means: echo what we send you, do not parse-and-rebuild. If you store the response amount in a database, store the string as-is; round-tripping through Number or a non-decimal type will silently corrupt the precision.
Idempotency and amount
Idempotency-Key fingerprints canonicalise the amount before hashing. A replay withamount: "1" against an original amount: "1.00" for USD will return the original response, not an IDEMPOTENCY_KEY_CONFLICT.
Why not base units
A common alternative is to send amounts as integer base units (e.g.100000000 for 1 BTC). Conduit does not do this on the public surface for two reasons:
- Asymmetry. Fiat and crypto amounts would have to agree on a representation. Sending
100000000for both1 BTCand1,000,000 USDis error-prone. - No precision context at the call site. Integrators have to look up the asset’s decimal places to know whether
1000is0.001 ETHor1000 USDC. Decimal strings carry the precision visually.