Skip to content

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

Merged
0xFantomMenace merged 4 commits into
masterfrom
feat/api-contract-2026-10
Oct 5, 2026
Merged

0xFantomMenace merged 4 commits 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.

…lay only

The SDK's channel table now mirrors /v1/capabilities: hip4_orderbook and
hip4_open_interest replay but do not stream live, and spot_twap neither
streams nor replays (TWAP statuses are REST only).

- oxa stream subscribe refuses hip4_orderbook and hip4_open_interest
  with a pointer to oxa orderbook get / oxa oi current and to replay,
  and refuses spot_twap with a pointer to oxa spot twap history.
- The dedicated verbs check the channel they resolve to against the
  same table, so oxa stream orderbook --exchange hip4 is refused before
  a socket opens instead of waiting on a channel that sends nothing.
  On an SDK without the table they stream as before.
- oxa stream replay names spot_twap as REST only rather than live only.
  It no longer probes the SDK's replay check on an unconnected client
  (the SDK now refuses to send before connect()); the table check runs
  before connecting, and the SDK's own check runs after it.
- Stream and replay help list the channels each mode refuses.
- The live tests compare every channel in the table with
  /v1/capabilities, filter Lighter and Robinhood Chain trades by
  --side (the API applies it there now), and read Spot and Lighter
  trades and books over windows wide enough to hold rows.
oxa candles history --format pretty failed with "padEnd is not a
function" on every venue, because the table printer assumed string
cells and candle rows carry numbers. The printer now writes every cell
as text: numbers keep all their digits without exponent notation,
missing values show as "-", and objects are written as JSON. Every
command's pretty table goes through it.

- Pretty headers and empty cells use plain punctuation
  ("BTC Candles (hyperliquid): 24 records", "-").
- Usage examples in the missing --start/--end messages use a window
  from yesterday, so they run on every plan, including Free.
- The Spot command comments give coverage from oxa capabilities.
- Tests cover the printer and pretty candles on every venue.
…age from capabilities

- Install with npm install -g @0xarchive/cli, so oxa is on the PATH;
  npx stays as the no-install option.
- First Request runs as written on a fresh Free key: it sets NOW,
  HOUR_AGO, DAY_AGO, WEEK_AGO and LAST_HOUR (Unix ms, relative to now)
  and every example in the README uses them, so each window stays
  inside the 30-day history of every plan. HIP-4 examples list the
  open outcomes, look up the current BTC price outcome's side coin
  (COIN), and use it; outcome 0 has settled. HIP-3 examples use
  markets that are trading, and replay examples use speeds every plan
  allows.
- The venue table and the Spot section give each dataset's first
  served instant from oxa capabilities. Spot and Robinhood Chain
  market counts are no longer pinned (the listing commands return the
  current set), Robinhood Chain candles are served from 2026-06-26
  20:10 UTC, and Spot TWAP statuses are REST only.
- The stream section and help no longer list hip4_orderbook,
  hip4_open_interest or spot_twap as live, and oxa spot pairs no
  longer pins a count.
- CHANGELOG 1.10.0 records the pretty table fix, the channel table
  changes, and these documentation changes.
@0xFantomMenace
0xFantomMenace merged commit c4b1489 into master Oct 5, 2026
2 checks passed
@0xFantomMenace
0xFantomMenace deleted the feat/api-contract-2026-10 branch October 5, 2026 00:47
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