Reference
Known documentation drift
A living list of places where the official Hyperliquid docs and the live servers disagree, and what this SDK does about it. Each entry is dated when observed; server behavior can change without notice, so treat the "server reality" column as a snapshot, not a guarantee.
When an entry is resolved upstream (docs fixed, or server aligned with docs), move it to Resolved with the date rather than deleting it.
Open
1. l2Book — mantissa: 1 is documented but 500s
- Observed: 2026-07-26
- Docs claim:
mantissaaccepts1,2, or5(l2Book). - Server reality:
mantissa: 1returns HTTP 500. - SDK behavior: correct —
mantissais validated as2 | 5(or omitted), so the broken value is rejected client-side with aValidationErrorbefore any request is sent (packages/hyperliquid/src/api/info/_methods/l2Book.ts).
2. webData2 vs webData3 subscriptions
- Observed: 2026-07-26
- Docs claim:
webData2is listed among the WebSocket subscription channels. - Server reality: the subscription channel the server actually serves for this aggregate user feed is
webData3. - SDK behavior: matches the server —
SubscriptionClientimplementswebData3only.webData2remains available as an info method (InfoClient.webData2), which is unaffected.
3. userFillsByTime — undocumented reversed parameter
- Observed: 2026-07-26
- Docs claim: no
reversedparameter is documented. - Server reality:
reversed: trueworks and returns fills newest-first. - SDK behavior: supported —
reversedis an optional boolean parameter ofInfoClient.userFillsByTime(packages/hyperliquid/src/api/info/_methods/userFillsByTime.ts).
4. userNonFundingLedgerUpdates — startTime is optional, not required
- Observed: 2026-07-26
- Docs claim:
startTimeis a required parameter. - Server reality: the request succeeds without
startTime. - SDK behavior: matches the server —
startTimeis optional (packages/hyperliquid/src/api/info/_methods/userNonFundingLedgerUpdates.ts).
5. activeAssetCtx with a spot coin pushes on activeSpotAssetCtx
- Observed: 2026-07-26
- Docs claim: subscribing to
activeAssetCtxdelivers frames on theactiveAssetCtxchannel. - Server reality: when the subscription carries a spot coin, the server pushes frames on the
activeSpotAssetCtxchannel instead — for the identical{ type: "activeAssetCtx", ... }subscription payload. - SDK behavior: handled — use
SubscriptionClient.activeSpotAssetCtx({ coin })for spot. It sends the identical payload and listens on the channel the server actually uses, and the subscription manager keeps the two channels' listeners separate even though they share one server-side subscription (packages/hyperliquid/src/transport/websocket/_subscriptionManager.ts).
6. Unique users — docs say 10, the server's error says 15, the server enforces 14
- Observed: 2026-08-02 (live mainnet), superseding a 2026-07-26 observation.
- Docs claim: maximum of 10 unique users across user-specific WebSocket subscriptions (updated ~2026-07; rate limits).
- Server reality: 14 distinct users are accepted; the 15th is refused with an
errorframe readingCannot track more than 15 total users.— the message is off by one from the enforcement. Measured by subscribing distinct users one at a time with the client-side guard disabled, twice, on two independent connections; both runs stopped at 14. - Scope: per IP, not per connection. With one connection holding 14 users, a second connection from the same host was refused a 15th distinct user, while still being allowed to subscribe a user the first connection already held. Sharding user channels across sockets therefore buys no additional user slots.
- SDK behavior: enforces the measured 14 (
MAX_UNIQUE_USERS = 14,packages/hyperliquid/src/transport/websocket/_quota.ts), counted against a per-IPWebSocketQuotashared by every transport on the network. The earlier value of 15 was taken from the server's error text and was one too high — the 15th subscription passed the client guard, and because the server's refusal carries no echoed request, it could not be matched to the pending subscribe and surfaced only as a request timeout ~10 s later.
7. TwapState frames gained trigger / stopPx
- Observed: 2026-07-26 — tracked in #48.
- Docs claim:
twapStatesframes carry the documentedTwapStatefields only. - Server reality: frames now also include
triggerandstopPx. - SDK behavior: supported —
TwapStatedeclares both fields as optional and nullable, preserving compatibility with older responses. Set a trigger throughtwapOrder.details.t({ p, a }) and a stop price throughtwapOrder.details.s; either setting can benull. Responses usetrigger: { px, above }andstopPx. Live mainnet history tests cover non-null values and thewaitingForTrigger/stoppedstatuses; offline fixtures also cover older responses that omit the fields. The original type gap tracked in #48 is fixed.
8. Outcome markets have no documented price/size precision
- Observed: 2026-07-26
- Docs claim:
outcomeMetareturns no precision fields (noszDecimals, no tick size) — that much matches the server — and no precision model is documented anywhere for outcome markets. - Server reality (empirical): orders behave like spot — spot-like tick size for prices, integer sizes. This is evidence-based, not protocol-guaranteed; size increments could change per market without notice.
- SDK behavior: the
OutcomeMetaResponsetype mirrors the docs (no precision fields,packages/hyperliquid/src/api/info/_methods/outcomeMeta.ts), andSymbolConverterresolves outcome asset IDs (100000000 + outcomeId * 10 + sideIndex) fromoutcomeMetaalone. Format prices and sizes for outcome markets with the spot-like model above, at your own risk.
9. outcomeMeta outcomes gained a deployer field
- Observed: 2026-08-02 (live mainnet), via the
outcomeMetaschema-coverage test. - Docs claim: each entry of
outcomescarries nodeployer. - Server reality: every outcome in the response now includes
deployer; the schema-coverage check reportsadditionalProperty: "deployer"across the wholeoutcomesarray (observed at indices 0 through 157+). - SDK behavior: fixed —
OutcomeMetaResponseinpackages/hyperliquid/src/api/info/_methods/outcomeMeta.tsdeclaresdeployeras an optional field, so it is typed and the schema-coverage test accepts it. The docs still don't mention the field, so this entry stays open until they do.
10. validatorL1Votes actions gained registerTemplate
- Observed: 2026-08-02 (live mainnet), via the
validatorL1Votesschema-coverage test. - Docs claim: the validator action union covers
registerTokensAndStandaloneOutcomeamong its variants. - Server reality: a live vote carried an action whose
Oobject holdsregisterTemplateand omitsregisterTokensAndStandaloneOutcome, so it matches no variant of the documented union — the check reports bothmissingProperty: "registerTokensAndStandaloneOutcome"andadditionalProperty: "registerTemplate"for the same sample. - SDK behavior: fixed — the union in
packages/hyperliquid/src/api/info/_methods/validatorL1Votes.tsincludes theregisterTemplatevariant (and thesettleQuestion2variant added alongside it), so live votes validate. The docs still don't show the variant, so this entry stays open until they do.
11. Aug-2026 outcome-template API snapshot
- Observed: 2026-08-23.
- Docs at that date: the info-endpoint and exchange-endpoint pages had no entries for
outcomeTemplates,usdcRouting,activateOutcomeDeployer, thespotDeployoutcome sub-actions (registerStandaloneOutcomeFromTemplate,registerQuestionFromTemplate,settleOutcome,settleQuestion2),twapOrder'sdetails(trigger/stop),reserveRequestWeight'sdestination, ormarginTable'sdexparameter. - Server at that date: these additions shipped in the Aug-2026 "HIP-4 outcome templates" API drop.
- SDK behavior: the August schemas were implemented against the reference TypeScript SDK
(nktkas/hyperliquid v0.33.3), which tracks the deployed API, then
widened where live testnet responses went further:
outcomeTemplatesserves keyword formatsuDecimal,uInt, andshortStringand aroleunion ofstandaloneOutcome/questionOutcome/"question"that the upstream schema doesn't cover (observed 2026-08-24). The deployment action formats have since changed on testnet; see the September verification for the remaining compatibility gap.
12. HIP-4 deployment now requires venues
- Verified: 2026-09-26 against
https://api.hyperliquid-testnet.xyz. - Docs: HIP-4 deployer actions
describe activation with
activate: { venueName }ordeactivate: null, and deployment throughoutcomeDeploywithvenueandoperation. - Server reality: both activation variants and all six documented deployment operations parse successfully
and reach signature recovery. The legacy
isDeactivateforms andspotDeploy.outcomeregistration return HTTP 422. Omittingvenueor a standalone template'sdeployerFeeScalealso returns HTTP 422. - Verification scope: every exchange probe uses
r = s = 0, an invalid ECDSA signature. Recognized formats returnUnable to recover signer.No action executes. These results verify request parsing, not staking, permissions, settlement rules, or successful deployment. Repeat withbun run packages/hyperliquid/.dev/verify_hip4_actions.ts. - SDK behavior: activation now accepts
activate: { venueName }ordeactivate: null. UseoutcomeDeploy({ venue, operation })for all six current operations and their required template fee scales. Migrate olderspotDeploy({ outcome: ... })calls by moving the outcome operation tooperationand supplying the venue; the retained legacy shape is not accepted by the current testnet server. - Read API behavior: the response types include deployment metadata (
deployers,feeScale, per-outcomevenueanddeployerFeeScale) and the same specification fields on settled outcomes. Legacy outcomes may omit these fields. The queried templates still omit the documentedsemanticRestrictionfield; its live shape remains unverified.
13. HIP-3 fees moved to asset metadata
- Verified: 2026-09-29 on mainnet and testnet.
- Current docs: HIP-3 deployer actions
describe
setFundingClamps,setDeployerFees, nullable open-interest caps, andnormalmargin mode. - Server reality: DEX metadata includes
assetToFundingClamp; fee scale and change timestamps are per-asset metadata. Sampled DEX objects omit the older DEX-level fee fields. - SDK behavior: supports the current setters and metadata, including
[0, 3]fee scales and[0, 10)in growth mode. LegacysetFeeScale/setGrowthModesremain available for compatibility, but new integrations should usesetDeployerFees. Their absence from current docs does not establish server-side removal; no state-changing probe was used to infer their status. Legacy response fields remain optional.
14. HIP-3* user state is serialized as tuples
- Verified: 2026-09-29 using read-only testnet requests.
- Docs claim:
userStarState.dexToStateis an object keyed by venue. - Server reality: empty state is
[]; a nonempty response for0x0c839e7f21c712e64f80ca0775ec1f35a43af3eeis[["nimb", null]], confirming tuple serialization and removed-approval state. Approved-state flag names follow the documented schema. - SDK behavior: types the observed tuple array. HIP-3* registration, star oracle/proxy operations,
object-valued grants and
userStarStateare supported; these features are documented as testnet-only. Proxied orders must be reduce-only, and scoped cancellation accepts 1-10 asset IDs or null/omission for all.
15. allPerpMetas returns metadata without contexts
- Verified: 2026-09-29 on mainnet and testnet.
- Docs example: all perpetual metadata depicts metadata/context tuples for each venue.
- Server reality: the response is an array of plain metadata objects, aligned with
perpDexsindices. Captured arrays had 11 mainnet entries and 268 testnet entries, including the main venue. - SDK behavior:
AllPerpMetasResponsefollows the plain-object format.SymbolConverteruses it for four-request all-DEX reloads and rejects registry/metadata mismatches before publishing asset IDs.
Resolved
None yet.