Follow our Status Page for real-time updates on system performance and maintenance schedules.
You can also subscribe to receive notifications about any incidents or scheduled maintenance that may affect the API's availability.
For support with the Foxbit FIX API, please visit our Help Center.
Welcome to the official Foxbit's FIX API documentation. The FIX (Financial Information eXchange) API targets institutional clients, market makers and trading systems that already speak FIX and require a low-latency, persistent session for order entry and market-data consumption.
The endpoint accepts standard FIX v4.4 messages over a single TCP session. Authentication, order entry, market data and reference data are all multiplexed onto the same connection, there is no separate trade vs. market-data channel.
Please contact our customer relationship team to obtain the access URL, the default port, and to request IP whitelisting in order to access the FIX API from your server.
Examples throughout this document show messages in the canonical FIX
wire format tag=value with | standing in for the field separator
byte SOH (0x01). Replace | with 0x01 when writing bytes to the
socket.
BodyLength (9) and CheckSum (10) are computed by the FIX engine,
the values in the examples are illustrative; do not copy them
verbatim into hand-built messages.
If you don't find something here, check our other API documentation:
The FIX endpoint is exposed exclusively over TLS, plain-text TCP is
rejected at the listener and never reaches the FIX engine. Clients must
complete the TLS handshake before sending Logon (35=A).
1.2 or 1.3. Earlier versions (SSL 3.0, TLS 1.0,
TLS 1.1) are refused.Logon (35=A), see the
Authentication section.The server certificate needed to validate the TLS handshake is distributed by Foxbit. To request the current certificate contact Foxbit support through the Help Center.
Install the provided certificate in the trust store used by your FIX client. Do not disable certificate verification, an unverified connection bypasses the only transport-layer protection against a man-in-the-middle.
Inbound application messages are rate-limited per MsgType. Each MsgType has its own bucket, so a burst of one kind of request does not consume another's budget.
MarketDataRequest (35=V) is the exception: it is not rate-limited, and is bounded by a ceiling on concurrently subscribed markets instead — see Market-data subscription limit below.
The Logon (35=A) limit is keyed by source IP and enforced before authentication. The remaining limits are keyed by the authenticated trading account and enforced after it; the bucket is shared across every session of the same account, so opening additional sessions does not multiply the budget.
| MsgType | Limit | Scope |
|---|---|---|
| Logon (35=A) | 10 per 2 seconds | per source IP |
| MarketDataRequest (35=V) | 25 subscriptions | per message |
| NewOrderSingle (35=D) | 30 per 2 seconds | per account |
| OrderCancelRequest (35=F) | 30 per 2 seconds | per account |
| OrderStatusRequest (35=H) | 30 per 2 seconds | per account |
| RequestForPositions (35=AN) | 5 per minute | per account |
| SecurityListRequest (35=x) | 6 per second | per account |
| TradeCaptureReportRequest (35=AD) | 5 per second | per account |
When the limit is exceeded the response depends on the inbound message:
Logon (35=A) is rejected with a Logout (35=5); the connection is closed.NewOrderSingle (35=D) is answered with an ExecutionReport (35=8) carrying OrdStatus=8 Rejected, OrdRejReason=3 Order exceeds limit and Text=Request limit exceeded. Try again later..OrderCancelRequest (35=F) is answered with an OrderCancelReject (35=9) carrying CxlRejReason=99 Other and Text=Request limit exceeded. Try again later..SecurityListRequest (35=x) is answered with a SecurityList (35=y) carrying SecurityRequestResult=4.OrderStatusRequest (35=H) is answered with an ExecutionReport (35=8) carrying ExecType=8 Rejected, OrdStatus=8 Rejected and Text=Request limit exceeded. Try again later..RequestForPositions (35=AN) is answered with a RequestForPositionsAck (35=AO) carrying PosReqResult=99 Other, PosReqStatus=2 Rejected.TradeCaptureReportRequest (35=AD) is answered with a TradeCaptureReportRequestAck (35=AQ) carrying TradeRequestResult=99 Other, TradeRequestStatus=2 Rejected.MarketDataRequest (35=V) is not rate-limited (bursts are paced server-side and serviced over a few seconds). What is bounded is concurrently subscribed markets: 150 per account, shared across all sessions. It counts markets, not requests: every market in NoRelatedSym is charged, so batching buys nothing, and a 35=V is accepted or rejected in full. Independently, a request may name at most 25 markets; splitting is fine as long as the account limit holds.
Only SubscriptionRequestType=1 Snapshot + Updates charges capacity; 0 Snapshot is free. Capacity returns on SubscriptionRequestType=2 and on logout. Cancels are exempt from both caps, so any subscription unwinds in one request, and capacity frees the moment the cancel is accepted, not when the broker confirms it, so a client at the limit can rotate by sending 2 then 1 without waiting. A cancel naming no symbols frees the whole subscription; one naming symbols frees only those, and the rest stay charged. Re-subscribing under a streaming MDReqID replaces its market set, but is charged in full while the old set is still counted, so a near-limit re-subscribe may be refused now and accepted a moment later; if it is rejected, the previous set keeps streaming.
Both failures return MarketDataRequestReject (35=Y) with MDReqRejReason=2 Insufficient bandwidth, as FIX 4.4 has no distinct value; Text tells them apart. Over the account limit: Text=Subscription limit exceeded. Unsubscribe before subscribing to more markets., not retryable until markets are canceled. Over 25 in one request: Text=Too many markets in one request. A MarketDataRequest may name at most 25 markets. Split the request.
Every FIX session is authenticated at Logon (35=A) with an HMAC-SHA256 signature derived from the session's API secret. The signature is presented in RawData (96) and verified server-side against the API key declared in Username (553).
Credentials are issued per integration and bound to a role. Only API keys carrying the trade role are accepted by the FIX endpoint; keys without that role are rejected with a generic Logout even if the signature is otherwise valid.
A single API key may also restrict the IP addresses allowed to authenticate with it. When configured, the Logon is rejected if the source IP is not on the trusted list.
The signature input (the prehash) concatenates five fields from the Logon message, separated by the FIX field-separator byte (SOH, 0x01):
prehash = SendingTime(52) + SOH + MsgType(35) + SOH + MsgSeqNum(34) + SOH + Username(553) + SOH + TargetCompID(56)
The signature is then:
RawData(96) = Base64( HMAC-SHA256( apiSecret, prehash ) )
RawDataLength (95) carries the byte length of the Base64-encoded signature.
Example (Python):
import base64, hmac, hashlib
sending_time = "20260508-12:00:00.000"
msg_type = "A"
msg_seq_num = "1"
api_key = "<your-api-key>"
target_comp_id = "FOXBIT-FIX-API"
api_secret = "<your-api-secret>"
prehash = "\x01".join([sending_time, msg_type, msg_seq_num, api_key, target_comp_id])
signature = base64.b64encode(
hmac.new(api_secret.encode(), prehash.encode(), hashlib.sha256).digest()
).decode()
SendingTime (52) must carry the current UTC timestamp at the moment the Logon is sent and must be unique per attempt. Keep the client clock synchronized via NTP, large clock skew can cause timestamp validation failures.
Logon (35=A) with Username, RawData, RawDataLength, SendingTime and MsgSeqNum.Logon echo before sending application messages.Logout (35=5) carrying Text, treat the session as terminated and inspect the reason before reconnecting.Authenticates the session. Must be the first application-level message sent after the TCP connection is established. See the Authentication section for the signature construction and the recommended flow.
| 8 required | string BeginString — protocol version. Must be Value: "FIX.4.4" |
| 34 required | integer MsgSeqNum — message sequence number, also part of the HMAC prehash. |
| 35 required | string MsgType — Value: "A" |
| 49 required | string SenderCompID — your client identifier (assigned by Foxbit). |
| 52 required | string SendingTime — current UTC timestamp in |
| 56 required | string TargetCompID — the server identifier. Must be Value: "FOXBIT" |
| 95 required | integer RawDataLength — byte length of the Base64-encoded signature in
|
| 96 required | string RawData — Base64-encoded HMAC-SHA256 signature of the prehash. See the Authentication section for the prehash format. |
| 98 required | integer EncryptMethod — encryption is unsupported. Must be |
| 108 required | integer HeartBtInt — heartbeat interval in seconds. Recommended |
| 141 | string Default: "N" Enum: "Y" "N" ResetSeqNumFlag — request a sequence-number reset for this session.
Set to |
| 553 required | string Username — your Foxbit API key. |
"8=FIX.4.4|9=193|35=A|34=1|49=ACME|52=20260508-12:00:00.000|56=FOXBIT|98=0|108=30|141=N|553=a4e9b1c0-3f8e-4a2b-b1c2-3d4e5f6a7b8c|95=44|96=8x4Q3a4z6yYg7Zk2Lp+gB1lWmJpTQ8U7uHcG4hPXAxA=|10=128|"On a successful authentication the server replies with a Logon (35=A) echo. From this point on, application messages are accepted on the session.
| 8 | string Value: "FIX.4.4" |
| 35 | string MsgType — Value: "A" |
| 49 | string SenderCompID — Value: "FOXBIT" |
| 56 | string TargetCompID — echoes the client identifier from the request. |
| 98 | integer |
| 108 | integer HeartBtInt — echoes the requested heartbeat interval. |
"8=FIX.4.4|9=72|35=A|34=1|49=FOXBIT|52=20260508-12:00:00.050|56=ACME|98=0|108=30|10=045|"Authentication failures fall into two categories:
A protocol-level rejection is sent as a BusinessMessageReject (35=j) with BusinessRejectReason=5 Conditionally required field missing and RefTagID=96 when the signature is mathematically invalid for the supplied prehash.
All other failures (missing required tag, unknown API key, role mismatch, IP not whitelisted) are reported as a Logout (35=5) carrying a generic Text="could not process logon". The connection is then closed.
Common causes:
trade role.| 35 | string Enum: "5" "j" MsgType — |
| 58 | string Text — generic reason. Always |
| 371 | integer RefTagID (only on Value: 96 |
| 380 | integer BusinessRejectReason (only on Value: 5 |
"8=FIX.4.4|9=88|35=5|34=2|49=FOXBIT|52=20260508-12:00:00.500|56=ACME|58=could not process logon|10=233|"Submits a new order to the matching engine. Only Limit orders are supported on this version of the API; OrdType (40) must be set to 2 Limit. Orders carry one of two time-in-force values:
IOC (TimeInForce=3 Immediate Or Cancel): match what is available, cancel the remainder immediately.FOK (TimeInForce=4 Fill Or Kill): match the entire size or cancel; no partial fills.Decimal precision is preserved end-to-end: OrderQty, Price, StopPx and CashOrderQty are decimal strings and are forwarded to the matching engine without floating-point conversion.
| 11 | string ClOrdID — client-side unique order identifier. Optional but strongly
recommended for client-side reconciliation; echoed back on every
| ||||||||||
| 18 | string ExecInst — order handling instruction. Only
A post-only order is guaranteed to add liquidity: if it would match
immediately against a resting order, the matching engine cancels it
instead of executing. The cancellation arrives as an
Post-only requires Value: "6" | ||||||||||
| 35 required | string MsgType — Value: "D" | ||||||||||
| 38 | string OrderQty — base-asset quantity, decimal string. Either | ||||||||||
| 40 required | string OrdType — order type. Only Value: "2" | ||||||||||
| 44 | string Price — limit price, decimal string. Required for any meaningful order; orders sent with no price will be rejected by the matching engine. | ||||||||||
| 54 required | string Enum: "1" "2" Side — | ||||||||||
| 55 required | string Symbol — market symbol. Case-insensitive on input; the server lowercases it before forwarding. | ||||||||||
| 59 | string Enum: "1" "3" "4" TimeInForce — only A | ||||||||||
| 60 required | string TransactTime — UTC timestamp at which the client generated the
order, in | ||||||||||
| 99 | string StopPx — stop trigger price, decimal string. Reserved for future use; parsed but not currently honoured by the matching engine. | ||||||||||
| 152 | string CashOrderQty — quote-asset quantity, decimal string. Use to express the order size as a notional amount instead of base quantity. | ||||||||||
| 20200 | string Enum: "EXPIRE_BOTH" "EXPIRE_MAKER" "EXPIRE_TAKER" "DECREMENT" SelfTradePrevention — selects what happens when this order would match against one of your own resting orders. Optional; when the tag is omitted the account's configured default applies.
Values are case-insensitive. Any other value is rejected with
Applies to book orders only. On a quote execution (a When the rule cancels an order, that order is reported on an
|
"8=FIX.4.4|9=176|35=D|34=2|49=ACME|52=20260508-12:00:01.000|56=FOXBIT|11=order-2026-05-08-001|55=btcbrl|54=1|40=2|38=0.00350000|44=350000.00|59=3|60=20260508-12:00:01.000|10=215|"Every NewOrderSingle is acknowledged with at least one ExecutionReport (35=8). Subsequent fill, cancel and reject events are also delivered as ExecutionReport. See the ExecutionReport section for the full response schema.
Cancels a single working order (for example a resting GTC limit order). The order is located by one of two lookup keys, at least one of which must be present:
OrderID (37): the numeric exchange id assigned on order creation
(echoed on every ExecutionReport). Preferred key.OrigClOrdID (41): the original numeric client order id.When both are supplied OrderID (37) takes precedence. ClOrdID (11)
identifies the cancel request itself and is required.
Cancellation is asynchronous: submitting 35=F only registers the
request; there is no synchronous confirmation that the order left the book.
Order Cancel/Replace (35=G) is out of scope.
| 11 required | string ClOrdID — the client-assigned identifier of this cancel request.
Required. Echoed on the |
| 35 required | string MsgType — Value: "F" |
| 37 | string OrderID — the numeric exchange id assigned on order creation and
echoes on every |
| 41 | string OrigClOrdID — the client order id of the order being canceled
(cancel-by-ClientOrderID): the same |
| 54 | string Enum: "1" "2" Side — |
| 55 | string Symbol — market symbol. Not a lookup key; echoed back. |
| 60 | string TransactTime — request time, |
"8=FIX.4.4|9=153|35=F|34=2|49=ACME|52=20260508-12:05:00.000|56=FOXBIT|11=cancel-2026-05-08-001|41=451637946501|37=1928374651|54=1|55=btcbrl|60=20260508-12:05:00.000|10=061|"An accepted request is acknowledged synchronously with an
ExecutionReport (35=8) carrying ExecType=6 PendingCancel /
OrdStatus=6 Pending Cancel. The order actually leaving the book is reported
asynchronously as a later ExecutionReport with ExecType=4 Canceled /
OrdStatus=4 Canceled — which also carries the final CumQty (14) when the
order was partially filled before cancellation. See the
ExecutionReport section.
| 6 | string AvgPx — Value: "0" |
| 11 | string ClOrdID — echoes the cancel request's |
| 14 | string CumQty — Value: "0" |
| 17 | string ExecID — unique execution id for this report. |
| 35 | string MsgType — Value: "8" |
| 37 | string OrderID — the resolved numeric exchange id. |
| 39 | string OrdStatus — Value: "6" |
| 41 | string OrigClOrdID — echoes the request's |
| 54 | string Enum: "1" "2" Side — |
| 55 | string Symbol — the order's market. |
| 60 | string TransactTime — |
| 150 | string ExecType — Value: "6" |
| 151 | string LeavesQty — remaining open quantity at acceptance, decimal string. |
"8=FIX.4.4|9=178|35=8|34=5|49=FOXBIT|52=20260508-12:05:00.100|56=ACME|37=1928374651|17=3f2a1c9d0b7e4a56|150=6|39=6|11=cancel-2026-05-08-001|41=451637946501|54=1|55=btcbrl|40=2|151=0.00250000|14=0|6=0|60=20260508-12:05:00.100|10=181|"A cancel that cannot be honored is refused with an OrderCancelReject (35=9)
carrying CxlRejResponseTo=1, a coded CxlRejReason (102) and the reason in
Text (58):
102=1, Text=order not found.102=0 Too late,
Text=order already executed / Text=order already canceled.102=3, Text=order already pending cancel.102=99.A message carrying neither OrderID (37) nor OrigClOrdID (41) is rejected
at the protocol level with Reject (35=3).
| 11 | string ClOrdID — echoes the cancel request's |
| 35 | string MsgType — Value: "9" |
| 37 | string OrderID — resolved exchange id, or |
| 39 | string Enum: "2" "4" "6" "8" OrdStatus — the order's current status:
|
| 41 | string OrigClOrdID — echoes the request's |
| 58 | string Text — human-readable rejection reason. |
| 60 | string TransactTime — |
| 102 | string Enum: "0" "1" "3" "99" CxlRejReason — |
| 434 | string CxlRejResponseTo — Value: "1" |
"8=FIX.4.4|9=158|35=9|34=5|49=FOXBIT|52=20260508-12:05:00.100|56=ACME|37=1928374651|11=cancel-2026-05-08-001|41=451637946501|39=8|434=1|102=1|58=order not found|60=20260508-12:05:00.100|10=094|"ExecutionReport is the outbound message that carries every state change for an order. The same MsgType is reused with different ExecType (150) and OrdStatus (39) combinations to express acceptance, fills, cancellation and rejection.
All variants always populate: OrderID (37), ExecID (17), ExecType (150), OrdStatus (39), Side (54), LeavesQty (151), CumQty (14) and AvgPx (6). Other fields are populated when applicable to the variant.
Sent immediately after the matching engine accepts the order; the order is now live on the book.
| 6 | string AvgPx — average fill price. Value: "0" |
| 11 | string ClOrdID — echoes the client-supplied identifier from the original
|
| 14 | string CumQty — cumulative filled quantity. Value: "0" |
| 17 | string ExecID — unique identifier for this execution event. |
| 35 | string MsgType — Value: "8" |
| 37 | string OrderID — server-side unique order identifier. |
| 38 | string OrderQty — original requested quantity, decimal string. |
| 39 | string OrdStatus — Value: "0" |
| 44 | string Price — original limit price, decimal string. |
| 54 | string Enum: "1" "2" Side — |
| 55 | string Symbol — echoes the market. |
| 150 | string ExecType — Value: "0" |
| 151 | string LeavesQty — quantity still working in the book. |
| 20200 | string Enum: "EXPIRE_BOTH" "EXPIRE_MAKER" "EXPIRE_TAKER" "DECREMENT" SelfTradePrevention — echoes the mode supplied on the
|
"8=FIX.4.4|9=212|35=8|34=3|49=FOXBIT|52=20260508-12:00:01.100|56=ACME|37=1928374651|17=1928374651-1|11=order-2026-05-08-001|150=0|39=0|55=btcbrl|54=1|38=0.00350000|44=350000.00|14=0|151=0.00350000|6=0|10=097|"Emitted on every fill, partial or full. LastQty (32) and LastPx (31) carry the fill, while CumQty (14) and LeavesQty (151) carry the running totals. OrdStatus is 1 Partially filled or 2 Filled depending on whether LeavesQty reaches zero.
| 6 | string AvgPx — average fill price across all trades, decimal string. |
| 14 | string CumQty — cumulative filled quantity across all trades. |
| 17 | string ExecID — unique identifier for this fill. |
| 31 | string LastPx — price of this fill, decimal string. |
| 32 | string LastQty — quantity filled by this trade, decimal string. |
| 35 | string Value: "8" |
| 37 | string OrderID — server-side order identifier. |
| 39 | string Enum: "1" "2" OrdStatus — |
| 150 | string ExecType — Value: "F" |
| 151 | string LeavesQty — remaining open quantity. |
| 381 | string GrossTradeAmt — |
"8=FIX.4.4|9=232|35=8|34=4|49=FOXBIT|52=20260508-12:00:02.000|56=ACME|37=1928374651|17=1928374651-2|11=order-2026-05-08-001|150=F|39=1|55=btcbrl|54=1|32=0.00100000|31=350000.00|381=350.00000000|14=0.00100000|151=0.00250000|6=350000.00|10=104|"Emitted when the order is canceled, by user request, by the engine (e.g. unfilled remainder of an IOC) or by external constraints.
OrdRejReason (103) is populated only when the cancellation was driven by an engine-side condition (no liquidity, price out of range, etc.); user-initiated cancels do not carry tag 103.
| 6 | string AvgPx — average fill price across any prior fills. |
| 14 | string CumQty — quantity already filled before cancellation. |
| 17 | string |
| 35 | string Value: "8" |
| 37 | string |
| 39 | string OrdStatus — Value: "4" |
| 103 | integer Enum: 30 32 99 OrdRejReason — present only when the cancellation was driven by an
engine-side condition. A self-trade prevention cancellation reports
|
| 150 | string ExecType — Value: "4" |
| 151 | string LeavesQty — always Value: "0" |
"8=FIX.4.4|9=176|35=8|34=5|49=FOXBIT|52=20260508-12:00:03.000|56=ACME|37=1928374651|17=1928374651-3|11=order-2026-05-08-001|150=4|39=4|55=btcbrl|54=1|14=0.00100000|151=0|6=350000.00|10=176|"Emitted when the order cannot be accepted. The same ExecType=8 Rejected covers synchronous rejections (validation failures, rate-limit denial, insufficient funds) and asynchronous rejections raised by the matching engine after the initial accept.
OrdRejReason (103) is mapped from the underlying error code; Text (58) carries a human-readable reason. See the table below for the supported OrdRejReason values.
| OrdRejReason (103) | Meaning | When |
|---|---|---|
1 Unknown symbol |
The market in Symbol (55) does not exist. |
Sync reject. |
2 Exchange closed |
Trading on the requested side or market is currently disabled. | Sync reject. |
3 Order exceeds limit |
Insufficient funds, too many open orders or rate-limit denial. | Sync reject. |
30 Last look |
Limit price is outside the protective band; the order would have crossed at an off-market price. | Sync or async reject; also async cancel. |
32 No liquidity |
IOC with nothing to match, FOK with insufficient resting volume, or insufficient remaining size on the book. |
Async cancel for IOC/FOK; sync reject for "market not deep enough". |
99 Other |
Catch-all for any reason not represented above. | Any reject path. |
| 17 | string |
| 35 | string Value: "8" |
| 37 | string OrderID — server-side order identifier. |
| 39 | string OrdStatus — Value: "8" |
| 58 | string Text — human-readable rejection reason. |
| 103 | integer Enum: 1 2 3 30 32 99 OrdRejReason — see the ExecutionReport
section for the full code table. Defaults to |
| 150 | string ExecType — Value: "8" |
"8=FIX.4.4|9=160|35=8|34=3|49=FOXBIT|52=20260508-12:00:01.100|56=ACME|37=0|17=rej-20260508-001|11=order-2026-05-08-001|150=8|39=8|103=1|58=invalid symbol|10=088|"Fetches the current state of a single, already-submitted order on demand. Use it to reconcile an order whenever needed — for example after a reconnect, or when an expected ExecutionReport was missed. It queries live order state directly and does not replay the order's past execution events.
The order is located by one of two lookup keys, at least one of which must be present:
OrderID (37): the numeric exchange id assigned on order creation
(echoed on every ExecutionReport). Primary lookup key.ClOrdID (11): the client-supplied order identifier.When both are supplied both filters are applied. OrdStatusReqID (790) is
optional and echoed on the response for correlation.
| 11 | string ClOrdID — the client-supplied order identifier. Used as a lookup key
when |
| 35 required | string MsgType — Value: "H" |
| 37 | string OrderID — the numeric exchange id assigned on order creation and
echoes on every |
| 54 | string Enum: "1" "2" Side — |
| 55 | string Symbol — market symbol. Not a lookup key; echoed back on a rejected
|
| 790 | string OrdStatusReqID — optional client-side request identifier. Echoed on the response (both the status report and any rejection) for correlation. |
"8=FIX.4.4|9=140|35=H|34=2|49=ACME|52=20260508-12:05:00.000|56=FOXBIT|37=1928374651|11=order-2026-05-08-001|54=1|55=btcbrl|790=STAT-1|10=207|"The order is returned as a single ExecutionReport (35=8) carrying
ExecType=I Order Status — distinct from the ExecType values used by the
execution events pushed as the order works. OrdStatus (39) reflects the
order's current state; OrderQty (38), CumQty (14) and LeavesQty (151)
carry the original, filled and remaining quantities.
| 6 | string AvgPx — average fill price, decimal string. |
| 11 | string ClOrdID — the order's client identifier. Present only when the order has one. |
| 14 | string CumQty — cumulative filled quantity, decimal string. |
| 17 | string ExecID — always Value: "0" |
| 35 | string MsgType — Value: "8" |
| 37 | string OrderID — server-side order id. |
| 38 | string OrderQty — original requested quantity, decimal string. |
| 39 | string Enum: "0" "1" "2" "4" "6" OrdStatus — the order's current state:
|
| 40 | string Enum: "1" "2" "3" "4" OrdType — |
| 44 | string Price — limit price, decimal string. Omitted for orders with no price (e.g. market orders). |
| 54 | string Enum: "1" "2" Side — |
| 55 | string Symbol — the order's market. |
| 59 | string Enum: "1" "3" "4" TimeInForce — |
| 60 | string TransactTime — the order's last-update time in
|
| 99 | string StopPx — stop trigger price, decimal string. Present only when the order carries one. |
| 150 | string ExecType — Value: "I" |
| 151 | string LeavesQty — remaining open quantity, decimal string. |
| 790 | string OrdStatusReqID — echoes |
"8=FIX.4.4|9=252|35=8|34=5|49=FOXBIT|52=20260508-12:05:00.100|56=ACME|37=1928374651|17=0|150=I|39=1|55=btcbrl|54=1|40=2|38=0.00350000|44=350000.00|14=0.00100000|151=0.00250000|6=350000.00|59=3|11=order-2026-05-08-001|60=20260508-12:04:59.000|790=STAT-1|10=131|"Failures are reported as a rejected ExecutionReport (35=8) with
ExecType=8 Rejected, OrdStatus=8 Rejected and the reason in Text (58),
echoing the request identifiers so the rejection stays correlated:
Text=order not found.Text=not authenticated / Text=authentication revoked.Text=internal error.Text=Request limit exceeded. Try again later..A message carrying neither ClOrdID (11) nor OrderID (37) is rejected at
the protocol level with Reject (35=3), since there is no identifier to
echo on an ExecutionReport.
| 6 | string AvgPx — always Value: "0" |
| 11 | string ClOrdID — echoed when the request carried one. |
| 14 | string CumQty — always Value: "0" |
| 17 | string ExecID — always Value: "0" |
| 35 | string Value: "8" |
| 37 | string OrderID — echoes |
| 39 | string OrdStatus — Value: "8" |
| 40 | string OrdType — Value: "2" |
| 54 | string Enum: "1" "2" Side — echoes |
| 55 | string Symbol — echoed when the request carried one. |
| 58 | string Text — human-readable rejection reason. |
| 150 | string ExecType — Value: "8" |
| 151 | string LeavesQty — always Value: "0" |
| 790 | string OrdStatusReqID — echoed when the request carried one. |
"8=FIX.4.4|9=176|35=8|34=5|49=FOXBIT|52=20260508-12:05:00.100|56=ACME|37=0|17=0|150=8|39=8|54=1|40=2|14=0|151=0|6=0|58=order not found|11=order-2026-05-08-001|790=STAT-1|10=095|"Lists every tradeable market exposed on the API. Useful at session start to discover symbols, currencies and tick / lot sizes.
Only SecurityListRequestType=0 All Securities is supported. Other values are answered with SecurityList (35=y) carrying SecurityRequestResult=4 Invalid or unsupported request.
| 35 required | string MsgType — Value: "x" |
| 320 required | string SecurityReqID — client-side request identifier. Echoed on the
|
| 559 required | string SecurityListRequestType — only Value: "0" |
"8=FIX.4.4|9=098|35=x|34=3|49=ACME|52=20260508-12:00:04.000|56=FOXBIT|320=sec-list-1|559=0|10=192|"A successful request returns a single SecurityList (35=y) with SecurityRequestResult=0 Valid request and one NoRelatedSym block per market. Each block contains the symbol, currency, minimum tradeable volume and price/volume increments.
| 15 | string Currency — quote currency code. |
| 35 | string MsgType — Value: "y" |
| 55 | string Symbol — market symbol. |
| 107 | string SecurityDesc — human-readable market name. |
| 146 | integer NoRelatedSym — number of market blocks that follow. |
| 167 | string SecurityType — instrument classification. Value: "FXSPOT" |
| 320 | string SecurityReqID — echoes the original |
| 322 | string SecurityResponseID — server-side identifier for this response. Useful for correlating with operational telemetry. |
| 461 | string CFICode — ISO 10962 classification. Value: "MRCXXX" |
| 560 | integer SecurityRequestResult — |
| 561 | string RoundLot — minimum volume increment, decimal string. Orders must carry a quantity that is a multiple of this lot size. |
| 562 | string MinTradeVol — minimum tradeable volume in base asset, decimal string. |
| 969 | string MinPriceIncrement — minimum price tick, decimal string. Orders must be priced as a multiple of this increment. |
"8=FIX.4.4|9=276|35=y|34=4|49=FOXBIT|52=20260508-12:00:04.100|56=ACME|320=sec-list-1|322=resp-2026-05-08-001|560=0|146=1|55=btcbrl|167=FXSPOT|461=MRCXXX|107=Bitcoin / Real|15=BRL|562=0.00001000|969=0.01|561=0.00000001|10=170|"Failure modes:
SecurityListRequestType → SecurityRequestResult=4 Invalid or unsupported request.SecurityRequestResult=2 Instrument data temporarily unavailable.SecurityRequestResult=1 No instruments found that match selection criteria.SecurityRequestResult=4 with Text=Request limit exceeded. Try again later..| 35 | string Value: "y" |
| 58 | string Text — optional human-readable hint. |
| 320 | string SecurityReqID — echoes the original request. |
| 560 | integer Enum: 1 2 4 SecurityRequestResult:
|
"8=FIX.4.4|9=132|35=y|34=4|49=FOXBIT|52=20260508-12:00:04.100|56=ACME|320=sec-list-1|560=4|58=Request limit exceeded. Try again later.|10=088|"Subscribes or unsubscribes the session to a level-2 order-book stream. Subscriptions are scoped to the session that issued the request; closing the session terminates all of its subscriptions automatically.
SubscriptionRequestType (263) selects the operation:
0 Snapshot: one-shot full book.1 Snapshot + Updates: initial full book followed by incremental updates.2 Disable previous snapshot + updates: unsubscribe a previously requested stream identified by MDReqID (262).MDUpdateType (265) must be 1 Incremental refresh when subscribing with updates. 0 Full refresh is not supported on the stream and is rejected.
| 35 required | string MsgType — Value: "V" |
| 55 required | string Symbol — repeating, one per |
| 146 required | integer NoRelatedSym — number of symbols that follow. |
| 262 required | string MDReqID — client-side request identifier. Echoed on every response (snapshot, incremental, reject) bound to this request. Required on unsubscribe to identify the stream being closed. |
| 263 required | string Enum: "0" "1" "2" SubscriptionRequestType:
|
| 264 | integer MarketDepth — maximum number of price levels per side. Use |
| 265 | string MDUpdateType — only Value: "1" |
| 267 required | integer NoMDEntryTypes — number of |
| 269 required | Array of strings Items Enum: "0" "1" MDEntryType (repeating) — |
"8=FIX.4.4|9=144|35=V|34=4|49=ACME|52=20260508-12:00:05.000|56=FOXBIT|262=req-btcbrl-1|263=1|264=50|265=1|267=2|269=0|269=1|146=1|55=btcbrl|10=017|"The first response is always a MarketDataSnapshotFullRefresh (35=W). On SubscriptionRequestType=1, subsequent updates are streamed as MarketDataIncrementalRefresh (35=X).
A MarketDataRequestReject (35=Y) is emitted on any of the following:
MDReqID or SubscriptionRequestType.NoRelatedSym.MDUpdateType (i.e. 0 Full refresh).SubscriptionRequestType value.MDReqID that the session never opened.See the MarketDataRequestReject section for the response schema.
Carries the full state of a level-2 order book at a point in time. Sent once on subscription and as the first message after SubscriptionRequestType=0 Snapshot only requests.
Each MDEntry describes one price level on either the bid or the ask side. MDEntryPositionNo (290) is the depth rank within the side, starting at 1.
| 35 | string MsgType — Value: "W" |
| 55 | string Symbol — market symbol of this snapshot. |
| 262 | string MDReqID — echoes the original |
| 268 | integer NoMDEntries — number of |
| 269 | string Enum: "0" "1" MDEntryType per entry — |
| 270 | string MDEntryPx — price of this entry, decimal string. |
| 271 | string MDEntrySize — quantity available at this price level, decimal string. |
| 290 | integer MDEntryPositionNo — depth rank of this entry within its side,
starting at |
"8=FIX.4.4|9=204|35=W|34=5|49=FOXBIT|52=20260508-12:00:05.100|56=ACME|262=req-btcbrl-1|55=btcbrl|268=2|269=0|270=350000.00|271=0.00350000|290=1|269=1|270=350100.00|271=0.00250000|290=1|10=212|"Streams individual book updates after the initial MarketDataSnapshotFullRefresh. Sent only when subscribing with SubscriptionRequestType=1 Snapshot + Updates.
Each MDEntry carries an MDUpdateAction (279) describing the operation to apply to the local book:
0 New: new price level.1 Change: quantity update at an existing level.2 Delete: level removed from the book.The recipient is expected to apply each entry in order to the local book mirror keyed by (Symbol, MDEntryType, MDEntryPx).
| 35 | string MsgType — Value: "X" |
| 55 | string Symbol — market of this update. Carried on the message body, not
repeated per |
| 262 | string MDReqID — echoes the original |
| 268 | integer NoMDEntries — number of |
| 269 | string Enum: "0" "1" MDEntryType per entry — |
| 270 | string MDEntryPx — price of this entry, decimal string. The book key
along with |
| 271 | string MDEntrySize — new quantity at this price level, decimal string.
|
| 279 | string Enum: "0" "1" "2" MDUpdateAction per entry:
|
"8=FIX.4.4|9=140|35=X|34=6|49=FOXBIT|52=20260508-12:00:06.000|56=ACME|262=req-btcbrl-1|55=btcbrl|268=1|279=1|269=0|270=350100.00|271=0.00500000|10=041|"Sent in response to a MarketDataRequest (35=V) that cannot be served. The original request is identified by echoing MDReqID (262).
The textual reason is delivered in Text (58); MDReqRejReason (281) is not used on this version of the API.
| 35 | string MsgType — Value: "Y" |
| 58 | string Text — human-readable rejection reason. |
| 262 | string MDReqID — echoes the original |
"8=FIX.4.4|9=108|35=Y|34=5|49=FOXBIT|52=20260508-12:00:05.100|56=ACME|262=req-btcbrl-1|58=no symbols specified|10=246|"Requests a snapshot of the authenticated member's account balances. Balances are exposed through the FIX position family: each currency the member holds maps to one position entry whose LongQty (704) is the available (spendable) balance.
PosReqType (724) must be 0 Positions. SubscriptionRequestType (263) selects 0 Snapshot or 1 Snapshot + Updates; on this version both are served as a one-shot snapshot (continuous push is a future milestone). An optional Currency (15) restricts the snapshot to a single ISO-4217 asset (matched case-insensitively).
| 1 | string Account — optional. Read when present; balances are always scoped to the authenticated member regardless of this value. |
| 15 | string Currency — optional ISO-4217 code. When set, only the matching currency is reported (matched case-insensitively). Omit to receive every currency the member holds. |
| 35 required | string MsgType — Value: "AN" |
| 263 | string Enum: "0" "1" SubscriptionRequestType:
Any other value (e.g. |
| 710 required | string PosReqID — client-side request identifier. Echoed on the |
| 724 required | string PosReqType — only Value: "0" |
"8=FIX.4.4|9=120|35=AN|34=2|49=ACME|52=20260617-12:00:00.000|56=FOXBIT|710=POS-1|724=0|263=1|15=BTC|10=051|"The request is acknowledged with a RequestForPositionsAck (35=AO) carrying PosReqResult=0 Valid request, followed by one PositionReport (35=AP) per currency. A valid request that matches no currency yields the accepted AO and zero PositionReport messages — an empty snapshot is not an error.
A RequestForPositionsAck (35=AO) with PosReqStatus=2 Rejected is emitted on:
PosReqType (anything other than 0 Positions) or SubscriptionRequestType (e.g. 2 Disable) → PosReqResult=1 Invalid or unsupported request.PosReqResult=3 Not authorized to request positions.PosReqResult=99 Other (retryable).A malformed message missing PosReqID (710) or PosReqType (724) is rejected at the protocol level with Reject (35=3).
Acknowledges a RequestForPositions (35=AN). On success it precedes the PositionReport (35=AP) sequence; on failure it carries the rejection reason in Text (58) and no reports follow. The original request is identified by echoing PosReqID (710).
PosReqResult (728) distinguishes the outcome: 0 valid, 1 invalid/unsupported, 3 not authorized, 99 other (including rate-limit denial). PosReqStatus (729) is 0 Completed when accepted and 2 Rejected otherwise.
| 35 required | string MsgType — Value: "AO" |
| 58 | string Text — human-readable reason. Present only on rejection. |
| 710 required | string PosReqID — echoes the original |
| 721 required | string PosMaintRptID — server-assigned id, unique per emitted ack. |
| 728 required | string Enum: "0" "1" "3" "99" PosReqResult:
|
| 729 required | string Enum: "0" "2" PosReqStatus:
|
"8=FIX.4.4|9=110|35=AO|34=3|49=FOXBIT|52=20260617-12:00:00.100|56=ACME|721=a1b2c3d4|710=POS-1|728=0|729=0|10=098|"Carries the balance for a single currency. One message is sent per currency in the snapshot, after the optional Currency (15) filter on the request.
The balance is LongQty (704) inside the NoPositions (702) group — always exactly one entry — with PosType (703)=POS. Currency (15) identifies the asset and TotalNumPosReports (727) is the number of reports in the snapshot, so the client knows when the sequence is complete.
| 15 required | string Currency — ISO-4217 code of this position (uppercase). |
| 35 required | string MsgType — Value: "AP" |
| 60 required | string TransactTime — time the report was generated (UTC). |
| 702 required | integer NoPositions — number of position entries; always Value: 1 |
| 703 required | string PosType — Value: "POS" |
| 704 required | string LongQty — the balance: the available (spendable) amount for this currency, as a precision-preserved decimal string. |
| 710 required | string PosReqID — echoes the original |
| 721 required | string PosMaintRptID — server-assigned id, unique per emitted report. |
| 724 required | string PosReqType — Value: "0" |
| 727 required | integer TotalNumPosReports — total number of |
| 728 required | string PosReqResult — Value: "0" |
"8=FIX.4.4|9=180|35=AP|34=4|49=FOXBIT|52=20260617-12:00:00.110|56=ACME|721=e5f6a7b8|710=POS-1|724=0|727=2|728=0|15=BTC|702=1|703=POS|704=1.25000000|60=20260617-12:00:00.110|10=201|"Requests a point-in-time snapshot of the authenticated member's trades
(fills). Use it to reconcile fills — for example after a reconnect, or when
an expected fill ExecutionReport was missed. It
reads current trade state on demand and does not stream: live fills
continue to arrive on the asynchronous ExecutionReport path.
A request must be scoped in one of two ways.
By order. One of two lookup keys:
OrderID (37): the numeric exchange id assigned on order creation
(echoed on every ExecutionReport). Primary lookup key.ClOrdID (11): the client-supplied order identifier, resolved to the
numeric order id first.OrderID (37) takes precedence when both are supplied (ClOrdID is then
ignored).
By time window. A NoDates (580) group carrying one or two entries:
the first entry's TransactTime (60) opens the window, the second closes
it. Omit the second entry to run the window up to the moment the request is
received. Both bounds are inclusive, evaluated to whole-second precision
and rounded outwards, so the window served is never narrower than the one
requested.
Both bounds are UTC, as FIX defines TransactTime (60). A local
wall-clock time sent in its place shifts the window by the offset and
silently reconciles the wrong period; where the shift puts the whole window
ahead of the current time the request is rejected rather than answered with
an empty snapshot.
Every NoDates (580) entry must begin with TradeDate (75), the
YYYYMMDD date of that entry's bound. It is the group delimiter: an entry
beginning with TransactTime (60) is not recognized as an entry, and the
request is rejected.
A window is how fills missed during a disconnect are recovered. Sequence
numbers reset on every logon, so a session-level ResendRequest cannot
replay the ExecutionReports sent while the session was down.
A window may span at most 24 hours and match at most 1000 trades. Exceeding either is a rejection, not a truncated snapshot — a snapshot that arrives is always complete. Narrow the window and retry.
Symbol (55) is not a supported filter on this message, and
TradeRequestType (569) must be 1 Matched trades matching criteria provided on request. Only a snapshot is served
(SubscriptionRequestType (263) = 0 or omitted).
| 11 | string ClOrdID — the client-supplied order identifier. Used as a lookup key
only when |
| 35 required | string MsgType — Value: "AD" |
| 37 | string OrderID — the numeric exchange id assigned on order creation and
echoes on every |
| 60 | string TransactTime — the bound itself, The value is UTC, not local time: a window whose start lands ahead of the current time can hold no trade and is rejected rather than answered with an empty snapshot. |
| 75 | string TradeDate — the |
| 263 | string SubscriptionRequestType — Value: "0" |
| 568 required | string TradeRequestID — client-side request identifier. Echoed on the |
| 569 required | string TradeRequestType — only Value: "1" |
| 580 | integer Enum: 1 2 NoDates — number of entries in the time-window group: |
"8=FIX.4.4|9=126|35=AD|34=2|49=ACME|52=20260708-12:00:00.000|56=FOXBIT|568=TRD-1|569=1|263=0|37=1928374651|10=017|"The request is acknowledged with a TradeCaptureReportRequestAck (35=AQ)
carrying TradeRequestResult=0 Successful and TotNumTradeReports (748),
followed by one TradeCaptureReport (35=AE) per
trade, in ascending time order. Each report echoes TradeRequestID (568)
and carries the same TotNumTradeReports (748); the final one is marked
with LastRptRequested (912)=Y. A request that matches no trade yields the
accepted AQ with TotNumTradeReports=0 and no reports — an empty
snapshot is not an error.
A TradeCaptureReportRequestAck (35=AQ) with TradeRequestStatus=2 Rejected
is emitted on:
TradeRequestType (anything other than 1) →
TradeRequestResult=8.TradeRequestResult=9.SubscriptionRequestType; a request carrying neither an
order key nor a time window; a window that ends before it starts, starts
in the future, spans more than 24 hours, or matches more than 1000
trades; a backend or transport error; or rate-limit denial →
TradeRequestResult=99.A malformed message missing TradeRequestID (568) or
TradeRequestType (569), or carrying a NoDates (580) group that is not
encoded as described above, is rejected at the protocol level with
Reject (35=3), so is a group whose TransactTime (60) is not a usable
bound.
Acknowledges a TradeCaptureReportRequest (35=AD). On success it precedes
the TradeCaptureReport (35=AE) sequence and states the count in
TotNumTradeReports (748); on failure it carries the rejection reason in
Text (58) and no reports follow. The original request is identified by
echoing TradeRequestID (568).
TradeRequestResult (749) distinguishes the outcome: 0 successful, 8
trade request type not supported, 9 not authorized, 99 other
(including rate-limit denial). TradeRequestStatus (750) is 1 Completed
when accepted and 2 Rejected otherwise.
| 35 required | string MsgType — Value: "AQ" |
| 568 required | string TradeRequestID — echoes the original |
| 569 required | string TradeRequestType — echoes the request value ( Value: "1" |
| 748 required | integer TotNumTradeReports — number of |
| 749 required | string TradeRequestResult — Value: "0" |
| 750 required | string TradeRequestStatus — Value: "1" |
"8=FIX.4.4|9=90|35=AQ|34=3|49=FOXBIT|52=20260708-12:00:00.100|56=ACME|568=TRD-1|569=1|749=0|750=1|748=2|10=045|"On rejection the same AQ carries TradeRequestStatus=2 Rejected,
TotNumTradeReports=0 and the reason in Text (58); no
TradeCaptureReport messages follow.
| 35 required | string Value: "AQ" |
| 58 required | string Text — human-readable rejection reason. |
| 568 required | string TradeRequestID — echoes the request identifier. |
| 569 required | string TradeRequestType — echoes the request value. |
| 748 required | integer TotNumTradeReports — always |
| 749 required | string Enum: "8" "9" "99" TradeRequestResult — classifies the rejection:
|
| 750 required | string TradeRequestStatus — Value: "2" |
"8=FIX.4.4|9=136|35=AQ|34=3|49=FOXBIT|52=20260708-12:00:00.100|56=ACME|568=TRD-1|569=1|749=99|750=2|748=0|58=at least one of OrderID(37) or ClOrdID(11) tags is required|10=228|"Carries a single member trade (fill). One message is sent per trade in the
snapshot, after the TradeCaptureReportRequestAck (35=AQ) that states the
total count.
The member's own side is the single NoSides (552) entry, carrying
Side (54) and OrderID (37). A non-zero fee is reported on that entry as
Commission (12) with CommType (13)=3 Absolute and CommCurrency (479).
| 12 | string Commission — the fee charged on this trade, decimal string. Present
only when the fee is non-zero. Lives on the |
| 13 | string CommType — Value: "3" |
| 17 required | string ExecID — a stable identifier derived from the trade id. |
| 31 required | string LastPx — price of this fill, decimal string. |
| 32 required | string LastQty — quantity filled by this trade, decimal string. |
| 35 required | string MsgType — Value: "AE" |
| 37 required | string OrderID — the member's order id for this trade. |
| 54 required | string Enum: "1" "2" Side — the member's side on the trade. |
| 55 required | string Symbol — the trade's market. |
| 60 required | string TransactTime — the trade time in |
| 75 required | string TradeDate — the trade date in |
| 479 | string CommCurrency — ISO-4217 code of the fee currency (lowercase). Present only when a non-zero fee carries a currency. |
| 552 required | integer NoSides — number of side entries; always Value: 1 |
| 568 required | string TradeRequestID — echoes the identifier from the
|
| 570 required | string PreviouslyReported — always Value: "N" |
| 571 required | string TradeReportID — the trade's sequence number, unique per trade. |
| 748 required | integer TotNumTradeReports — the number of reports in this snapshot, the same
count carried by the preceding |
| 851 | string Enum: "1" "2" LastLiquidityInd — the member's liquidity role, present only when
known: |
| 912 | string LastRptRequested — Value: "Y" |
"8=FIX.4.4|9=196|35=AE|34=4|49=FOXBIT|52=20260708-12:00:00.110|56=ACME|571=778899|570=N|568=TRD-1|748=3|912=Y|17=a1b2c3d4e5f6a7b8|55=btcbrl|851=2|32=0.00100000|31=350000.00|75=20260708|60=20260708-11:59:58.000|552=1|54=1|37=1928374651|12=0.35000000|13=3|479=brl|10=011|"