Foxbit FIX API (1.0)

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.

Introduction

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.

Features

  • Persistent FIX v4.4 session with HMAC-SHA256 authenticated Logon.
  • Order entry with synchronous accept/reject and asynchronous fill / cancel / reject events.
  • Real-time order book streaming via snapshot + incremental refresh.
  • Reference-data discovery for tradeable instruments.

Wire-Format Notation

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.

Need More?

If you don't find something here, check our other API documentation:

See all available APIs

Transport & TLS

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).

Requirements

  • TLS version: 1.2 or 1.3. Earlier versions (SSL 3.0, TLS 1.0, TLS 1.1) are refused.
  • Authentication: server-side TLS only. Clients verify the server certificate during the handshake; no client certificate is requested. Session-level authentication is performed at Logon (35=A), see the Authentication section.

Obtaining the Server Certificate

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.

Rate Limit

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

Behaviour on rejection

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.

Market-data subscription limit

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.

Authentication

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

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.

Signature Construction

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()

Time Synchronization

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.

  1. Open the TCP connection to the FIX endpoint.
  2. Send Logon (35=A) with Username, RawData, RawDataLength, SendingTime and MsgSeqNum.
  3. Wait for the inbound Logon echo before sending application messages.
  4. On any Logout (35=5) carrying Text, treat the session as terminated and inspect the reason before reconnecting.

Logon (35=A)

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.

Message Payload

8
required
string

BeginString — protocol version. Must be FIX.4.4.

Value: "FIX.4.4"
34
required
integer

MsgSeqNum — message sequence number, also part of the HMAC prehash.

35
required
string

MsgType — A for Logon.

Value: "A"
49
required
string

SenderCompID — your client identifier (assigned by Foxbit).

52
required
string

SendingTime — current UTC timestamp in YYYYMMDD-HH:MM:SS.sss format. Part of the HMAC prehash; must be unique per Logon attempt.

56
required
string

TargetCompID — the server identifier. Must be FOXBIT.

Value: "FOXBIT"
95
required
integer

RawDataLength — byte length of the Base64-encoded signature in RawData (96).

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 0.

108
required
integer

HeartBtInt — heartbeat interval in seconds. Recommended 30.

141
string
Default: "N"
Enum: "Y" "N"

ResetSeqNumFlag — request a sequence-number reset for this session. Set to Y after a long disconnect or whenever the local sequence counter is out of sync.

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|"

Success

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 — A for Logon.

Value: "A"
49
string

SenderCompID — FOXBIT.

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|"

Invalid

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:

  • Incorrect API key, secret or signature concatenation.
  • Client clock skew beyond the allowed window.
  • API key without the trade role.
  • Source IP not on the API key's trusted-IP list.
35
string
Enum: "5" "j"

MsgType — 5 for Logout, j for BusinessMessageReject.

58
string

Text — generic reason. Always "could not process logon" on the Logout path; "invalid signature" on the BusinessMessageReject path.

371
integer

RefTagID (only on 35=j) — 96 (RawData), the tag whose value failed verification.

Value: 96
380
integer

BusinessRejectReason (only on 35=j) — 5 Conditionally required field missing.

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|"

NewOrderSingle (35=D)

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.

Message Payload

11
string

ClOrdID — client-side unique order identifier. Optional but strongly recommended for client-side reconciliation; echoed back on every ExecutionReport for the order.

18
string

ExecInst — order handling instruction. Only 6 Participate don't initiate (post-only) is supported; any other value is rejected with ValueIsIncorrect (tag=18). The tag accepts several space-delimited instructions, but 6 must be among them.

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 ExecutionReport with ExecType (150) = 4 Canceled and OrdRejReason (103) = 99 Other, distinguishable from other cancellations by that combination.

Post-only requires OrdType (40) = 2 Limit and, when TimeInForce (59) is supplied, 1 GTC — the instruction is contradictory with IOC or FOK, which are rejected with ValueIsIncorrect (tag=59).

Value: "6"
35
required
string

MsgType — D for NewOrderSingle.

Value: "D"
38
string

OrderQty — base-asset quantity, decimal string. Either OrderQty (38) or CashOrderQty (152) should be supplied; supplying both is allowed but only one is honoured by the matching engine.

40
required
string

OrdType — order type. Only 2 Limit is supported on this version of the API.

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 — 1 Buy, 2 Sell.

55
required
string

