# Market Data

The Market Data session provides real-time order book streaming via the FIX 4.4 protocol. Use this session to subscribe to price updates for specific trading instruments and receive continuous market data.

{% hint style="warning" %}
For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker.
{% endhint %}

{% hint style="info" %}
This page covers the **Market Data** session only. For trading operations (order placement, execution reports), use the [Trading](/fix-api/trading.md) session.
{% endhint %}

{% file src="/files/xM6citQL0j1gWFVY8g4H" %}
FIX 4.4 Data Dictionary
{% endfile %}

## Supported message types

The following values can be assigned to the `<35>` MsgType field:

* `A` — Logon (Client → B2PRIME)
* `0` — Heartbeat (Client ↔ B2PRIME)
* `1` — Test Request (Client ↔ B2PRIME)
* `3` — Reject (Client ← B2PRIME)
* `4` — Sequence Reset (Client ↔ B2PRIME)
* `5` — Logout (Client ↔ B2PRIME)
* `V` — Market Data Request (Client → B2PRIME)
* `W` — Market Data — Snapshot/Full Refresh (Client ← B2PRIME)
* `X` — Market Data — Incremental Refresh (Client ← B2PRIME)
* `Y` — Market Data Request Reject (Client ← B2PRIME)
* `j` — Business Reject (Client ← B2PRIME)

## Getting started

### Connection

To connect to the Market Data session, use the following parameters provided by B2PRIME:

* **Host and port**: The Market Data endpoint (provided separately from the Trading endpoint)
* **SenderCompID**: Your client identifier for the Market Data session
* **TargetCompID**: The server identifier for the Market Data session
* **Protocol**: FIX 4.4

{% hint style="warning" %}
The Market Data connection does not require SSL.
{% endhint %}

### Message structure

{% hint style="info" %}
**Standard Header**

All FIX messages must begin with a Standard Header containing the following fields:

**`8 BeginString`** `String`

Identifies the FIX version (`FIX.4.4`). Always the first field in a message.

**`9 BodyLength`** `int`

The automatically computed message length, in bytes. Always the second field.

**`35 MsgType`** `String`

The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field.

**`34 MsgSeqNum`** `int`

The message sequence number, incremented by 1 for each consecutive message.

**`49 SenderCompID`** `String`

The identifier of the message sender. Provided by B2PRIME.

**`52 SendingTime`** `Timestamp`

The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`.

**`56 TargetCompID`** `String`

The identifier of the message recipient. Provided by B2PRIME.

***

**Standard Trailer**

All FIX messages must end with a Standard Trailer:

**`10 CheckSum`** `int`

A three-digit checksum. Always the last field in a message.
{% endhint %}

### Logon (A)

This message is sent by the client to initiate a FIX session. It must be the first message in each connection.

{% columns %}
{% column width="60%" %}
**`1 Account`** `String`

The account identifier. Required. Provided by B2PRIME.

**`98 EncryptMethod`** `int`

The encryption method. Required. Must be `0` (no encryption).

**`108 HeartBtInt`** `int`

The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check.

**`141 ResetSeqNumFlag`** `Boolean`

Indicates whether both parties should reset the currently used sequence numbers. Optional.

**`553 Username`** `String`

The client username. Required. Provided by B2PRIME.

**`554 Password`** `String`

The client password. Required. Provided by B2PRIME.
{% endcolumn %}

{% column width="40%" %}
{% code title="Request (Client → B2PRIME)" overflow="wrap" %}

```
8=FIX.4.4^9=138^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2prime^56=target_b2prime^554=password^553=username^98=0^108=30^10=139^
```

{% endcode %}

{% code title="Response (B2PRIME → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=112^35=A^1=68a4446ac84827ff5cd35c74^34=1^49=target_b2prime^52=20231218-07:59:06.655^56=sender_b2prime^98=0^108=30^10=009^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

### Session maintenance

#### Heartbeat (0)

This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages.

{% columns %}
{% column width="60%" %}
**`112 TestReqID`** `String`

The identifier of a Test Request in response to which this Heartbeat is sent. Required when the Heartbeat is a response to a Test Request.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example" overflow="wrap" %}

```
8=FIX.4.4^9=73^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2prime^56=target_b2prime^10=202^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

#### Test Request (1)

This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID.

{% columns %}
{% column width="60%" %}
**`112 TestReqID`** `String`

The identifier of a Test Request. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example" overflow="wrap" %}

```
8=FIX.4.4^9=81^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2prime^56=target_b2prime^112=2^10=040^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

#### Sequence Reset (4)

This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable.

{% columns %}
{% column width="60%" %}
**`123 GapFillFlag`** `Boolean`

Indicates that this message replaces missing messages that won't be resent. Optional.

Possible values:

* `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range
* `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations

**`36 NewSeqNo`** `int`

The new sequence number. Required.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example" overflow="wrap" %}

```
8=FIX.4.4^9=84^35=4^34=6^49=target_b2prime^52=20231219-21:11:38.578^56=sender_b2prime^123=Y^36=8^10=231^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

