Skip to main content
UpsideMAX returns JSON for every request. Understanding the response structure is important because HTTP 200 does not always mean the operation succeeded — business-level rejections (such as invalid order prices or unknown order IDs) return HTTP 200 with error detail inside the response body. This page explains every response shape you may encounter.

POST /exchange Success Response

When a write operation is accepted and processed, the server returns HTTP 200 with status: "ok":
string
Always "ok" for HTTP-level success. Note that business-level errors can still appear inside response.data even when status is "ok".
string
A server-generated unique identifier for this request. Include this value when contacting UpsideMAX support — it allows the team to trace the request through server logs.
string
Echoes the action.type from the request. Useful for confirming which action the response corresponds to when processing responses asynchronously.
object
Action-specific result data. For order actions this contains a statuses array. For registerAccount this contains accountId. See each action’s reference page for the full data shape.

POST /exchange Error Response

When the server rejects the request at the HTTP level (bad signature, malformed JSON, rate limit, etc.), it returns a non-200 HTTP status with status: "error":
string
Always "error" for HTTP-level failures.
string
Server-generated request identifier. Provide this to UpsideMAX support when reporting an issue.
string
Machine-readable error code. See Error Codes for the full list.
string
Human-readable explanation of the error. Branch on code, not on message.

Parameter validation errors

When a request parameter fails validation, the server rejects the request before processing with HTTP 400 and code: "INVALID_PARAM". The body adds an errors[] array with one entry per failing field:
array
Field-level validation details. Present only when code is "INVALID_PARAM".

Business-Level Errors

Some operations return HTTP 200 with status: "ok" but contain per-item errors inside response.data.statuses. This occurs when the request envelope is valid and signed correctly, but one or more of the operations within the request was rejected by the matching engine.
Each entry in statuses corresponds to one item in the request’s array (e.g. one entry per order in orders[]). A successful item looks like {"resting": {"oid": 15}} or {"filled": {...}}. A rejected item looks like {"error": "<message>"}.
Always check the statuses array in order and cancel responses. An HTTP 200 response does not guarantee that any or all operations within the request succeeded. Iterate over statuses and handle each error entry explicitly.

POST /info Response

Read query responses return HTTP 200 with the query result directly in the body. There is no wrapper status field — the body IS the data. For example, userOrders returns an object that echoes the query and carries the orders in an orders array:
The order entries above are abbreviated; see userOrders for the complete field list. If the query fails (bad type, missing required fields), the server returns a non-200 status with an error body consistent with the exchange error format.

The two endpoints do not share a response shape

This asymmetry costs most integrators a round trip. Compare them side by side before writing a parser:
Sending {"action": {"type": "configs"}} to /info fails, and reading result["data"]["contracts"] from an /info response returns nothing. Neither mistake produces an error that names the real cause.

HTTP 202 — accepted, not completed

The order and cancel family — order, cancel, cancelByCloid, cancelAll, modify — may answer with 202 instead of 200:
type is the literal "accepted", not the action name, and there is no statuses[]. Clients must handle both status codes. To choose the form explicitly, set the envelope field sync — see Exchange Requests. A 202 means the batch was taken for processing. It does not mean an order rested — a rejection after acceptance is delivered only on the orderUpdates channel, never in the HTTP response. Confirm the outcome from userOrders, correlating on the client order ID you set.

The requestId Field

Every POST /exchange response includes a requestId such as "req-144115188075855905". This is a globally unique identifier generated by the server for each incoming request. When you contact UpsideMAX support about a specific request — whether it succeeded unexpectedly, failed unexpectedly, or produced a surprising result — including the requestId allows the support team to locate the exact request in server logs and investigate efficiently.
Log the requestId for every POST /exchange call your application makes. Even if you don’t need it immediately, having it available significantly speeds up any future debugging or support conversations.