Skip to content

API contract 2026-10-01: error codes, capabilities, has_more, filters, one grammar - #10

Open
0xFantomMenace wants to merge 1 commit into
masterfrom
feat/api-contract-2026-10
Open

0xFantomMenace wants to merge 1 commit into
masterfrom
feat/api-contract-2026-10

Conversation

@0xFantomMenace

Copy link
Copy Markdown
Member

Adopts the 0xArchive API contract 2026-10-01 in oxa. Every request selects that API version (the 0xArchive-Version header on REST, version= on WebSocket connections), including the requests the CLI sends itself for HIP-4 and Spot candles. Folded into the unreleased 1.10.0 section of the changelog; the version is unchanged.

Requires @0xarchive/sdk 1.12.0 (0xArchiveIO/sdk-typescript#23), which the package already names as its floor.

Changes

  1. Error codes. A failure the API answered prints error_code, request_id, status, and, when the API names them, param and valid_values on the stderr JSON line, in every output format. WebSocket errors from oxa stream and oxa stream replay carry error_code too. Exit codes stay 2, 3, 4, 5 and are now chosen by error class: request errors (invalid_*, range_before_coverage, unsupported_for_venue, route_not_found, not_found) exit 2; key and plan errors (unauthorized, forbidden, historical_*_exceeded, insufficient_credits, ...) exit 3; rate limits, conflicts, upstream and internal errors, slow_consumer, and unknown codes exit 4. Without a code, 401 and 403 exit 3 and the rest 4, as before. The README lists the mapping.
  2. oxa capabilities [--exchange <venue>] [--datatype <d>]: rows from client.capabilities(), as JSON (default) or a table (--format pretty); one row prints in full. No API key needed.
  3. has_more on every paged JSON response and --out summary, next to nextCursor, from the SDK's hasMore (falling back to the cursor on an older SDK). Pretty output prints the cursor to pass back. The CLI has no auto-paging loops; the README shows a shell loop that stops on has_more.
  4. Filters: --side buy|sell on oxa trades history (every venue, ranged and recent), oxa hip4 trades, and oxa spot trades; --triggered true|false on oxa orders history and oxa hip4 orders history; --depth on oxa l2 history, and on oxa orderbook history for HIP-3, HIP-4 and Spot.
  5. Stream and replay follow the SDK's WS_CHANNEL_CAPABILITIES; the CLI keeps no channel list of its own. oxa stream replay now runs bulk replay of every L4 channel on HIP-3, HIP-4 and Spot and of orderbook_full / hip3_orderbook_full (pretty output summarizes each page). oxa stream subscribe accepts the live HIP-4 book and open interest and refuses the replay-only candle channels before connecting. oxa stream trades|orderbook --exchange hip4 added.
  6. One grammar: shared datatypes are oxa <datatype> <verb> --exchange <venue>: trades history, candles history, cvd history --symbol, instruments list, symbols list, summary get, prices history, freshness get, and --exchange spot on the shared datatypes Spot serves (order book get and history, trades, candles, L4, order history, freshness, instruments). Venue-only data sits under the venue: oxa lighter l3 get|history, oxa lighter accounts by-l1, oxa spot pairs list|get, oxa spot twap history. Every earlier form keeps working and runs the same command; nothing is removed or hidden.
  7. Lighter naming: help, README, changelog and source say Lighter; a test keeps it that way, and keeps em dashes out of the help text.

JSON output follows the response shapes of 2026-10-01: RFC 3339 timestamp with timestampMs on CVD, the HIP-3 oracle, Lighter liquidations and the resting orders of an L4 snapshot; snapshotTsMs beside snapshotTs on levels; Lighter replay rows in the live shapes. Also fixed: the pretty order history table showed blank price and user columns.

Tests

  • npm run typecheck, npm test, npm run build, npm run check:pack pass with SDK 1.12.0: 435 passed, 17 skipped (the opt-in live suite and the old-SDK case).
  • The same checks pass on the published SDK that CI installs until 1.12.0 is on npm: 358 passed, 94 skipped (the checks that need the SDK's channel table or contract fields skip there, as the webhook verifier checks already do).
  • New: tests/contract.test.ts (errors and exit codes, capabilities, has_more, filters, both command forms), tests/contract-http.test.ts (requests and answers over a stubbed fetch, through the SDK and the CLI's own client), and tests/live.test.ts, read-only against the live API and skipped unless OXA_LIVE_API_KEY is set. It passes against production (16 tests). --side on Lighter and Lighter on Robinhood Chain is marked expected to fail there until the API applies that filter on those venues.
  • npm pack --dry-run ships LICENSE, README.md, dist/cli.js, dist/cli.js.map, package.json, as before.

…, one grammar

Every request selects API version 2026-10-01, and the CLI reads the
response shapes of that version.

- Failures print the API's error_code, request_id, status, param and
  valid_values on the stderr JSON line, in every output format, and exit
  by error class: request errors 2, key and plan errors 3, the rest 4.
  WebSocket errors carry error_code the same way.
- oxa capabilities [--exchange] [--datatype]: what each venue serves, as
  JSON or a table. No API key needed.
- has_more on every paged JSON response and --out summary; pretty output
  prints the cursor to pass back.
- --side buy|sell on trade history (every venue, ranged and recent),
  --triggered on order history (Hyperliquid, HIP-3, HIP-4), and --depth
  on full-depth L2 history; order book history --depth now applies on
  HIP-3, HIP-4 and Spot.
- Stream and replay follow the SDK's channel table: bulk replay of every
  L4 channel on HIP-3, HIP-4 and Spot and of the full-depth books; live
  HIP-4 book and open interest; replay-only channels refused up front.
- One grammar: oxa <datatype> <verb> --exchange <venue> (trades history,
  candles history, cvd history, instruments list, symbols list, summary
  get, prices history, freshness get, and --exchange spot on the shared
  datatypes Spot serves), with venue-only data under the venue (lighter
  l3, lighter accounts, spot pairs get, spot twap history). Earlier
  forms keep working.
@nuttykenzo

Copy link
Copy Markdown
Contributor

Target date: no date → 2026-10-08

Date status: Proposed. This is a proposed delivery target; owner confirmation is still required.

Why: K requested a Target date on every active tracked item. This copies the already recorded planning/review date; it does not create owner agreement or change scope, status, priority, ownership, implementation/deployment/sending permission, or any release hold.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants