POST /v1/price

Quote a swap. Server-computed pricing with optional partner markup.

POST/api/v1/priceAuth optional

Server-computed quote for a pair and amount. The same pricing path powers /v1/create, so a quote followed by a create will not surprise you with a different rate (modulo natural market movement during the round-trip).

Signed callers receive a partner-specific rate; markupBps in the response echoes the applied basis points. Unsigned callers see the base rate (markupBps = 0). Resolution order, highest wins: request body afftax> per-code default > partner default.

Request

Body
type"float"required
Quote mode. Currently "float" only. The rate is recomputed server-side at order creation against the live feed.
fromCcystringrequired
Source asset id (e.g. "btc"). Must be active and part of an active pair.
toCcystringrequired
Destination asset id (e.g. "usdt_trc20").
direction"from" | "to"required
Which side of the trade amount refers to. "from" quotes the receive amount for a given deposit; "to" quotes the deposit required for a given receive amount.
amountstring | numberrequired
Decimal amount, interpreted in the asset selected by `direction`. Strings are preferred for precision safety.
afftaxinteger
Optional partner markup in basis points (0..2000 = 0–20%). If omitted, the per-code default applies when an X-API-KEY: prefix.code segment is present and matches an enabled, partner-owned code; otherwise the partner’s default. Values outside the range return code 1 INVALID_REQUEST. Never silently clamped.

Response

200 OK
{
  "code": 0,
  "msg": "",
  "data": {
    "from": {
      "code": "btc",
      "coin": "BTC",
      "network": "Bitcoin",
      "amount": "0.01000000",
      "rate": "62450.12345678",
      "precision": 8,
      "min": "0.00002000",
      "max": "0.08000000",
      "usd": "624.50",
      "btc": "0"
    },
    "to": {
      "code": "usdt_trc20",
      "coin": "USDT",
      "network": "Tron",
      "amount": "619.987654",
      "rate": "62450.12345678",
      "precision": 6,
      "min": "1.000000",
      "max": "5000.000000",
      "usd": "619.99"
    },
    "errors": [],
    "markupBps": 50
  }
}
Fields
data.from.code / coin / networkstring
Source asset descriptor: id, symbol, network.
data.from.amountstring (decimal)
Required deposit amount. When direction = "from" this echoes your input; when direction = "to" it is derived.
data.from.ratestring (decimal)
Effective rate from -> to after applying the base service-fee margin and any afftax markup. Same value as data.to.rate.
data.from.precisionnumber
Source asset decimal precision.
data.from.min / maxstring (decimal)
Per-asset deposit window in source-asset units, derived from the per-pair USD floor and ceiling against the current USD price.
data.from.usdstring (decimal, 2 dp)
USD value of the deposit at the current rate.
data.from.btcstring
Reserved field; always "0".
data.to.code / coin / networkstring
Destination asset descriptor.
data.to.amountstring (decimal)
Amount the recipient receives, after the rate and network fee. "0" when the quote produced a non-positive amount.
data.to.rate / precision / min / max / usdstring / number
Mirrors data.from. The shared `rate` field is repeated for partner-side convenience; min/max are in destination-asset units.
data.errorsarray<string>
Reserved. Always empty in the current contract.
data.markupBpsnumber
Applied afftax in basis points. 0 for anonymous calls; the resolved (explicit > code > partner-default) value otherwise.

Errors

codemsgHTTPDescription
1INVALID_REQUEST400Body fails validation: unsupported asset, disabled pair, unparseable amount, invalid address, FLOAT without refundAddress, malformed Idempotency-Key. The same code + HTTP 409 fires on Idempotency-Key reuse with a different payload.
3AUTH_INVALID401Unknown key, malformed signature, signature mismatch, expired or replayed nonce, decrypt failure. Generic body — never an oracle for "which" of those it was.
5RATE_LIMIT429Per-partner weight budget exhausted within the 60-second sliding window. Response includes Retry-After: <seconds>.
11UPSTREAM_ERROR503A required upstream is temporarily unavailable. Retry with exponential backoff.
99INTERNAL500Unexpected server-side condition. Already logged on our side; safe to retry.

Code examples

# Request a quote for 0.01 BTC -> USDT (Tron) with a 0.5% partner markup.
APIKEY="rWqZ...your-api-key...Rg"
APISECRET="G1JV...your-api-secret...n4"
NONCE=$(openssl rand -hex 16)
BODY='{"type":"float","fromCcy":"btc","toCcy":"usdt_trc20","direction":"from","amount":"0.01","afftax":50}'
SIGN=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$APISECRET" | sed 's/^.* //')

curl -sS -X POST "https://0trace.io/api/v1/price" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $APIKEY" \
  -H "X-API-SIGN: $SIGN" \
  -H "X-API-NONCE: $NONCE" \
  --data "$BODY"

Rate limit

Weight 1 per call. Unsigned calls bypass the per-partner bucket; signed calls are charged 1 weight unit each.

Notes

Quote freshness. No response cache on this endpoint. Every call recomputes the quote against the latest rate-feed snapshot. Anonymous callers (no X-API-KEY) share an IP rate-limit bucket of 60 calls per minute per /24 (IPv6: /48); signed callers run on the per-partner weight budget instead.

Quote vs create amounts. amounton a subsequent create call is a hint. The create path re-quotes server-side, so the order’s final amount is authoritative.

Partner API.
Same engine as 0trace.

A private partner integration surface. Signed quotes, server-side pricing, webhook delivery, multiple reference codes, and a self-serve cabinet — all backed by the production exchange engine.

Support

Questions? Answers.

Get the latest updates

Follow us on X

The 0trace team will never ask for KYC or AML. We retain no logs, metadata, or tracking cookies.

Learn more