Symbol — market symbol. Case-insensitive on input; the server lowercases it before forwarding.

59
string
Enum: "1" "3" "4"

TimeInForce — only IOC (3 Immediate Or Cancel), FOK (4 Fill Or Kill) and GTC (1 Good Till Cancel) are accepted. Any other value is rejected with ValueIsIncorrect (tag=59) at the protocol level. When omitted, the order defaults to GTC.

A GTC order rests on the book until explicitly canceled with an OrderCancelRequest (35=F).

60
required
string

TransactTime — UTC timestamp at which the client generated the order, in YYYYMMDD-HH:MM:SS.sss format.

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.

Value Behavior on a self-match
EXPIRE_BOTH Cancels both the incoming and the resting order
EXPIRE_MAKER Cancels the resting order; the incoming order continues
EXPIRE_TAKER Cancels the incoming order; the resting order stays
DECREMENT Reduces both orders by the overlapping quantity

Values are case-insensitive. Any other value is rejected with ValueIsIncorrect (tag=20200) at the protocol level, and the order is not submitted. When supplied, the value is echoed on the resulting ExecutionReport (35=8).

Applies to book orders only. On a quote execution (a 35=D carrying QuoteID (117)) the tag is ignored and not echoed.

When the rule cancels an order, that order is reported on an ExecutionReport (35=8) with ExecType=4 Canceled / OrdStatus=4 Canceled and OrdRejReason (103) = 99 Other — a cancellation, not a rejection. Tag 103 alone does not distinguish a self-match from other engine-side cancellations that also map to 99.

"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|"

Response

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.

OrderCancelRequest (35=F)

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.

Message Payload

11
required
string

ClOrdID — the client-assigned identifier of this cancel request. Required. Echoed on the ExecutionReport and on any OrderCancelReject.

35
required
string

MsgType — F for OrderCancelRequest.

Value: "F"
37
string

OrderID — the numeric exchange id assigned on order creation and echoes on every ExecutionReport (cancel-by-OrderID). Lookup key and the preferred one; optional if OrigClOrdID (41) is supplied.

41
string

OrigClOrdID — the client order id of the order being canceled (cancel-by-ClientOrderID): the same ClOrdID (11) value sent when the order was created. Lookup key; optional if OrderID (37) is supplied.

54
string
Enum: "1" "2"

Side — 1 Buy, 2 Sell. Not a lookup key; echoed back on the response.

55
string

Symbol — market symbol. Not a lookup key; echoed back.

60
string

TransactTime — request time, YYYYMMDD-HH:MM:SS.sss.

"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|"

Success

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 — 0 on the PendingCancel ack.

Value: "0"
11
string

ClOrdID — echoes the cancel request's ClOrdID (11).

14
string

CumQty — 0 on the PendingCancel ack (the terminal Canceled carries the final value).

Value: "0"
17
string

ExecID — unique execution id for this report.

35
string

MsgType — 8 for ExecutionReport.

Value: "8"
37
string

OrderID — the resolved numeric exchange id.

39
string

OrdStatus — 6 Pending Cancel.

Value: "6"
41
string

OrigClOrdID — echoes the request's OrigClOrdID (41) when supplied.

54
string
Enum: "1" "2"

Side — 1 Buy, 2 Sell.

55
string

Symbol — the order's market.

60
string

TransactTime — YYYYMMDD-HH:MM:SS.sss.

150
string

ExecType — 6 Pending Cancel.

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|"

Invalid

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):

  • Unknown order → 102=1, Text=order not found.
  • Already executed / already canceled → 102=0 Too late, Text=order already executed / Text=order already canceled.
  • Already pending cancel → 102=3, Text=order already pending cancel.
  • Not authenticated, backend failure, or rate-limit denial → 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 ClOrdID (11).

35
string

MsgType — 9 for OrderCancelReject.

Value: "9"
37
string

OrderID — resolved exchange id, or 0 when the order was not found.

39
string
Enum: "2" "4" "6" "8"

OrdStatus — the order's current status:

  • 8 Rejected (unknown order / internal)
  • 2 Filled (already executed)
  • 4 Canceled (already canceled)
  • 6 Pending Cancel (already pending cancel)
41
string

OrigClOrdID — echoes the request's OrigClOrdID (41).

58
string

Text — human-readable rejection reason.

60
string

TransactTime — YYYYMMDD-HH:MM:SS.sss.

102
string
Enum: "0" "1" "3" "99"