#### Logout (5)

This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field.

{% columns %}
{% column width="60%" %}
**`58 Text`** `String`

The detailed information about the reason for logging out. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Request (Client → B2PRIME)" overflow="wrap" %}

```
8=FIX.4.4^9=83^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2prime^56=target_b2prime^58=ST1234^10=229^
```

{% endcode %}

{% code title="Response (B2PRIME → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=75^35=5^34=748^49=target_b2prime^52=20231218-13:40:49.016^56=sender_b2prime^10=064^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

### Reject (3)

This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field.

{% hint style="warning" %}
This message is unrelated to application-level rejections (Market Data Request Reject and Business Reject).
{% endhint %}

{% columns %}
{% column width="60%" %}
**`45 RefSeqNum`** `int`

The sequence number of the rejected message (`<34>` MsgSeqNum). Required.

**`371 RefTagID`** `int`

The tag number of the field that caused message rejection. Optional.

**`372 RefMsgType`** `String`

The type of the rejected message (`<35>` MsgType). Optional.

**`373 SessionRejectReason`** `int`

The reason why the message is rejected. Optional.

Possible values:

* `0` — Invalid tag number
* `1` — Required tag missing
* `2` — Tag not defined for this message type
* `3` — Undefined tag
* `4` — Tag has no value assigned
* `5` — Value is incorrect (out of range) for this tag
* `6` — Incorrect value data format
* `7` — Decryption issue
* `8` — Signature problem
* `9` — CompID issue
* `10` — SendingTime accuracy issue
* `11` — Invalid MsgType
* `12` — XML validation error
* `13` — Same tag appears more than once
* `14` — Tag specified not in required order
* `15` — Wrong order of repeating group fields
* `16` — Incorrect NumInGroup count for repeating group
* `17` — Non-"Data" value includes field delimiter (SOH character)
* `99` — Other

**`58 Text`** `String`

The detailed information about the rejection reason. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2PRIME → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=125^35=3^34=193^52=20231219-22:41:16.000^49=target_b2prime^56=sender_b2prime^45=18^371=262^372=V^373=1^58=Required tag missing^10=122^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

***

## Market Data Request (V)

This message is sent by the client to subscribe to real-time quoting data for a specified ticker symbol.

After subscribing, the server sends an initial Market Data — Snapshot/Full Refresh, followed by continuous Market Data — Incremental Refresh messages with each market data update.

To subscribe to multiple symbols, send a separate Market Data Request for each symbol. To unsubscribe, send a Market Data Request with `<263>` SubscriptionRequestType set to `2`. All subscriptions are also terminated when the session is closed via Logout.

{% columns %}
{% column width="60%" %}
**`262 MDReqID`** `String`

The identifier of the Market Data Request. Required. Must be unique for the duration of each session. When unsubscribing, specify the ID of a previous request to discard.

**`263 SubscriptionRequestType`** `int`

The type of response expected from the server. Required.

Possible values:

* `1` — Subscribe: receive updates as the market status changes
* `2` — Unsubscribe: stop streaming market data for the specified symbol

**`264 MarketDepth`** `int`

The market depth for an order book snapshot. Required.

Possible values:

* `0` — Full order book
* `1` — Top-of-the-book prices

**`265 MDUpdateType`** `int`

The update type. Required. Must be `1` (incremental updates for changed price levels only).

**`267 NoMDEntryTypes`** `int`

The number of `<269>` MDEntryType entries requested. Required.

> Repeating group:

**`269 MDEntryType`** `int`

The side of the quote. Required.

Possible values:

* `0` — Bid
* `1` — Ask

**`146 NoRelatedSym`** `int`

The number of ticker symbols. Required. Must be `1`. To subscribe to multiple symbols, send a separate request for each.

> Repeating group:

**`55 Symbol`** `String`

The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (Client → B2PRIME)" overflow="wrap" %}

```
8=FIX.4.4^9=141^35=V^34=7^52=20231220-08:11:50.000^49=sender_b2prime^56=target_b2prime^262=1235^263=1^264=0^265=1^267=2^269=0^269=1^146=1^55=spot.btc_usdt^10=250^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

## Market Data — Snapshot/Full Refresh (W)

This message is sent by the server after the client subscribes to a ticker symbol. It contains the full current state of the order book. Subsequent updates are delivered as Market Data — Incremental Refresh messages.

{% columns %}
{% column width="60%" %}
**`55 Symbol`** `String`

The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`.

**`262 MDReqID`** `String`

The identifier of the originating Market Data Request.

**`268 NoMDEntries`** `int`

The number of market data entries following. The value is `0` if the order book is empty.

> Repeating group (present when `<268>` NoMDEntries > 0):

**`269 MDEntryType`** `int`

The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`.

Possible values:

* `0` — Bid
* `1` — Ask

**`270 MDEntryPx`** `Price`

The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`.

**`271 MDEntrySize`** `Qty`

The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`.

**`278 MDEntryID`** `String`

A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2PRIME → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=507^35=W^34=48^49=target_b2prime^52=20231222-14:40:39.983^56=sender_b2prime^55=spot.btc_usdt^262=1235^268=9^269=1^270=1.10338^271=3000000^278=4441516524^269=1^270=1.10337^271=1000000^278=4441516521^269=1^270=1.10339^271=5000000^278=4441516523^269=1^270=1.10335^271=600000^278=4441516522^269=0^270=1.10333^271=500000^278=4441516520^269=0^270=1.10332^271=1000000^278=4441516517^269=0^270=1.10331^271=3000000^278=4441516516^269=0^270=1.10334^271=100000^278=4441516519^269=0^270=1.1033^271=5000000^278=4441516518^10=025^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

## Market Data — Incremental Refresh (X)

This message is continuously sent by the server after the initial Snapshot/Full Refresh. Each message includes only the changes since the previous update.

{% columns %}
{% column width="60%" %}
**`55 Symbol`** `String`

The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`.

**`262 MDReqID`** `String`

The identifier of the originating Market Data Request.

**`268 NoMDEntries`** `int`

The number of market data entries following. The value is `0` if the order book is empty.

> Repeating group (present when `<268>` NoMDEntries > 0):

**`269 MDEntryType`** `int`

The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`.

Possible values:

* `0` — Bid
* `1` — Ask

**`270 MDEntryPx`** `Price`

The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`.

**`271 MDEntrySize`** `Qty`

The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`.

**`278 MDEntryID`** `String`

A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`.

* Must be unique among active entries when `<279>` MDUpdateAction is `0` (New)
* Must match the previous `<278>` MDEntryID when `<279>` MDUpdateAction is `1` (Change) or `2` (Delete)

**`279 MDUpdateAction`** `int`

The update type. Conditional — required if `<268>` NoMDEntries is not `0`.

Possible values:

* `0` — New
* `1` — Change
* `2` — Delete

**`58 Text`** `String`

Additional context. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2PRIME → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=201^35=X^34=52^49=target_b2prime^52=20231222-14:40:41.150^56=sender_b2prime^55=spot.btc_usdt^262=1235^268=2^279=1^269=0^270=1.10334^271=200000^278=4441516519^279=2^269=1^270=1.10339^271=0^278=4441516523^10=092^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

## Market Data Request Reject (Y)

This message is sent by the server to reject a Market Data Request due to business or technical reasons.

{% columns %}
{% column width="60%" %}
**`262 MDReqID`** `String`

The identifier of the rejected Market Data Request. Required.

**`281 MDReqRejReason`** `int`

The reason why the request is rejected. Optional.

Possible values:

* `0` — Unknown symbol
* `1` — Duplicate MDReqID
* `2` — Insufficient bandwidth
* `3` — Insufficient permissions
* `4` — Unsupported SubscriptionRequestType
* `5` — Unsupported MarketDepth
* `6` — Unsupported MDUpdateType
* `8` — Unsupported MDEntryType

**`58 Text`** `String`

The detailed information about the rejection reason. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2PRIME → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=118^35=Y^34=3^49=target_b2prime^52=20231221-10:25:11.849^56=sender_b2prime^262=1234^58=symbol 'btcusd' is not supported^10=104^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

## Business Reject (j)

This message is sent by the server to reject a message due to a business-level issue not addressed by the standard Market Data Request Reject or session-level Reject.

{% columns %}
{% column width="60%" %}
**`45 RefSeqNum`** `int`

The sequence number of the rejected message (`<34>` MsgSeqNum). Required.

**`372 RefMsgType`** `String`

The type of the rejected message (`<35>` MsgType). Optional.

**`380 BusinessRejectReason`** `int`

The reason why the request is rejected. Required.

Possible values:

* `0` — Other
* `1` — Unknown ID
* `2` — Unknown Security
* `3` — Unsupported MsgType
* `4` — Application not available
* `5` — Conditionally required field missing
* `6` — Not authorized
* `7` — DeliverTo firm not available at this time

**`58 Text`** `String`

The detailed information about the rejection reason. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2PRIME → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=120^35=j^34=2^49=target_b2prime^52=20231219-22:30:39.617^56=sender_b2prime^45=133^58=Unsupported Message Type^372=V^380=3^10=166^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://api-docs.b2prime.com/fix-api/market-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
