The error format
Every refusal is an HTTP status and a JSON body like this:- Branch on
detail.code, never onmessage. Codes are stable; messages are for people and may change. - Some codes add fields to
detail, listed in the table below:reason,order_id,orderorerrors. - Some answers carry a
Retry-Afterheader: the number of seconds to wait before retrying. - If you meet a code that is not listed here, handle it by its HTTP status: retry
429and503later with the sameIdempotency-Key, and treat other4xxas a refusal.
Rate limits
These are the defaults; Bullionwale’s limits may differ. Over a budget, the answer is
429 with a Retry-After header:
rate_limited: the key’s budget or, for production orders, the account’s budget is used up.auth_throttled: too many failed authentications came from your address. Until it cools down, calls from that address are refused even with a good key, so fix a misconfigured key before it locks out your other systems.
Retry-After seconds, then retry. For an order, retry with the same Idempotency-Key.
If order rate limiting is temporarily unavailable, orders are refused with 503 rate_limiter_unavailable and Retry-After, and no order is placed. Reads keep working.
Error codes
“Env.” says where a code can occur: both environments, or prod (production only).Troubleshooting
Every call answers 404, with no code in the body
Every call answers 404, with no code in the body
Check the host and the path: the API is served at
https://api.bullionwale.com under /api/trading/test/v1 and /api/trading/v1. A 404 that carries a detail.code (order_not_found, unknown_symbol) is a normal refusal.401 wrong_environment
401 wrong_environment
A
bwk_test. key works only under /api/trading/test/v1, and a bwk_live. key only under /api/trading/v1. Check both the base path and the key your program loaded.401 on a key that worked yesterday
401 on a key that worked yesterday
The code says why:
credential_rotated (use the new key), credential_expired (ask for a rotation) or credential_revoked (ask for a new key). See Rotation, expiry and revocation.429 auth_throttled, even with a good key
429 auth_throttled, even with a good key
Something on your network is sending a bad key repeatedly. Calls from that address are refused until the throttle cools down. Find and fix the misconfigured system, then wait
Retry-After.403 production_trading_disabled
403 production_trading_disabled
Production trading is not available to your account right now. Check
production_trading_available from GET /me, and see When production orders are refused.A POST /orders timed out
A POST /orders timed out
Do not send a new order. Retry with the same
Idempotency-Key and body, or look the order up first. See Recovering an order.400 limit_exceeded although I have no open orders
400 limit_exceeded although I have no open orders
Check
GET /positions: free is what you can still add in that metal. On the test path the position is your test book. A trade that reduces your position is always allowed.An order placed in the app is missing from GET /orders
An order placed in the app is missing from GET /orders
App orders that are still being confirmed, or that were refused, are not shown until they are confirmed. See Which orders you see.
detail.code, your client_order_id and the key id from GET /me. Never send the key’s secret.