CxlRejReason — 0 Too late, 1 Unknown order, 3 Already pending cancel, 99 Other.

434
string

CxlRejResponseTo — 1 Order Cancel Request.

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 (35=8)

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.

New

Sent immediately after the matching engine accepts the order; the order is now live on the book.

6
string

AvgPx — average fill price. 0 for a fresh accept.

Value: "0"
11
string

ClOrdID — echoes the client-supplied identifier from the original NewOrderSingle (35=D). Empty when the client did not supply one.

14
string

CumQty — cumulative filled quantity. 0 for a fresh accept.

Value: "0"
17
string

ExecID — unique identifier for this execution event.

35
string

MsgType — 8 for ExecutionReport.

Value: "8"
37
string

OrderID — server-side unique order identifier.

38
string

OrderQty — original requested quantity, decimal string.

39
string

OrdStatus — 0 New.

Value: "0"
44
string

Price — original limit price, decimal string.

54
string
Enum: "1" "2"

Side — 1 Buy, 2 Sell.

55
string

Symbol — echoes the market.

150
string

ExecType — 0 New.

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 NewOrderSingle (35=D). Absent when the order carried no tag 20200, in which case the account's configured default applies.

"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|"

Trade (Fill)

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 — 1 Partially filled while LeavesQty > 0, 2 Filled when the order is fully matched.

150
string

ExecType — F Trade.

Value: "F"
151
string

LeavesQty — remaining open quantity.

381
string

GrossTradeAmt — LastQty * LastPx, decimal string.

"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|"

Canceled

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 — 4 Canceled.

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 99 Other; see SelfTradePrevention (20200) on NewOrderSingle (35=D). See the ExecutionReport section for the full code table.

150
string

ExecType — 4 Canceled.

Value: "4"
151
string

LeavesQty — always 0 after cancel.

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|"

Rejected

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. 0 on synchronous transport or authentication failures where no exchange-side identifier is available.

39
string

OrdStatus — 8 Rejected.

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 99 Other when no dedicated mapping exists for the underlying cause.

150
string

ExecType — 8 Rejected.

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|"

OrderStatusRequest (35=H)

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.

Message Payload

11
string

ClOrdID — the client-supplied order identifier. Used as a lookup key when OrderID (37) is absent. Optional if OrderID (37) is supplied.

35
required
string

MsgType — H for OrderStatusRequest.

Value: "H"
37
string

OrderID — the numeric exchange id assigned on order creation and echoes on every ExecutionReport. Primary lookup key. Optional if ClOrdID (11) is supplied.

54
string
Enum: "1" "2"

Side — 1 Buy, 2 Sell. Not a lookup key; echoed back on a rejected ExecutionReport so the rejection stays correlatable.

55
string

Symbol — market symbol. Not a lookup key; echoed back on a rejected ExecutionReport.

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|"

Success

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. 0 if unfilled.

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 0 on a status snapshot; per FIX 4.4, ExecID is not meaningful when ExecType=I.

Value: "0"
35
string

MsgType — 8 for ExecutionReport.

Value: "8"
37
string

OrderID — server-side order id. 0 when the snapshot carries no numeric id.

38
string

OrderQty — original requested quantity, decimal string.

39
string
Enum: "0" "1" "2" "4" "6"

OrdStatus — the order's current state:

  • 0 New (still working)
  • 1 Partially filled
  • 2 Filled
  • 4 Canceled (also covers partially-canceled)
  • 6 Pending Cancel
40
string
Enum: "1" "2" "3" "4"

OrdType — 1 Market, 2 Limit, 3 Stop, 4 Stop limit.

44
string

Price — limit price, decimal string. Omitted for orders with no price (e.g. market orders).

54
string
Enum: "1" "2"

Side — 1 Buy, 2 Sell.

55
string

Symbol — the order's market.

59
string
Enum: "1" "3" "4"

TimeInForce — 1 GTC, 3 IOC, 4 FOK. Present only when the order carries one.

60
string

TransactTime — the order's last-update time in YYYYMMDD-HH:MM:SS.sss format; falls back to the current time when the order carries no update timestamp.

99
string

StopPx — stop trigger price, decimal string. Present only when the order carries one.

150
string

ExecType — I Order Status.

Value: "I"
151
string

LeavesQty — remaining open quantity, decimal string.

790
string

OrdStatusReqID — echoes OrdStatusReqID (790) from the request when one was supplied.

