Skip to main content
Upside returns errors at two levels: HTTP-level errors that appear in the top-level status: "error" response, and business-level errors that appear inside response.data.statuses[] even when status is "ok". Both levels are documented here.

HTTP-Level Error Codes

These errors are returned with a non-200 HTTP status code when the server rejects the request before or during processing. The response body contains status: "error", a machine-readable code, and a human-readable message.

Business-Level Errors

These errors appear inside response.data.statuses[] when the request envelope is valid and authenticated, but the matching engine or risk engine rejects one or more operations within the batch. The outer status is "ok" and the HTTP status is 200.

Troubleshooting

This is the most common error when integrating for the first time. Work through this checklist:
  1. Right signing path — Funds/permission actions (registerAccount, approveAgent, revokeAgent, lockCollateral, unlockCollateral, transferBetweenDeployers) use the EIP-712 typed struct; everything else uses the Agent path. Signing an action via the wrong path always fails. See Authentication.
  2. Canonical JSON (Agent path) — Keys must be sorted alphabetically with compact separators and no whitespace: json.dumps(action, sort_keys=True, separators=(",", ":")). A single extra space produces a different actionHash.
  3. Correct domain & nonce encoding — Use the fixed domain (name="Exchange", version="1", chainId=9767, verifyingContract=0x0). The nonce is a big-endian 8-byte suffix inside the Agent actionHash, but a 32-byte uint64 field in a typed struct — mixing these up is a common cause.
  4. No double-hashing — The EIP-712 digest is already the final hash. Pass the 32-byte digest directly to the signing function (prehash = false); do not hash again.
  5. Correct v value — Ensure v = sig.v if sig.v >= 27 else sig.v + 27. Some libraries return v as 0 or 1; you must add 27.
  6. Right private key — The SIGNATURE_INVALID message includes the recovered address. If it doesn’t match your expected address, you are signing with a different private key than the one whose address you registered.
This is a business-level rejection, not an HTTP error. The request was correctly signed and delivered to the matching engine, but the engine rejected the order.Check response.data.statuses[0].error for the rejection reason. Common causes:
  • size must be positive — You passed "s": "0" or a negative string.
  • price <n> exceeds maxTicks — On testnet, price must be ≤ 10000.
  • signer has no registered account — You need to call registerAccount first.
  • orderId not found — The oid you tried to cancel doesn’t exist or was already filled.
Always iterate over the entire statuses array when placing batch orders — some items in the batch may succeed while others fail.
A DOWNSTREAM_TIMEOUT (HTTP 504) means the backend matching engine did not return a result within the server’s 5-second timeout window. Critically, this means the operation was not applied — you will not find a new order or cancellation as a result of that request.What to do:
  1. Wait 1–2 seconds.
  2. Query POST /info with userOrders to confirm the current state of your orders.
  3. If the order does not exist, retry the request with a fresh nonce.
  4. If you continue to see timeouts, check the Upside status page or contact support with your requestId.
This means the address has already been registered in this environment. You do not need to register again — proceed directly to placing orders.If you are generating a new keypair each time in your test scripts, each new address will need its own registerAccount call. Consider persisting your test wallet’s private key between runs.
Some environments require a valid invite code to register. Make sure you:
  1. Place the inviteCode field at the top level of the envelope — not inside the action object.
  2. Do not include inviteCode inside the signed message (it is outside action).
  3. Check whether the code was already used (ALREADY_USED) or is simply wrong/expired (NOT_FOUND).
Contact the Upside team to obtain a valid invite code for restricted environments.