Skip to content

API version 2026-10-01: error codes, has_more, capabilities, working filters, L4 replay - #19

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

0xFantomMenace merged 4 commits into
mainfrom
feat/api-contract-2026-10

Conversation

@0xFantomMenace

Copy link
Copy Markdown
Member

Adopts API version 2026-10-01 in the Rust SDK. Everything is folded into the unreleased 1.12.0 entry of the CHANGELOG; the crate version is unchanged.

What changes for users

Version selector. Every REST request sends 0xArchive-Version: 2026-10-01 and the WebSocket connects with version=2026-10-01 (oxarchive::API_VERSION). The types read the shapes that version selects:

  • the standard {success, data, meta} envelope on the data quality routes, /v1/status/coverage (new data_quality.status_coverage()) and /v1/symbols; the older bodies still decode;
  • RFC 3339 times with an integer *_ms field on L4 snapshot resting orders (L4OrderEntry.timestamp / timestamp_ms), CVD buckets, the HIP-3 oracle, Lighter and Robinhood Chain liquidations and liquidation volume, and snapshot_ts_ms on liquidation and trigger levels;
  • Lighter and Robinhood Chain replay rows in the live shapes, which ServerMsg::lighter_live_data() now decodes for historical_data and replay_snapshot too.

Errors. Error::Api gains error_code (ErrorCode, with Other(String) for codes this release does not name), param and valid_values, next to code and request_id, plus error_code(), status(), request_id(), param() and valid_values() accessors. WebSocket ServerMsg::Error carries error_code, including slow_consumer and endpoint_unsupported.

Paging. CursorResponse is now the same type as MetaResponse: data, next_cursor, has_more and the full meta, which includes meta.symbol and meta.venue. orderbook.collect_tick_history() now follows the tick cursor (cursor + cursor_seq) until has_more is false; before, it returned only the first page. history_tick_page() exposes the same paging.

Capabilities. client.capabilities() returns typed Capability rows from GET /v1/capabilities; Capability::for_channel() finds a WebSocket channel's row.

Parameters the API now applies. side (TradeSide::Buy / Sell) on trades for every venue, including trades.recent_with() and hip4.get_trades_recent_with(); triggered on order history (Hyperliquid, HIP-3, HIP-4); depth on full-depth L2 history and on HIP-3, HIP-4 (Hip4OrderBookHistoryParams) and Spot order book history.

WebSocket replay. replay() no longer refuses the HIP-3, Spot and HIP-4 L4 channels or orderbook_full / hip3_orderbook_full, which the API now replays in bulk. replay_multi() rejects only the channels that replay one at a time (every L4 and full-depth channel). LIVE_ONLY_L4_CHANNELS and is_live_only_l4_channel() are deprecated.

Verbs. Aliases next to the existing names: trades.history(); on HIP-4 list_instruments(), get_trades_history(), get_open_interest_history() and get_price_history(); client.list_symbols().

Also. Triggered order-history rows (no tif) and Spot TWAP rows with numeric sizes now decode. The venue is named "Lighter" throughout.

Compatibility

Additive except where a struct or variant gains fields: a pattern or literal that names every field of Error::Api, ServerMsg::Error, CursorResponse, GetTradesParams, Hip4TradesParams or L2HistoryParams needs the new fields or ... side on the trades params is Option<TradeSide>; side: None compiles unchanged.

Checks

  • cargo test --all-features: 191 passed. cargo test (default features): 154 passed.
  • cargo clippy --all-targets, with and without --all-features: no warnings. cargo doc --no-deps with -D warnings: clean.
  • cargo package --list: no files outside src/, the listed examples, README.md, CHANGELOG.md, LICENSE and Cargo.toml.
  • README snippets that changed compile.
  • Checked read-only against the production API and WebSocket: the version header and envelopes, every outlier time field, error codes, has_more paging, capabilities, side on Hyperliquid, HIP-3, Spot and HIP-4, triggered, depth, and replay of HIP-3, Spot and HIP-4 L4 and both full-depth channels.

… L4 replay

Every request sends 0xArchive-Version: 2026-10-01 and the WebSocket
connects with version=2026-10-01. The SDK reads the shapes that version
selects: the standard envelope on data quality, /v1/status/coverage and
/v1/symbols, RFC 3339 times with *_ms integers on L4 snapshot orders, CVD,
the HIP-3 oracle, Lighter liquidations and levels, and Lighter replay rows
in the live shapes.

- Error::Api carries error_code (ErrorCode, with an Other fallback), param
  and valid_values; ServerMsg::Error carries error_code.
- Paged responses expose has_more and the full meta block, including
  meta.symbol and meta.venue. Tick-level history pages by cursor until
  has_more is false.
- client.capabilities() returns typed rows.
- Trades side (every venue, recent included), order history triggered, and
  depth on full-depth L2 history and HIP-3, HIP-4 and Spot order book
  history.
- WebSocket replay is no longer refused for HIP-3, Spot and HIP-4 L4 or for
  orderbook_full and hip3_orderbook_full; they replay one channel at a time.
- Verb aliases: trades.history(), and list_instruments(),
  get_trades_history(), get_open_interest_history() and get_price_history()
  on HIP-4.
- The venue is named Lighter.
@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.

The pairs routes send base_token_name, quote_token_name, name and
pair_index, so SpotPair::base, quote, wire_symbol and spot_index were
always None. Each field now also accepts the route's name, and the other
registry fields (is_canonical, token ids and decimals, first_seen_at,
last_updated_at) stay in extra. mark_price, mid_price, latest_timestamp
and is_active are deprecated: the pairs routes never return them.
examples/spot.rs prints the mapped fields and reads candles for the last
hour, and a test covers both routes with the field names they send.

replay() and replay_multi() sent "speed": null when speed was None, and
the server gave no answer to that request, so an L4 replay without a
speed waited forever. An unset speed or end is now left out of the
request and the server applies its defaults.
…docs.rs

The include list shipped every .rs file under src/, so an untracked file
there would have been published. It now names each source file. The
package-contents workflow also plants src/stray.rs and
src/resources/stray.rs, and fails when a tracked source file is missing
from the crate, so a new module cannot be left out.

docs.rs builds with all features, and the ws module has its own
documentation, so OxArchiveWs, WsOptions and ServerMsg appear there.

The ignore rules no longer match every file under tests/, which hid
tests/websocket_capability.rs; they name the two local-only files
instead.
The README coverage table gives each dataset's first available instant as
GET /v1/capabilities returns it, instead of months and fixed market
counts, and Robinhood Chain candles are listed as served from
2026-06-26 20:10 UTC.

README, rustdoc and example code read recent minutes, hours or days
instead of fixed dates from 2024 to September 2026, so they work on a Free
key's 30-day window, and they use markets that are trading: xyz:XYZ100 on
HIP-3 and the open daily BTC outcome on HIP-4. The Robinhood Chain trades
snippet and the HIP-3 instruments snippet now compile, replays run at 10x,
and the Spot example comment no longer gives the wrong year.

The WebSocket channel table matches GET /v1/capabilities: spot_twap is
REST only, and hip4_orderbook and hip4_open_interest replay without a
live subscription. Recent trades are listed for HIP-3, HIP-4, Spot,
Lighter and Robinhood Chain, and the Enterprise replay speed is 1000x.

CHANGELOG: an "Upgrading from 1.8" section lists the changes that need
code changes for users coming from the last published release. No em
dashes remain in the README, CHANGELOG, rustdoc or error messages, and
examples/levels_smoke.rs describes what each call returns.
@0xFantomMenace
0xFantomMenace merged commit 871327b into main Oct 5, 2026
1 check 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