"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|"

Invalid

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:

  • No order matches the supplied key → Text=order not found.
  • Session not authenticated, or API key revoked mid-session → Text=not authenticated / Text=authentication revoked.
  • Backend/transport failure (retryable) → Text=internal error.
  • Rate-limit denial → 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 0 on a rejection.

Value: "0"
11
string

ClOrdID — echoed when the request carried one.

14
string

CumQty — always 0 on a rejection.

Value: "0"
17
string

ExecID — always 0 on an order-status response.

Value: "0"
35
string
Value: "8"
37
string

OrderID — echoes OrderID (37) from the request; 0 when the request carried none.

39
string

OrdStatus — 8 Rejected.

Value: "8"
40
string

OrdType — 2 Limit.

Value: "2"
54
string
Enum: "1" "2"

Side — echoes Side (54) from the request.

55
string

Symbol — echoed when the request carried one.

58
string

Text — human-readable rejection reason.

150
string

ExecType — 8 Rejected.

Value: "8"
151
string

LeavesQty — always 0 on a rejection.

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|"

SecurityListRequest (35=x)

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.

Message Payload

35
required
string

MsgType — x for SecurityListRequest.

Value: "x"
320
required
string

SecurityReqID — client-side request identifier. Echoed on the SecurityList (35=y) response.

559
required
string

SecurityListRequestType — only 0 All Securities is supported. Other values are answered with SecurityRequestResult=4 Invalid or unsupported request.

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|"

Success

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 — y for SecurityList.

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. FXSPOT for crypto spot markets.

Value: "FXSPOT"
320
string

SecurityReqID — echoes the original SecurityListRequest.320.

322
string

SecurityResponseID — server-side identifier for this response. Useful for correlating with operational telemetry.

461
string

CFICode — ISO 10962 classification. MRCXXX for crypto markets.

Value: "MRCXXX"
560
integer

SecurityRequestResult — 0 Valid request on success.

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|"

Invalid

Failure modes:

  • Unsupported SecurityListRequestType → SecurityRequestResult=4 Invalid or unsupported request.
  • Underlying reference-data store unavailable → SecurityRequestResult=2 Instrument data temporarily unavailable.
  • No markets configured → SecurityRequestResult=1 No instruments found that match selection criteria.
  • Rate-limit denial → 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:

  • 1 No instruments found that match selection criteria
  • 2 Instrument data temporarily unavailable
  • 4 Invalid or unsupported request
"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|"

MarketDataRequest (35=V)

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.

Message Payload

35
required
string

MsgType — V for MarketDataRequest.

Value: "V"
55
required
string

Symbol — repeating, one per NoRelatedSym.

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:

  • 0 Snapshot only
  • 1 Snapshot + Updates (subscribe)
  • 2 Disable previous snapshot + updates (unsubscribe)
264
integer

MarketDepth — maximum number of price levels per side. Use 0 to request the full book. Optional.

265
string

MDUpdateType — only 1 Incremental refresh is supported. Required on SubscriptionRequestType=1. 0 Full refresh is rejected.

Value: "1"
267
required
integer

NoMDEntryTypes — number of MDEntryType entries that follow.

269
required
Array of strings
Items Enum: "0" "1"

MDEntryType (repeating) — 0 Bid, 1 Offer.

"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|"

Success

The first response is always a MarketDataSnapshotFullRefresh (35=W). On SubscriptionRequestType=1, subsequent updates are streamed as MarketDataIncrementalRefresh (35=X).

Invalid

A MarketDataRequestReject (35=Y) is emitted on any of the following:

  • Missing MDReqID or SubscriptionRequestType.
  • No symbols specified in NoRelatedSym.
  • Unsupported MDUpdateType (i.e. 0 Full refresh).
  • Unknown SubscriptionRequestType value.
  • Unsubscribe targeting an MDReqID that the session never opened.
  • Order book temporarily unavailable for the requested symbol.
  • The markets named would take the account past its subscribed-market limit (see Rate Limit).

See the MarketDataRequestReject section for the response schema.

MarketDataSnapshotFullRefresh (35=W)

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.

Message Schema

35
string

MsgType — W for MarketDataSnapshotFullRefresh.

Value: "W"
55
string

Symbol — market symbol of this snapshot.

262
string

MDReqID — echoes the original MarketDataRequest.262.

268
integer

NoMDEntries — number of MDEntry blocks that follow.

