Errors cookbook

Per-code real-world remedies: symptom, cause, remedy for every numeric code in the envelope.

Every numeric code maps to a finite set of remedies. Use this when something is failing in integration testing or production. Reference table: Errors.

code: 1 — INVALID_REQUEST

Symptom

HTTP 400. Some endpoints also return HTTP 409 when an Idempotency-Key is reused with a different payload.

Common causes

  • The asset code (fromCcy / toCcy) is misspelled or disabled.
  • direction is not one of "from" / "to".
  • amount parses to zero or a negative number.
  • toAddress does not validate against the destination asset’s network.
  • type = "float" without refundAddress.
  • Idempotency-Key shorter than 8 chars or longer than 128.
  • Idempotency-Key reused with a different body (HTTP 409).

Remedy

Inspect the request body. There are no hidden hints; the wire body is exactly { "code": 1, "msg": "INVALID_REQUEST" }. If your logs show one cause repeatedly, add a pre-flight validation step before the POST.

code: 2 — AUTH_REQUIRED

Symptom

HTTP 401 on an endpoint that requires authentication.

Cause

You forgot to set X-API-KEY or X-API-SIGN.

Remedy

Check that your HTTP client sends all three headers: X-API-KEY, X-API-SIGN, X-API-NONCE. The third is the one most integrations forget. A missing X-API-NONCE collapses to code: 3 AUTH_INVALID, not code: 2. Those are different failure modes.

code: 3 — AUTH_INVALID

Symptom

HTTP 401, possibly on a request that looks fine at first glance.

Common causes (uniform on the wire, indistinguishable)

  • Unknown apiKey.
  • Bad HMAC: signature computed over a different byte stream than the body you sent (re-serialised, sorted keys, whitespace difference, or echo appending a trailing newline).
  • apiSecret wrong, typo, or from a different partner.
  • X-API-NONCE empty, shorter than 16, longer than 64, or already used in the last 5 minutes.

Remedy

  1. Print apiKey and the body bytes you signed; print the body bytes the HTTP client actually sent (after middleware). They must match byte-for-byte. The most common bug is middleware that pretty-prints JSON after the signature step.
  2. Use printf '%s' "$BODY" and --data "$BODY", never echo and --data-raw. echo appends a newline.
  3. Generate a fresh nonce on every request. Never reuse across retries.

code: 4 — AUTH_DISABLED

Symptom

HTTP 401, but the signature was valid (you can prove this because the same nonce + signature on a different second still returns AUTH_DISABLED, not AUTH_INVALID).

Cause

The operator has flipped enabled = false on your partner record. Reasons: planned maintenance, credential revocation, or a billing pause.

Remedy

Contact your operator. There is no API path to recover.

code: 5 — RATE_LIMIT

Symptom

HTTP 429 with a Retry-After: <seconds> header.

Cause

Your per-partner weight budget (default 2500 wu/min) is exhausted within the rolling 60-second window. POST /api/v1/create weighs 50, POST /api/v1/qr weighs 5, every other endpoint weighs 1.

Remedy

  • Sleep for Retry-After seconds (no less) before the next request.
  • For burst traffic, queue server-side and drain at ≤ budget/60 calls per second.
  • For sustained growth, send projected per-endpoint call rates to your operator and request a budget raise.

code: 6 — NOT_FOUND

Symptom

HTTP 404 on /api/v1/order, /api/v1/qr, or /api/v1/emergency.

Causes (collapsed into one envelope, no oracle)

  • The id does not exist.
  • The id belongs to another partner.
  • The token does not match the stored hash.
  • The order was soft-deleted by the user.

Remedy

Re-verify that id and token come from a successful /api/v1/create on this same partner record. If they do, the order was soft-deleted by the end user. Your aggregate counters remain accurate, but the underlying row is no longer queryable.

code: 7 — LIMIT_MIN

Symptom

HTTP 400 on /api/v1/create.

Cause

Your amount is below the per-pair USD minimum (default $30).

Remedy

