Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.adipredictstreet.com/llms.txt

Use this file to discover all available pages before exploring further.

All error responses share the same envelope:
{
  "code": "insufficient_funds",
  "message": "overdraft on 0xabc.../USDC (lock): Δavail=-100, Δlock=100",
  "details": { ... }
}

HTTP status code conventions

StatusMeaningExample
200Success — but check code field for business rejectsUser tried to trade more than their balance
201Resource createdWithdrawal request accepted
400Client error — malformed requestMissing field, invalid address
401UnauthenticatedMissing / malformed / revoked / expired X-Api-Key (see api_key_* codes)
403ForbiddenBanned wallet or API-key scope missing (api_key_scope_missing)
404Not foundOrder doesn’t exist
409Conflict — valid request, wrong stateMarket not OPEN
429Rate limitedExceeded per-wallet quota
503Service unavailableMatcher down

Business rejects vs HTTP errors

Two reject-envelope shapes are in use across the partner surface; which one you get depends on the endpoint family. Branch on the path, not on a single shape detector.

Order placement — full success-envelope shape with status: 'REJECTED'

POST /api/orders/place always returns the same JSON shape regardless of outcome — placement success and business reject share the schema, distinguished by the top-level status field. The HTTP status is 201 Created even on reject because the request was accepted and processed; the body tells you the matcher’s verdict.
{
  "orderId": "",
  "status": "REJECTED",
  "filledQty": "0",
  "remainingQty": "0",
  "trades": [],
  "code": "insufficient_funds",
  "message": "overdraft ..."
}
Branch on body.status: OPEN / FILLED / PARTIAL are good, REJECTED carries the failure reason in code.

Vault signature requests — bare {code, message} envelope

POST /api/vault/{split,merge,convert}-signature (and most other non-/orders/place endpoints when they reject through the core-api → exchange-service hop) return a doubly-nested envelope: the outer status numeric mirrors the HTTP status, and the actual error code lives under error.code:
HTTP/1.1 503 Service Unavailable
Content-Type: application/json

{
  "status": 503,
  "error": {
    "code":     "lock_invariant_violation",
    "message":  "vault state diverged from off-chain mirror",
    "trace_id": "06d5d318-0204-47cb-9607-3b37a531e760",
    "details":  { ... optional structured context ... }
  }
}
trace_id is always present and matches the X-Trace-Id header on the response — quote it when filing tickets. details is endpoint- specific (rate-limit windows, conflicting state, etc.).

Upstream errors — flattened to error.code directly

Errors raised by downstream services (matcher, vault helper, exchange-service, withdrawal pipeline) reach the partner with the original code surfaced at the top of the envelope:
{
  "status": 404,
  "error": {
    "code":     "withdrawal_not_found",
    "message":  "no record for id wd-...",
    "trace_id": "...",
    "details": {
      "upstream": {
        "status": 404,
        "body": {
          "code":    "withdrawal_not_found",
          "message": "no record for id wd-..."
        }
      }
    }
  }
}
Affects (non-exhaustive) POST /api/orders/place upstream rejects, POST /api/me/withdrawals/{id}/cancel (invalid_state, not_found), POST /api/vault/{split,merge,convert}-signature upstream rejects from exchange-service. Branch on error.code directly — the upstream code is now lifted to the top level, so the /errors/codes catalogue is canonical regardless of whether the rejection originated in core-api or in a downstream service.
error.details.upstream still carries the original wrapper ({status, body}) for diagnostic and logging tooling that needs the upstream-side context. New partner code should rely on top-level error.code exclusively. The exchange_upstream_error wrapper code is still emitted as a fallback for non-structured upstream responses (HTML proxy page, empty body, raw text).

Why two shapes

POST /api/orders/place is the only endpoint where the matcher’s “sync” rejection path returns a structured fill record (zero-fills, zero-trades) — that record is the same shape a successful fill returns, so the schema unifies success and reject and the HTTP code stays 201. Vault signature endpoints are pure pre-flight checks with no fill record to return; they reuse the platform-wide HTTP error envelope. Look at code either way to distinguish success from reject — it’s present in both shapes.

Error codes

Complete code reference across all endpoints.