269
string
Enum: "0" "1"

MDEntryType per entry — 0 Bid, 1 Offer.

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 1.

"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|"

MarketDataIncrementalRefresh (35=X)

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).

Message Schema

35
string

MsgType — X for MarketDataIncrementalRefresh.

Value: "X"
55
string

Symbol — market of this update. Carried on the message body, not repeated per MDEntry.

262
string

MDReqID — echoes the original MarketDataRequest.262.

268
integer

NoMDEntries — number of MDEntry blocks that follow.

269
string
Enum: "0" "1"

MDEntryType per entry — 0 Bid, 1 Offer.

270
string

MDEntryPx — price of this entry, decimal string. The book key along with MDEntryType.

271
string

MDEntrySize — new quantity at this price level, decimal string. 0 is permitted on MDUpdateAction=2 Delete entries.

279
string
Enum: "0" "1" "2"

MDUpdateAction per entry:

  • 0 New — new price level appeared on the book.
  • 1 Change — quantity at an existing level changed.
  • 2 Delete — level was removed from the book.
"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|"

MarketDataRequestReject (35=Y)

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.

Message Schema

35
string

MsgType — Y for MarketDataRequestReject.

Value: "Y"
58
string

Text — human-readable rejection reason.

262
string

MDReqID — echoes the original MarketDataRequest.262.

"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|"

RequestForPositions (35=AN)

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).

Message Payload

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 — AN for RequestForPositions.

Value: "AN"
263
string
Enum: "0" "1"

SubscriptionRequestType:

  • 0 Snapshot
  • 1 Snapshot + Updates (served as a snapshot only on this version)

Any other value (e.g. 2 Disable / unsubscribe) is rejected with an AO carrying PosReqResult=1.

710
required
string

PosReqID — client-side request identifier. Echoed on the AO and on every AP produced for this request.

724
required
string

PosReqType — only 0 Positions is supported. Any other value is rejected with an AO carrying PosReqResult=1.

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|"

Success

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.

Invalid

A RequestForPositionsAck (35=AO) with PosReqStatus=2 Rejected is emitted on:

  • Unsupported PosReqType (anything other than 0 Positions) or SubscriptionRequestType (e.g. 2 Disable) → PosReqResult=1 Invalid or unsupported request.
  • Session not authenticated, or API key revoked mid-session → PosReqResult=3 Not authorized to request positions.
  • Backend/transport error or rate-limit denial → PosReqResult=99 Other (retryable).

A malformed message missing PosReqID (710) or PosReqType (724) is rejected at the protocol level with Reject (35=3).

RequestForPositionsAck (35=AO)

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.

Message Schema

35
required
string

MsgType — AO for RequestForPositionsAck.

Value: "AO"
58
string

Text — human-readable reason. Present only on rejection.

710
required
string

PosReqID — echoes the original RequestForPositions.710.

721
required
string

PosMaintRptID — server-assigned id, unique per emitted ack.

728
required
string
Enum: "0" "1" "3" "99"

PosReqResult:

  • 0 Valid request
  • 1 Invalid or unsupported request
  • 3 Not authorized to request positions
  • 99 Other (retryable internal error, including rate-limit denial)
729
required
string
Enum: "0" "2"

PosReqStatus:

  • 0 Completed (request accepted)
  • 2 Rejected
"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|"

PositionReport (35=AP)

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.

Message Schema

15
required
string

Currency — ISO-4217 code of this position (uppercase).

35
required
string

MsgType — AP for PositionReport.

Value: "AP"
60
required
string

TransactTime — time the report was generated (UTC).

702
required
integer

NoPositions — number of position entries; always 1 on this API.

Value: 1
703
required
string

PosType — POS, the available/unsettled position type defined by the Provider. Not part of the standard FIX 4.4 PosType enum.

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 RequestForPositions.710.

721
required
string

PosMaintRptID — server-assigned id, unique per emitted report.

724
required
string

PosReqType — 0 Positions.

Value: "0"
727
required
integer

TotalNumPosReports — total number of PositionReport messages in this snapshot, after the Currency filter.

728
required
string

PosReqResult — 0 Valid request.

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|"

TradeCaptureReportRequest (35=AD)

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).

Message Payload

11
string

ClOrdID — the client-supplied order identifier. Used as a lookup key only when OrderID (37) is absent; it is first resolved to the numeric order id. Optional if OrderID (37) or a time window is supplied.