Quote /api/v1/price first and respect the from.min and to.min fields in the response. /api/v1/price returns these bounds for pre-validation but does not reject out-of-range amounts. Only /api/v1/create enforces the gate.

code: 8 — LIMIT_MAX

Symptom

HTTP 400 on /api/v1/create.

Cause

Either the per-pair USD maximum is exceeded (default $5,000), or the daily payout cap on the operator side is exhausted.

Remedy

Lower the amount, split into multiple orders, or contact the operator for a higher per-order cap (operator-mediated).

code: 9 — RESERVE_EXCEEDED

Reserved for a future per-partner capacity control. No current route emits this code. Safe to omit from exhaustive switch statements until announced.

code: 10 — MAINTENANCE

Symptom

HTTP 503.

Cause

The site is in operator-toggled upgrade mode (rare).

Remedy

Retry with exponential backoff capped at 60 seconds. The window is usually short (< 5 min).

code: 11 — UPSTREAM_ERROR

Symptom

HTTP 503.

Cause

A required upstream is temporarily unavailable.

Remedy

Retry with exponential backoff: 1 s, 2 s, 5 s, 10 s, then bail and surface a partner-facing error.

code: 12 — EMERGENCY_INVALID_CHOICE

Symptom

HTTP 400 on /api/v1/emergency.

Cause

The choice field is not exactly "EXCHANGE" (case-sensitive).

Remedy

Send { "choice": "EXCHANGE" }. The "REFUND" choice is not exposed on the public surface — refunds are operator-mediated.

code: 13 — LIMIT_EXCEEDED

Symptom

HTTP 403 on POST /api/v1/codes.

Cause

Your partner record has already reached the per-partner cap on reference codes (default 50).

Remedy

Delete (soft-disable) unused codes via DELETE /api/v1/codes, or ask the operator to raise the cap.

code: 99 — INTERNAL

Symptom

HTTP 500.

Cause

Unexpected server-side condition. Already logged on our side; if it recurs, share the timestamp and the request body shape with your operator contact.

Remedy

Safe to retry once with the same Idempotency-Key for /api/v1/create. For other endpoints, retry with a fresh nonce.

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.

Need help?

Questions? Answers.

A partner integration surface on top of the same exchange engine that powers 0trace.io. You connect with a signed REST contract, query quotes, open orders, and receive webhook notifications. Our liquidity, our pricing, our payouts. You focus on your product.
No. The API is private and invite-only, aligned with the privacy posture of 0trace itself. There is no KYC, no identity collection, and no source-of-funds reporting required of partners or their end users.
Submit a request through our partner application form at 0trace.io/api/contact-sales and we’ll reply within three business days.
Traffic is encrypted in transit (TLS). Every request is signed with HMAC-SHA256 over the exact request body bytes and gated by a nonce-based replay window. Pricing, fees, and payout amounts are computed server-side. Payouts run on an isolated service that re-verifies each transfer against the on-chain deposit before broadcasting.
A per-partner sliding-window weight budget, default 2500 wu/min (≈50 creates/minute). Endpoint weights: /api/v1/create is 50, /api/v1/qr is 5, every other endpoint is 1. XML feeds run on a separate public bucket. Exceeding the budget returns 429 with a Retry-After header. To raise your cap, send your projected per-endpoint call rate to your operator contact.
Two ways to earn. Revenue share: send us traffic with your referral link and earn a share of our service fee on every order — the visitor sees our live rate. Markup: integrate through the API and add your own margin on top of our rate, shown in your own interface. Use either, or both.
Yes. 0trace operates its own liquidity pool across every supported asset and network. Quotes are recomputed server-side at order creation against the live feed. Payouts are direct, with no third-party intermediary.
Bitcoin, Ethereum, BSC, Solana, Tron, Monero, and Arbitrum One — covering native coins plus the major stablecoins on each network (USDT, USDC, USDC.e).
Yes. We push signed events for order.status_changed and partner.paid_out; you subscribe to the ones you want in your cabinet.

Follow us on X for the latest updates.

Subscribe