FIX API
[!NOTE] This API can only be used with the SPOT Exchange.
General API Information
- FIX connections require TLS encryption. Please either use native TCP+TLS connection or set up a local proxy such as stunnel to handle TLS encryption.
- APIs have a timeout of 10 seconds when processing a request. If a response from the Matching Engine takes longer than this, the API responds with "Timeout waiting for response from backend server. Send status unknown; execution status unknown." (-1007 TIMEOUT)
- This does not always mean that the request failed in the Matching Engine.
- If the status of the request has not appeared in User Data Stream, please perform an API query for its status.
FIX sessions only support Ed25519 keys.
You can setup and configure your API key permissions on Spot Test Network.
FIX API Order Entry sessions
- Endpoint is:
tcp+tls://fix-oe.testnet.binance.vision:9000
- Supports placing orders, canceling orders, and querying current limit usage.
- Supports receiving all of the account's ExecutionReport
<8>
and List Status<N>
. - Only API keys with
FIX_API
are allowed to connect. - QuickFIX Schema can be found here.
FIX API Drop Copy sessions
- Endpoint is:
tcp+tls://fix-dc.testnet.binance.vision:9000
- Supports receiving all of the account's ExecutionReport
<8>
and List Status<N>
. - Only API keys with
FIX_API
orFIX_API_READ_ONLY
are allowed to connect. - QuickFIX Schema can be found here.
FIX Market Data sessions
- Endpoint is:
tcp+tls://fix-md.testnet.binance.vision:9000
- Supports market data streams and active instruments queries.
- Does not support placing or canceling orders.
- Only API keys with
FIX_API
orFIX_API_READ_ONLY
are allowed to connect. - QuickFIX Schema can be found here.
FIX Connection Lifecycle
- All FIX API sessions will remain open for as long as possible, on a best-effort basis.
- There is no minimum connection time guarantee; a server can enter maintenance at any time.
- When a server enters maintenance, a News
<B>
message will be sent to clients every 10 seconds for 10 minutes, prompting clients to reconnect. Upon receiving this message, a client is expected to establish a new session and close the old one. If the client does not close the old session within the time frame, the server will proceed to log it out and close the session.
- When a server enters maintenance, a News
- After connecting, the client must send a Logon
<A>
request. For more information please refer to How to sign a Logon request. - The client should send a Logout
<5>
message to close the session before disconnecting. Failure to send the logout message will result in the session’sSenderCompID (49)
being unusable for new session establishment for a duration of 2x theHeartInt (108)
interval. - The system allows negotiation of the
HeartInt (108)
value during the logon process. Accepted values range between 5 and 60 seconds.- If the server has not sent any messages within a
HeartInt (108)
interval, a HeartBeat<0>
will be sent. - If the server has not received any messages within a
HeartInt (108)
interval, a TestRequest<1>
will be sent. If the server does not receive a HeartBeat<0>
containing the expectedTestReqID (112)
from the client withinHeartInt (108)
seconds, the server will send a Logout<5>
message and close the connection. - If the client has not received any messages within a
HeartInt (108)
interval, the client is responsible for sending a TestRequest<1>
to ensure the connection is healthy. Upon receiving such a TestRequest<1>
, the server will respond with a Heartbeat<0>
containing the expectedTestReqID (112)
. If the client does not receive the server’s response within aHeartInt (108)
interval, the client should close the session and connection and establish new ones.
- If the server has not sent any messages within a
API Key Permissions
To access the FIX API order entry sessions, your API key must be configured with the FIX_API
permission.
To access the FIX Drop Copy sessions, your API key must be configured with either FIX_API_READ_ONLY
or FIX_API
permission.
To access the FIX Market Data sessions, your API key must be configured with either FIX_API
or FIX_API_READ_ONLY
permission.
FIX sessions only support Ed25519 keys.
On message processing order
The MessageHandling (25035)
field required in the initial Logon<A>
message controls whether messages from the client may be reordered before they are processed by the Matching Engine.
Mode | Description |
---|---|
UNORDERED(1) | Messages from the client are allowed to be sent to the matching engine in any order. |
SEQUENTIAL(2) | Messages from the client are always sent to the matching engine in MsgSeqNum (34) order. |
In all modes, the client's MsgSeqNum (34)
must increase monotonically, with each subsequent message having a sequence number that is exactly 1 greater than the previous message.
[!TIP]
UNORDERED(1)
should offer better performance when there are multiple messages in flight from the client to the server.
Response Mode
By default, all concurrent order entry sessions receive all of the account's
successful ExecutionReport<8>
and ListStatus<N>
messages,
including those in response to orders placed from other FIX sessions and via non-FIX APIs.
Use the ResponseMode (25036)
field in the initial Logon<A>
message
to change this behavior.
EVERYTHING(1)
: The default mode.ONLY_ACKS(2)
: Receive only ACK messages whether operation succeeded or failed. Disables ExecutionReport push.
Timing Security
- All requests require a
SendingTime(52)
field which should be the current timestamp. - An additional optional field,
RecvWindow(25000)
, specifies for how long the request stays valid in milliseconds. - If
RecvWindow(25000)
is not specified, it defaults to 5000 milliseconds only for the Logon<A>
request. For other requests if unset, the RecvWindow check is not executed.- Maximum
RecvWindow(25000)
is 60000 milliseconds.
- Maximum
- Request processing logic is as follows:
serverTime = getCurrentTime()
if (SendingTime < (serverTime + 1 second) && (serverTime - SendingTime) <= RecvWindow) {
// begin processing request
serverTime = getCurrentTime()
if (serverTime - SendingTime) <= RecvWindow {
// forward request to Matching Engine
} else {
// reject request
}
// finish processing request
} else {
// reject request
}
How to sign Logon <A>
request
The Logon<A>
message authenticates your connection to the FIX API.
This must be the first message sent by the client.
- The
Username (553)
field is required to contain the API key. - The
RawData (96)
field is required to contain a valid signature made with the API key.
The signature payload is a text string constructed by concatenating the values of the following fields in this exact order, separated by the SOH character:
MsgType (35)
SenderCompId (49)
TargetCompId (56)
MsgSeqNum (34)
SendingTime (52)
Sign the payload using your private key.
Encode the signature with base64.
The resulting text string is the value of the RawData (96)
field.
Here is a sample Python code implementing the signature algorithm:
import base64
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import load_pem_private_key
def logon_raw_data(private_key: Ed25519PrivateKey,
sender_comp_id: str,
target_comp_id: str,
msg_seq_num: str,
sending_time: str):
"""
Computes the value of RawData (96) field in Logon<A> message.
"""
payload = chr(1).join([
'A',
sender_comp_id,
target_comp_id,
msg_seq_num,
sending_time,
])
signature = private_key.sign(payload.encode('ASCII'))
return base64.b64encode(signature).decode('ASCII')
with open('private_key.pem', 'rb') as f:
private_key = load_pem_private_key(data=f.read(),
password=None)
raw_data = logon_raw_data(private_key,
sender_comp_id='5JQmUOsm',
target_comp_id='SPOT',
msg_seq_num='1',
sending_time='20240612-08:52:21.613')
The values presented below can be used to validate the correctness of the signature computation implementation:
Field | Value |
---|---|
MsgType (35) | A |
SenderCompID (49) | EXAMPLE |
TargetCompID (56) | SPOT |
MsgSeqNum (34) | 1 |
SendingTime (52) | 20240627-11:17:25.223 |
The Ed25519 private key used in the example computation is shown below:
[!CAUTION] The following secret key is provided solely for illustrative purposes. Do not use this key in any real-world application as it is not secure and may compromise your cryptographic implementation. Always generate your own unique and secure keys for actual use.
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIIJEYWtGBrhACmb9Dvy+qa8WEf0lQOl1s4CLIAB9m89u
-----END PRIVATE KEY-----
Computed signature:
4MHXelVVcpkdwuLbl6n73HQUXUf1dse2PCgT1DYqW9w8AVZ1RACFGM+5UdlGPrQHrgtS3CvsRURC1oj73j8gCA==
Resulting Logon <A>
message:
8=FIX.4.4|9=247|35=A|34=1|49=EXAMPLE|52=20240627-11:17:25.223|56=SPOT|95=88|96=4MHXelVVcpkdwuLbl6n73HQUXUf1dse2PCgT1DYqW9w8AVZ1RACFGM+5UdlGPrQHrgtS3CvsRURC1oj73j8gCA==|98=0|108=30|141=Y|553=sBRXrJx2DsOraMXOaUovEhgVRcjOvCtQwnWj8VxkOh1xqboS02SPGfKi2h8spZJb|25035=2|10=227|
Limits
Message Limits
- Each connection has a limit on how many messages can be sent to the exchange.
- The message limit does not count the messages sent in response to the client.
- Breaching the message limit results in immediate Logout
<5>
and disconnection. - To understand current limits and usage, please send a LimitQuery
<XLQ>
message. A LimitResponse<XLR>
message will be sent in response, containing information about Order Rate Limits and Message Limits. - FIX Order entry sessions have a limit of 10,000 messages every 10 seconds.
- FIX Drop Copy sessions have a limit of 60 messages every 60 seconds.
- FIX Market Data sessions have a limit of 2000 messages every 60 seconds.
Connection Limits
- Each Account has a limit on how many TCP connections can be established at the same time.
- The limit is reduced when the TCP connection is closed. If the reduction of connections is not immediate, please wait up to twice the value of
HeartBtInt (108)
for the change to take effect. For example, if the current value ofHeartBtInt
is 5, please wait up to 10 seconds. - Upon breaching the limit a Reject
<3>
will be sent containing information about the connection limit breach and the current limit. - FIX Order Entry limits:
- 15 connection attempts within 30 seconds
- Maximum of 10 concurrent TCP connections per account
- FIX Drop Copy limits:
- 15 connection attempts within 30 seconds
- Maximum of 10 concurrent TCP connections per account
- FIX Market Data limits
- 300 connection attempts within 300 seconds
- Maximum of 100 concurrent TCP connections per account
- A single connection can listen to a maximum of 1000 streams.
Unfilled Order Count
- To understand how many orders you have placed within a certain time interval, please send a LimitQuery
<XLQ>
message. A LimitResponse<XLR>
message will be sent in response, containing information about Unfilled Order Count and Message Limits. - Please note that if your orders are consistently filled by trades, you can continuously place orders on the API. For more information, please see Spot Unfilled Order Count Rules.
- If you exceed the unfilled order count your message will be rejected, and information will be transferred back to you in a reject message specific to that endpoint.
- The number of unfilled orders is tracked for each account.
Error Handling
Client messages that contain syntax errors, missing required fields, or refer to unknown symbols will be rejected by the server with a Reject <3>
message.
If a valid message cannot be processed and is rejected, an appropriate reject response will be sent. Please refer to the individual message documentation for possible responses.
Please refer to the Text (58)
and ErrorCode (25016)
fields in responses for the reject reason.
The list of error codes can be found on the Error codes page.