35
required
string

MsgType — AD for TradeCaptureReportRequest.

Value: "AD"
37
string

OrderID — the numeric exchange id assigned on order creation and echoes on every ExecutionReport. Primary lookup key. Optional if ClOrdID (11) or a time window is supplied; takes precedence when both keys are present.

60
string

TransactTime — the bound itself, YYYYMMDD-HH:MM:SS.sss (UTC). On the first NoDates (580) entry it opens the window, on the second it closes it. Both bounds are inclusive and are evaluated to whole-second precision, rounded outwards, so the window served is never narrower than the one requested.

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 YYYYMMDD (UTC) date of this entry's bound. Must be the first field of every NoDates (580) entry: it is the group delimiter, and an entry beginning with TransactTime (60) is not recognized as an entry at all, which rejects the request.

263
string

SubscriptionRequestType — 0 Snapshot or omitted (an omitted value is treated as a snapshot). Any other value (e.g. 1 Snapshot + Updates) is rejected with an AQ carrying TradeRequestResult=99.

Value: "0"
568
required
string

TradeRequestID — client-side request identifier. Echoed on the AQ and correlates the response with this request.

569
required
string

TradeRequestType — only 1 Matched trades matching criteria provided on request is served. Any other value is rejected with an AQ carrying TradeRequestResult=8.

Value: "1"
580
integer
Enum: 1 2

NoDates — number of entries in the time-window group: 1 for a window running from the given instant up to the moment the request is received, 2 for an explicit from/to pair. More than 2 entries is rejected. Omit the group to scope the request by order; a count of 0 is read the same way, as no window, which leaves a request carrying no order key to be rejected as unscoped.

"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|"

Success

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.

Invalid

A TradeCaptureReportRequestAck (35=AQ) with TradeRequestStatus=2 Rejected is emitted on:

  • Unsupported TradeRequestType (anything other than 1) → TradeRequestResult=8.
  • Session not authenticated, or API key revoked mid-session → TradeRequestResult=9.
  • Unsupported 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.

TradeCaptureReportRequestAck (35=AQ)

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.

Success

35
required
string

MsgType — AQ for TradeCaptureReportRequestAck.

Value: "AQ"
568
required
string

TradeRequestID — echoes the original TradeCaptureReportRequest.568.

569
required
string

TradeRequestType — echoes the request value (1).

Value: "1"
748
required
integer

TotNumTradeReports — number of TradeCaptureReport (35=AE) messages that follow this ack.

749
required
string

TradeRequestResult — 0 Successful.

Value: "0"
750
required
string

TradeRequestStatus — 1 Completed (request accepted).

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|"

Invalid

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 0 on a rejection.

749
required
string
Enum: "8" "9" "99"

TradeRequestResult — classifies the rejection:

  • 8 Trade request type not supported (TradeRequestType != 1)
  • 9 Not authorized (session not authenticated, or API key revoked mid-session)
  • 99 Other — unsupported SubscriptionRequestType, a request with no order scope, a retryable backend/transport error, or rate-limit denial
750
required
string

TradeRequestStatus — 2 Rejected.

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|"

TradeCaptureReport (35=AE)

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).

Message Schema

12
string

Commission — the fee charged on this trade, decimal string. Present only when the fee is non-zero. Lives on the NoSides (552) entry.

13
string

CommType — 3 Absolute (the fee is an absolute amount). Present only when Commission (12) is.

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 — AE for TradeCaptureReport.

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. 1 Buy, 2 Sell.

55
required
string

Symbol — the trade's market.

60
required
string

TransactTime — the trade time in YYYYMMDD-HH:MM:SS.sss format (UTC); falls back to the current time when the trade carries no timestamp.

75
required
string

TradeDate — the trade date in YYYYMMDD format (UTC).

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 1 (the member's own side).

Value: 1
568
required
string

TradeRequestID — echoes the identifier from the TradeCaptureReportRequest (35=AD) this report answers, correlating the report with its request.

570
required
string

PreviouslyReported — always N; these reports are generated on demand in response to the request.

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 TradeCaptureReportRequestAck (35=AQ).

851
string
Enum: "1" "2"

LastLiquidityInd — the member's liquidity role, present only when known: 1 Added liquidity (maker), 2 Removed liquidity (taker).

912
string

LastRptRequested — Y on the final report of the snapshot. Absent on every other report, so its arrival marks the end of the sequence.

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|"