Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

FIX

The gateway accepts FIX 4.4 sessions on its FIX listener (plain TCP on the development network, TLS in production). The session layer is standard. The application layer is the same order entry the HTTP API fronts: every message is a call the HTTP routes make, with the same checks, the same engine input and the same signature, so nothing means something different over FIX.
Orders stay signed. The settlement contract settles only orders their maker signed (EIP-712 Order), so a NewOrderSingle carries the maker's signature over the order's terms in a field of its own, exactly as POST /v1/orders does. The logon proves who is connected, and nothing more. A counterparty's FIX engine signs with a signing key the account registered on chain, so the account's own key never sits in a trading process.

Logon

FIX.4.4, target CompID HYPERVOLIC. Any SenderCompID; one connection at a time per pair of CompIDs. A second connection for a pair that is logged on is closed at the door.
TagValue
34 MsgSeqNum1 (sequence numbers reset at every logon)
108 HeartBtInt1 to 300 seconds
553 UsernameThe account's address
52 SendingTimeYYYYMMDD-HH:MM:SS.sss, UTC, within 30 seconds of the gateway's clock
96 RawDataA 65-byte EIP-191 signature, in hex, over the message below
Hypervolic FIX logon Address: <the address, EIP-55 checksummed> SendingTime: <tag 52, verbatim>
The signer may be the address or a key it registered. Logon must be the first message, within 10 seconds of connecting. The gateway answers with a Logon (98=0, your HeartBtInt echoed), or a Logout giving the reason. A refused signature counts against your IP's failed-signature budget, shared with the HTTP API.
The gateway bounds connections in all and per remote address; a connection past either bound is closed without a Logout.

The session

  • Heartbeats at the agreed interval, and a TestRequest when the other side is silent for 1.2 intervals.
  • The gateway keeps no message store. A ResendRequest is answered with a SequenceReset-GapFill. An execution report you missed is recovered by OrderStatusRequest, the same recovery every HTTP and WebSocket client has.
  • A session that falls behind the stream is logged out with a Text saying so, and its connection closed two seconds later if still open. Log on again and recover by OrderStatusRequest.
  • A gateway's FIX sessions end with it. Reconnect to another gateway; nothing about your orders lives in the session.

Units and names

Prices (44, and 31, 6 on reports) are integer micro-USDC per contract on the tick ladder. Quantities are whole contracts. 55 Symbol is the engine's own name for a contract, underlyingKey:optionSpecifier in decimal, as the instruments list them. 11 ClOrdID is the order's nonce in decimal. 1 Account must be the logged-on address on every message and every list member, or the message is refused with a BusinessMessageReject (380=6) before any signature in it is read.

Messages in

MessageFieldsDoes
NewOrderSingle D11 nonce, 1, 55, 54 (1 buy, 2 sell), 38, 44, 20001 MaxFeeBps (0 to 255), 20002 OrderSignature (65 bytes of hex). Optional 40 (2 only), 59 and 126, 60Places the order. Never waits: the outcome arrives as execution reports
OrderCancelRequest F11 the cancel's nonce, 41 the order's nonce, 1, 20002 over Cancel(maker, nonce, orderNonce)Cancels
NewOrderList E66, then group 73 of up to 256 members. Each has 11, 1, 20002, and 20003 ListMemberAction: 1 new (the default) with D's fields, or 2 cancel with 41One batch: one publication, refused whole
OrderStatusRequest H11, 1. Optional 55 and 54, echoed where the gateway does not know the orderThe order as the live state holds it. Charged to your private-read rate
OrderCancelReplaceRequest GRefused, 380=3: there is no modification. Send the cancel and its replacement together in a NewOrderList
MarketDataRequest VRefused, 380=3: market data is on the WebSocket
Withdrawals stay HTTP (POST /v1/withdraw): a user's own signature, never a session's or a signing key's.
Expiry. 59 absent or 1 with no 126 is the signed expiresAt of "no expiry": the order lives until its contract expires. 59=6 with 126, or 126 alone, is expiresAt = 126 as a whole millisecond. No other TimeInForce is offered: an immediate-or-cancel order is one whose signed expiry has already come. Whatever you send must be exactly what you signed.

Custom tags

TagNameType
20001MaxFeeBpsint, 0 to 255
20002OrderSignaturestring: 0x and 130 hex digits
20003ListMemberActionchar: 1 new order, 2 cancel

Answers

OutcomeAnswer
Order entry refused the order before publishing itExecutionReport 150=8, 39=8, 103=99, 58 the reason; 17 begins rej-
Order entry refused the cancelOrderCancelReject 35=9, 434=1, 102=99, 58 the reason
The engine refused the cancel: ORDER_NONCE_NOT_FOUND, ORDER_ID_NOT_FOUNDOrderCancelReject, 102=1 (unknown order), 58 the code
The engine refused the cancel otherwiseOrderCancelReject, 102=99, 58 the code
A list refusedEvery member answered: a Rejected report for each order, an OrderCancelReject for each cancel
Held, rate limited, or the ingress did not take itBusinessMessageReject 380=4, 379 the ClOrdID or ListID, 58 what to do. Send the same signed message again: a repeat of one that landed is refused as a duplicate
A malformed fieldSession Reject 35=3 naming the tag
Too many of your messages waiting on order entry (64)BusinessMessageReject 380=4: send again

Execution reports

Each session forwards the stream's events for its account, as the WebSocket's account: channel does.
Event15039
inserted0 New0, or 1 where the order had already filled in part
fillF Trade, with 31 LastPx, 32 LastQty, 12 Commission and 13=3 (micros, absolute)1 or 2
cancelled44. Where this session's cancel did it, 11 is the cancel's nonce and 41 the order's
expiredCC
orderSettled3 Done for day3
refused88, 103=99, 58 the engine's code. NONCE_USED is 103=6 (duplicate order) and leaves the order the nonce names untouched
  • 17 ExecID is the event's stream position, with -m or -t on a fill's maker and taker sides, so every gateway sends the same id for the same event. A fill between two of your own orders is two reports.
  • 37 OrderID is the engine's order id, from inserted, or NONE before the order rests.
  • 14 CumQty, 151 LeavesQty and 6 AvgPx are tracked per session from the events; AvgPx is rounded to the nearest micro. For an order the session placed they are exact. An order first seen on the stream, placed over HTTP or on another session, is seeded once from the live state.
  • 60 TransactTime is the event's engine time.
An OrderStatusRequest is answered by an ExecutionReport with 150=I: 39 is 0 or 1 while the order rests, else 2, 4, C or 3 by how it ended. An order the live state does not hold is 39=8 with 103=5 (unknown order).

Limits

The same buckets as HTTP. Signature-bearing messages are charged per address to the signed-message rate; status requests to the private-read rate; failed signatures per IP. Over a limit you get a BusinessMessageReject 380=4, never a silent drop.

Not offered

  • Market data over FIX. Books, prints and references are on the WebSocket.
  • Quote requests over FIX. Ask for a market with POST /v1/quote-request; the answers reach you as the book's orders.
  • A message store. Recover by OrderStatusRequest.