# FIX Maker API: ESP Workflow

This document describes the Integral FIX Maker ESP API, a FIX-based channel that allows makers to publish streams of liquidity to customers and execute trades through Integral.

The following sections discuss the configuration of the API, and the trading workflows and messages that the API supports:

* [FIX solution](#fix-solution): FIX implementation, business rules, and overviews of messages and workflows
* [Administrative messages](#administrative-messages): messages used to control the FIX session and manage message conversations
* [Workflows](#workflows): business workflows and message conversations described
* [Application messages](#application-messages): trading message structure and data
* [Examples](#examples): message examples
* [Changes](#changes): corrections and enhancements made to the content of this document


## FIX solution

* [FIX implementation](#fix-implementation)
* [Configuration](#configuration)
* [Business rules](#business-rules)


### FIX implementation

The interface defined by the API conforms to the FIX 4.3 specifications. The FIX Protocol Organization provides a complete reference to the protocol at:

#### Terminology

Each FIX Maker ESP API message is comprised of message fields defined in this document. Each field has its own set of attributes including:

* Tag: field number.
* Field name: human-readable name for reference.
* Req’d: indicates if the field must be sent on the FIX message:
  * Y = required by the FIX protocol.
  * Y(API) = required by the FIX Maker ESP API implementation.
  * N = optional for both the FIX Maker ESP API and the FIX protocol.
  * C = conditional. Refer to the field’s description to determine applicability.
* Valid values: specific values accepted for this field.
* Description: brief description of the field.
* Type(length): FIX data type of the field and the maximum length of the field value.
* →: arrow indicates a field in a repeating group.


#### Supported message types

The API supports the following FIX messages types:

Supported message types 

| Message type | Message name | Inbound to Maker (I), Outbound from Maker (O), or Bidirectional (B) |
|  --- | --- | --- |
| Session management messages  |
| A | [Logon](#logon) | B |
| 5 | [Logout](#logout) | B |
| 0 (zero) | [Heartbeat](#heartbeat) | B |
| 1 | [Test Request](#test-request) | B |
| 2 | [Resend Request](#resend-request) | B |
| 3 | [Session-Level Reject](#session-level-reject) | B |
| 4 | [Sequence Reset](#sequence-reset) | B |
| Trading messages  |
| g | [Trading Session Status Request](#trading-session-status-request) | I |
| h | [Trading Session Status](#trading-session-status) | O |
| V | [Market Data Request](#market-data-request) | I |
| W | [Market Data Snapshot/Full Refresh](#market-data-snapshotfull-refresh) | O |
| Y | [Market Data Request Reject](#market-data-request-reject) | O |
| D | [New Order – Single (previously quoted)](#new-order-single) | I |
| H | [Order Status Request](#order-status-request) | I |
| F | [Order Cancel Request](#order-cancel-request) | I |
| OT | [Order Timeout](#order-timeout) | I |
| Q | [Don’t Know Trade](#dont-know-trade-dk) | I |
| 8 | [Execution Report](#execution-report) | O |
| j | [Business Message Reject](#business-message-reject) | B |


#### Ignored and unsupported fields

This document only describes the FIX workflows and fields necessary to access Integral. All fields not included in this document are unsupported and ignored by Integral.

Some fields are required conditionally based on the state of the message workflow or on the value of other fields in the message. These conditions and dependencies are clearly indicated in the field descriptions.

#### String length

For many fields of type String, the FIX protocol defines all possible valid values. Therefore, the maximum string length of these fields is also defined. The maximum string length never exceeds the longest valid value.

The API does not impose a maximum length on undefined String fields, such as free-form text fields and ID fields.

#### Message length

The API does not impose a maximum length on FIX messages sent or received by Integral.

#### Encryption

The API does not support FIX message encryption. Instead, the network transport mechanism (VPN, Radianz, or SSL) ensures message security.

#### Message headers and footers

FIX engines set a message’s header and footer fields automatically according to the message type and the application context as defined by the application’s configuration ([Configuration](#configuration)). For these reasons, the standard header and footer as defined by the FIX protocol are not discussed in detail in this document beyond the expected value of the `MsgType` (#35) and the fields that identify message and business senders and targets, such as the `SenderCompID` (#49), and `TargetCompID` (#56) fields.

Standard message header fields 

| Tag | Field name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 8 | BeginString | Y | FIX.4.3 | The identifier at the beginning of a new message that also holds the protocol version. Always set to “FIX.4.3”. Always the first field in the message. | String(7) |
| 9 | BodyLength | Y | — | Indicates the message length in bytes. Always the second field in the message. | int(6) |
| 35 | MsgType | Y | — | Defines the message type. Always the third field in the message. See [Supported message types](#supported-message-types) for the complete list of supported message types. | String(2) |
| 34 | MsgSeqNum | Y | — | This value is an integer message sequence number. | SeqNum(9) |
| 43 | PossDupFlag | N | Y=Possible duplicate
N=Original transmission | Indicates possible retransmission of message with this sequence number. | Boolean(1) |
| 49 | SenderCompID | Y | — | The message sender’s ID. See [Organization identification](#organization-identification). | String(20) |
| 56 | TargetCompID | Y | — | The message target’s ID. See [Organization identification](#organization-identification). | String(20) |
| 52 | SendingTime | Y | — | The time of message transmission (GMT). | UTCTimestamp(21) |
| 122 | OrigSendingTime | N | — | Original time of message transmission when transmitting orders as the result of a resend request. | UTCTimestamp(21) |


Standard message footer field 

| Tag | Field name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 10 | Checksum | Y | — | A three byte, simple checksum that is always the last field on the message. | String(3) |


### Configuration

The following sections describe the details involved in establishing a connection via the API.

#### Deployment

Integral deploys an API FIX engine instance for each maker. The instance is called the FIX Maker ESP API adaptor. The adaptor handles all streams from the maker and submits orders to the maker.

#### Network connectivity

The API uses TCP/IP sockets. FIX message encryption is not supported. Makers connect to Integral using one of the following options to ensure network reliability and security:

* Radianz
* IPSec VPN
* SSL


#### Organization identification

The values of the `TargetCompId` (#49) and `SenderCompId` (#56) fields in the message header are supplied by Integral for each maker connection. Integral does not allow multiple connections using the same `TargetCompId` (#49) and `SenderCompId` (#56) fields.

##### Account IDs

Integral is a trading facilitator. Trades are booked directly between your organization (maker) and the end customer. You must assign an account ID to each of the maker’s customer legal entities trading through Integral. The account ID is set on the `Account` (#1) field of New Order – Single message. The account ID value is agreed upon by your organization and Integral.

The ClientTag on a trade request, if any, is captured in the `PartyID` (#448) field. The ClientTag is a unique ID whose value is set by Integral. It is an optional field. See [New Order – Single](#new-order--single).

##### Maker organization ID

Your organization ID is expressed as a series of tokens separated by periods, much like an Internet domain name:

```
<sessionType>.<orgShortName>
price.yourOrg4
```

Organization ID format 

| Token | Example | Description |
|  --- | --- | --- |
| *sessionType* | **price**.yourOrg4 | For a description of the following session types, see [Sessions](#sessions):* price
* order

 |
| *orgShortName* | price.**yourOrg4** | Your organization’s short name ID |


All messages that you send to Integral must include your ID in the `SenderCompID` (#49) field.

All messages that you receive from Integral include your ID in the `TargetCompID` (#56) field.

##### Integral server ID

Like your organization ID, the Integral server ID looks like an Internet domain name:

```
<environment>.integral
demo.integral
```

Organization ID format 

| Token | Example | Description |
|  --- | --- | --- |
| *environment* | **demo**.integral | The specific environment to which you are connected (for example, staging, staging, or production) |
| integral | demo.**integral** | The Integral server ID |


All messages that you send to Integral must include the server ID in the `TargetCompID` (#56) field.

All messages that you receive from Integral include your ID in the `SenderCompID` (#49) field.

#### Connection mode

The FIX Maker ESP API supports initiator and acceptor connection modes. Communication starts with a Logon message ([Logon](#logon)) and ends with a Logout message ([Logout](#logout)).

##### Acceptor mode

In the acceptor mode, your FIX engine initiates the FIX connection. The acceptor mode is the default, preferred connection mode for the API. The following parameters must be specified in the FIX configuration of your FIX engine:

Parameters for acceptor connection mode 

```
ConnectionType=acceptor
SocketAcceptPort=<Integral’s Port>
```

##### Initiator mode

In the initiator mode, Integral initiates the FIX connection to the maker’s FIX engine. To configure your systems for initiator mode, please contact Integral Business Support. The following parameters must be specified in the FIX configuration of your FIX engine:

Parameters for initiator connection mode 

```
ConnectionType=initiator
SocketConnectHost=<Maker’s IP>
SocketConnectPort=<Maker’s Port>
HeartBtInt=5
```

### Business rules

The following business rules apply to all API workflows.

#### Sessions

The API distinguishes between two session types to optimize your trading message flows: price and order. You must establish both sessions to initiate all trading workflows.

Every session has exactly one associated session of the other type. Orders in an order session can only be received from prices sourced from its associated price session.

* Price: Session for sending/receiving market data and quotes. Messages are time-sensitive and transient to enable the high message volume typically associated with prices and price streams. Integral does not resend price session messages in response to a resend request from the maker system. You must establish a price session to initiate all trading workflows. See [Starting the trading session](#starting-the-trading-session).
* Order: Session for order submission and trade execution. Messages are transactional and persistent with no lost messages allowed, reflecting their business criticality. Integral resends order session messages in response to a resend request from the maker system. You must establish an order session to initiate all trading workflows. See [Starting the trading session](#starting-the-trading-session). How you use an order session depends on the trading workflow you employ.


You must log on and establish each FIX session separately with Integral. You use the same credentials for each session type. You can have multiple FIX sessions under one server connection. You do not have to reconnect for each session.

The ID that you set for your organization ID on messages includes an indicator of the session type. See [Maker organization ID](#maker-organization-id).

#### Business day end and start

The business day start and end time must be agreed upon by your organization and Integral. A typical daily configuration starts the day at 17:00:05 EST and ends at 17:00:00 EST.

Daily start/stop times 

```
ResetOnLogout=N
ResetOnLogin=N
ResetOnDisconnect=N
StartTime=17:00:05
EndTime=17:00:00
TimeZone=America/New_York
```

The API allows you to set custom start and end times for every day of the week.

The following examples illustrate the capabilities of API start/stop times. Please contact Integral Business Support to configure custom start/stop times.

Custom start/stop times format 

```
CustomScheduleTime=[*startDay0* *startTime0*]-[*endDay* *endTime*]~[*startDay1* *startTime1*]-[*endDay1* *endTime1*]~…
```

Custom start/stop times example 

```
CustomScheduleTime=[Sunday 08:30:00]-[Monday 06:35:00]~[Monday 06:40:00]-[Tuesday 04:00:00]~…
```

#### Server synchronization

Your servers initiating the FIX connection to Integral should be synchronized with the NTP pool. For more information about using the NTP pool, please use the following link:

[http://www.pool.ntp.org/en/use.html](http://www.pool.ntp.org/en/use.html)

#### Sequence number reset

Your FIX engine must be configured to reset the sequence number `MsgSeqNum` (#34) only at the end of day and not on disconnect.

To reset sequence numbers once a day after the business day end, the following session-level FIX parameters need to be set on the acceptor and initiator side with the following values (assuming 17:00:05 EST and 17:00:00 EST are the start and end time). The initiator side may have a slightly larger down-time window to ensure that the acceptor is ready to handle the connection started by the initiator. See [Connection mode](#connection-mode) for more information about initiator and acceptor connection modes.

Parameters for acceptor sequence number reset 

```
ResetOnDisconnect=N
ResetOnLogout=N
StartTime=17:00:05
EndTime=17:00:00
```

Parameters for initiator sequence number reset 

```
ResetOnDisconnect=N
ResetOnLogout=N
StartTime=17:00:05
EndTime=17:00:00
```

#### Event sequencing

The API handles trading events from customers and makers on a first-come first-served basis.

#### Supported deal types

The API currently supports dealing in the following deal types:

* FX spot only


#### Directed orders

To submit an order to a specific venue, set `ExDestination` (#100) to the target venue.

Subsequent order workflow is routed to and from the venue by Integral (for example, order cancel, order cancel/replace, order fills, status).

#### External algos

You can send orders for algos in third-party venues with the following fields on New Order - Single:

External algo fields 

| Tag  | Field name | Req’d | Valid values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 100  | ExDestination | N | — | For external algos and other directed orders, the name of the target venue. | String(20) |
| 957  | NoStrategyParameters | N | — | Number of strategy parameters in this repeating group. | NumInGroup(3) |
| → | 958 | StrategyParameterName | N | — | Name of the parameter. | String(255) |
| → | 959 | StrategyParameterType | N | See descr. | Datatype of the parameter.
1=Int
2=Length
3=NumInGroup
4=SeqNum
5=TagNum
6=Float
7=Qty
8=Price
9=PriceOffset
10=Amt
11=Percentage
12=Char
13=Boolean
14=String
15=MultipleCharValue
16=Currency
17=Exchange
18=Month-Year
19=UTCTimeStamp
20=UTCTimeOnly
21=LocalMktDate
22=UTCDateOnly
23=Data
24=MultipleStringValue | int(2) |
| → | 960 | StrategyParameterValue | N | — | Value of the parameter. | String(1023) |


#### Mid mark price

The API holds mid-mark information in the following fields:

| Tag | Field name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 631 | MidPx | N | — | The near-leg all-in mid price. Only required when the receiving organization is required to receive Pre-Trade Mid-Market Mark. This decision is made by the maker. | Price(20) |
| 7631 | MidPxFl | N | — | The far-leg all-in mid price. Only required when the receiving organization is required to receive Pre-Trade Mid-Market Mark. This decision is made by the maker. | Price(20) |


#### Rate update frequency

Integral applies flow control on makers’ incoming rates. A maximum 200 rate updates per currency pair per price stream in a 2 second window are permitted. Please contact your Integral Technical Account Manager if you have any questions.

If a price stream breaches the rate limits, the stream is blacked out for 5 seconds.

## Administrative messages

### Session management messages

The following messages are used to control the FIX session and manage message conversations:

* [Logon](#logon)
* [Logout](#logout)
* [Heartbeat](#heartbeat)
* [Test Request](#test-request)
* [Resend Request](#resend-request)
* [Session-level Reject](#session-level-reject)
* [Sequence Reset](#sequence-reset)


### Logon

(Bidirectional)

The Logon message is sent by the maker system to start a session with Integral and sent by Integral in response to a valid log-on request.

You should reset the FIX sequence number for the price session (`ResetSeqNumFlag` (#141)=Y) after 3 or 4 unsuccessful log-on attempts. Do not reset the sequence number of the order session.

If Integral receives a Logon message with invalid fields, it sends a Logout message in response. See [Logout](#logout).

Logon message fields 

| Tag | Name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | A | A=Logon | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: *HH*:*MM*:*SS*.*sss* | UTCTimestamp(21) |
| 98 | EncryptMethod | N | 0 | 0 (zero)=no encryption is used. This field may be omitted.
Radianz or VPN is used for transport-level security. | int(1) |
| 108 | HeartBtInt | Y | 5 | Heartbeat interval in seconds. If HeartBtInt is set zero, then no heart beat message is required. The recommended heartbeat interval is 5 seconds. | int(3) |
| 141 | ResetSeqNumFlag | N | Y | Indicates that both sides of the FIX session should reset sequence numbers. You should reset the FIX sequence number for the price session after 3 or 4 unsuccessful log-on attempts. Do not reset the sequence number of the order session.
Y=Yes, reset sequence numbers
N=No, do not reset sequence numbers | Boolean(1) |


### Logout

(Bidirectional)

The Logout message is sent by the maker system to end a session with Integral and sent by Integral in response.

If Integral receives a Logon message with invalid fields, it sends a Logout message in response with a description of the error in the `Text` (#58) field.

Logout message fields 

| Tag | Name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | 5 | 5=Logout | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `HH:MM:SS.sss` | UTCTimestamp(21) |
| 58 | Text | N | — | The reason for the Logon rejection. Only included for incoming Logout messages (Integral to maker) in response to a invalid Logon message. Not valid for outgoing Logout messages (maker to Integral). | String(150) |


### Heartbeat

(Bidirectional)

Both the maker system and Integral send the Heartbeat message to indicate that the connection is active.

The maker system generates a regular heartbeat at the interval defined by the `HeartBtInt` (#108) field in the Logon message from Integral or as a response to a Test Request message from Integral. The recommended heartbeat interval is 5 seconds.

Heartbeat message fields 

| Tag | Name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | 0 | 0 (zero)=Heartbeat | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `HH:MM:SS.sss` | UTCTimestamp(21) |
| 112 | TestReqID | N | — | Required when the heartbeat is the result of a Test Request message. See [Test Request](#test-request). | Strin(20) |


### Test Request

(Bidirectional)

Forces a heartbeat from the receiving system. The receiving system responds to a Test Request message with a Heartbeat message containing the TestReqID. See [Heartbeat](#heartbeat).

Test Request message fields 

| Tag | Name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | 1 | 1=Test Request | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `HH:MM:SS.sss` | UTCTimestamp(21) |
| 112 | TestReqID | Y | — | The resulting Heartbeat message contains this ID. The TestReqId should be incremental. | String(20) |


### Resend Request

(Bidirectional)

The Integral accepts Resend Request messages only for order sessions ([Sessions](#sessions)). Resend Requests sent on a price session are ignored. Both the maker system and Integral can send a Resend Request message when they detect a message gap to request either a single message or a range of messages.

Resend Request message fields 

| Tag | Name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | 2 | 2=Resend Request | Stgring(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `HH:MM:SS.sss` | UTCTimestamp(21) |
| 122 | OrigSendingTime | N | — | Original time of message transmission when transmitting orders as the result of a resend request | UTCTimestamp(21) |
| 7 | BeginSeqNo | Y | — | First message of range (inclusive) | SeqNum(9) |
| 16 | EndSeqNo | Y | — | Last message of range (inclusive). If the value of the `EndSeqNo` (#16) field is equal to the `BeginSeqNo` (#7) field, a single message is requested.
To request all messages after the `BeginSeqNo` (#7) field, set the `EndSeqNo` (#16) field to 0 (zero). | SeqNum(9) |


### Session-level Reject

(Bidirectional)

Both the maker system and Integral send this message when a message is received but cannot be processed for some reason, such as a missing field required by the FIX protocol.

Reject message fields 

| Tag | Name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | 3 | 3=Reject | String(2) |
| 45 | RefSeqNum | Y | — | Value of the `MsgSeqNum` (#34) field of the rejected message. | SeqNum(9) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `HH:MM:SS.sss` | UTCTimestamp(21) |
| 58 | Text | N | — | Free-form text explaining the reason for rejection. | String(150) |
| 371 | RefTagID | N | — | The tag number of the FIX field being referenced. | int(5) |
| 372 | RefMsgType | N | — | The value of the `MsgType` (#35) field in the FIX message being referenced. | String(2) |
| 373 | SessionRejectReason | N | — | The code that indicates the reason for rejection.
0=Invalid tag number
1=Required tag missing
2=Tag not defined for message type
3=Undefined Tag
4=Tag specified without a value
5=Value is incorrect (out of range) for this tag
6=Incorrect data format for value
7=Decryption problem
8=Signature problem
9=CompID problem
10=SendingTime accuracy problem
11=Invalid MsgType
12=XML Validation error
13=Tag appears more than once
14=Tag specified out of required order
15=Repeating group fields out of order
16=Incorrect NumInGroup count for repeating group
17=Non “data” value includes field delimiter (SOH character)
99=Other | int(2) |


### Sequence Reset

(Bidirectional)

This message is sent by both the maker system and Integral to reassign the sequence number when a gap in messages is detected.

Sequence Reset message fields 

| Tag | Name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | 4 | 4=Sequence Reset | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `HH:MM:SS.sss` | UTCTimestamp(21) |
| 122 | OrigSendingTime | N | — | Original time of message transmission when transmitting orders as the result of a resend request | UTCTimestamp(21) |
| 36 | NewSeqNo | Y | — | The next sequence number to be transmitted. | SeqNum(9) |
| 123 | GapFillFlag | N | — | Indicates that the Sequence Reset message is replacing administrative or application messages that will not be resent.
Y=Gap fill, the `NewSeqNo` (#36) field should conform to the FIX-standard message sequencing rules.
N or not specified=Sequence reset, the `NewSeqNo` (#36) of the header of the Sequence Reset message should be ignored so that if it is not correct it does not generate resent requests. This value would be appropriate in a disaster recovery situation. | Boolean(1) |


## Workflows

All trading activity through the API begins with a query to establish the maker’s trading session status ([Starting the trading session](#starting-the-trading-session)).

After the trading session has been established, the API implements the ESP pricing workflow ([Executable streaming prices (ESP) workflow](#executable-streaming-prices-esp-workflow)).

For order submission and trade execution, see [Orders workflow](#orders-workflow).

### Starting the trading session

A trading session consists of one price session and its associated order session. For more information about sessions, see [Sessions](#sessions).

To start a trading session, the following FIX message conversation must complete successfully between Integral and the maker.

Integral can only start the business workflow if the trading session status is “Open” (`TradSesStatus` (#340)=2) for both the price and order sessions.

1. Logon (#35=A) sent from maker on price session.
2. Logon response (#35=A) on price session from Integral.
3. Trading Session Status Request (#35=g) sent from Integral.
4. Trading Session Status (#35=h) with `TradSesStatus` (#340)=2 (Open) sent from maker on price session.
5. Logon (#35=A) sent from maker on order session.
6. Logon response (#35=A) on order session from Integral.
7. Trading Session Status Request (#35=g) sent from Integral.
8. Trading Session Status (#35=h) with `TradSesStatus` (#340)=2 (Open) sent from maker on order session.


```mermaid
sequenceDiagram
  accTitle: Message conversation to start trading
  participant API
  participant Maker

  Maker->>API: Logon(price session): MsgType(#num;35)=A
  API->>Maker: Logon(price session): MsgType(#num;35)=A
  API->>Maker: Trading Session Status Request(price session):<br/>MsgType(#num;35)=g
  Maker->>API: Trading Session Status(price session): MsgType(#num;35)=h |<br/>TradSesStatus(#num;340)=2
  Maker->>API: Logon(order session): MsgType(#num;35)=A
  API->>Maker: Logon(order session): MsgType(#num;35)=A
  API->>Maker: Trading Session Status Request(order session):<br/>MsgType(#num;35)=g
  Maker->>API: Trading Session Status(order session): MsgType(#num;35)=h |<br/>TradSesStatus(#num;340)=2
```

Message conversation to start trading 

### Stopping the trading session

To alert customers of a change in trading session status, the maker sends an unsolicited trading session status message. Typical reasons for unsolicited trading session status messages are:

* End-of-day close for daily sequence number reset
* End-of-week close for weekly maintenance
* Intra-day close due to errors


```mermaid
sequenceDiagram
  accTitle: Asynchronous trading session status update (halted)
  participant API
  participant Maker

  Maker->>API: Trading Session Status: MsgType(#num;35)=h |<br/> UnsolicitedIndicator(#num;325)=Y |<br/>TradSesSatus(#num;340)=1 (Halted)
```

```mermaid
sequenceDiagram
  accTitle: Asynchronous trading session status update (closed)
  participant API
  participant Maker

  Maker->>API: Trading Session Status: MsgType(#num;35)=h |<br/> UnsolicitedIndicator(#num;325)=Y |<br/>TradSesSatus(#num;340)=3 (Closed)
```

Asynchronous trading session status update 

When the trading session is “Closed” (`TradSesStatus` (#340)=3) or “Halted” (`TradSesStatus` (#340)=1), Integral stops sending messages and cleans up the current trading session (both the FIX price session and the FIX order session). When the trading session is reopened, Integral re-initializes the business workflow.

### Executable streaming prices (ESP) workflow

Integral can only start the trading workflow if the trading session status is “Open” (`TradSesStatus` (#340)=2) for both the price and order sessions. See [Starting the trading session](#starting-the-trading-session).

#### ESP supported trade types

For the ESP workflow, the API currently supports trading in FX spot only.

#### ESP workflow

The Executable Streaming Prices (ESP) workflow involves both price and order sessions. For more information about session types, see [Sessions](#sessions).

The customer requests market data in a price session and receives executable quotes on the same price session. Then in an order session the customer sends an order. For previously quoted orders (`OrdType` (#40)=D), the order refers to the originating price’s `QuoteEntryID` (#299). For limit orders (`OrdType` (#40)=2), the order must include the requested price and size (`Price` (#44) and `OrderQty` (#38)). For market orders (`OrdType` (#40)=1), the order must include the requested size (`OrderQty` (#38)).

```mermaid
sequenceDiagram
  accTitle: ESP trading workflow: previously quoted order
  participant API
  participant Maker

  API->>Maker: Market Data Request: MsgType(#num;35)=V |<br/>SubscriptionRequestType(#num;263)=1 (Snapshot+Updates)
  loop Market data updates on stream
    Maker->>API: Market Data Snapshot/Full Refresh: MsgType(#num;35)=Q
  end
  API->>Maker: New Order - Single: MsgType(#num;35)=D |<br/>OrdType(#num;40)=D (Previously Quoted) | QuoteEntryID(#num;299)=quote ID
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=F (Trade) | OrdStatus(#num;39)=2 (Filled)
```

ESP trading workflow: previously quoted order 

```mermaid
sequenceDiagram
  accTitle: ESP trading workflow: limit order
  participant API
  participant Maker

  API->>Maker: Market Data Request: MsgType(#num;35)=V |<br/>SubscriptionRequestType(#num;263)=1 (Snapshot+Updates)
  loop Market data updates on stream
    Maker->>API: Market Data Snapshot/Full Refresh: MsgType(#num;35)=Q
  end
  API->>Maker: New Order - Single: MsgType(#num;35)=D |<br/>OrdType(#num;40)=2 (Limit) | Price(#num;44)=Order rate | OrdQty(#num;38)=Order size
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=F (Trade) | OrdStatus(#num;39)=2 (Filled)
```

ESP trading workflow: limit order 

```mermaid
sequenceDiagram
  accTitle: ESP trading workflow: market order
  participant API
  participant Maker

  API->>Maker: Market Data Request: MsgType(#num;35)=V |<br/>SubscriptionRequestType(#num;263)=1 (Snapshot+Updates)
  loop Market data updates on stream
    Maker->>API: Market Data Snapshot/Full Refresh: MsgType(#num;35)=Q
  end
  API->>Maker: New Order - Single: MsgType(#num;35)=D |<br/>OrdType(#num;40)=1 (Market) | OrdQty(#num;38)=Order size
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=F (Trade) | OrdStatus(#num;39)=2 (Filled)
```

ESP trading workflow: market order 

The following trading messages are applicable to the ESP workflow:

ESP trading messages 

| Message (Direction) | Session | Comments |
|  --- | --- | --- |
| [Market Data Request](#market-data-request) | Price | Customer through Integral requests ESP from the maker or cancels ESP (unsubscribe). |
| [Market Data Snapshot/Full Refresh](#market-data-snapshotfull-refresh) | Price | Maker sends a price as a snapshot of the requested currency pairs to the customer through Integral. |
| [Market Data Request Reject](#market-data-request-reject) | Price | Maker rejects the market data request (for example, the currency pair is not supported). |
| [New Order – Single](#new-order-single) | Order | Customer through Integral submits an order to the maker in response to a price received in a Market Data Refresh message. |
| [Order Status Request](#order-status-request) | Order | Customer through Integral sends this message to the maker to request an Execution Report be sent with the order’s current status. |
| [Order Cancel Request](#order-cancel-request) | Order | Customer through Integral sends this message to the maker to request cancellation of a previously submitted order. |
| [Execution Report](#execution-report) | Order | Maker sends the current order status to the customer through Integral. See [Order state transition](#order-state-transition) for details. |


#### Quote type

The Market Data Snapshot/Full Refresh message contains the latest market price for a currency pair. The API supports three types of ESP quotes: single price, multi-tiered, and multi-price.

##### Single price quote

The Market Data Snapshot/Full Refresh contains one pair of bid and offer prices for a currency pair with each market data update.

* `NoMDEntries` (#268) = 2 (a single pair of bid and offer prices)
* `MDEntryType` (#269) = The message includes a bid entry and an offer entry.
* `MDEntryPositionNo` (#290) = 0


##### Multi-tiered quote

The Market Data Snapshot/Full Refresh contains multi-tiered quotes for each amount level. For example, 1.2345/46 for amounts to 5M, 1.2344/47 for amounts to 10M, 1.2343/48 for amounts to 15M.

* `NoMDEntries` (#268) = 2 times the number of tiers. In the above example, the `NoMDEntries` (#268) value would be 6.
* `MDEntryType` (#269) = Typically the message includes an equal number of bid/offer prices. The number of bid and offer price can become uneven if the maker performs dynamic liquidity regeneration.
* `MDEntryPositionNo` (#290) = The value indicates the tier position of the bid and offer prices. In the first tier, prices have a value of 1. Second tier prices have a value of 2 and so on.


For previously quoted orders, the customer must refer to the quote ID in the `QuoteID` (#117) field of the New Order – Single message.

For limit orders, the order price and size (`Price` (#44), `OrderQty` (#38)) must match the tier price and size of the quote in the `MDEntryPx` (#270) and `MDEntrySize` (#271) fields of the Market Data Snapshot/Full Refresh message. The maker should reject an order if the amount of the order and the price tier do not match. The order amount is filled to the offered amount.

For market orders, the order price and size (`Price` (#44), `OrderQty` (#38)) must match the tier price and size of the quote in the `MDEntryPx` (#270) and `MDEntrySize` (#271) fields of the Market Data Snapshot/Full Refresh message. The maker should reject an order if the amount of the order and the price tier do not match. The order amount is filled to the offered amount.

##### Multi-price quote

The Market Data Snapshot/Full Refresh contains the entire depth of the book with multiple independent prices (typically from an order book). A customer can sweep the entire book and get multiple fills at each price level.

* `NoMDEntries` (#268): Any number depending on the number of prices in the book
* `MDEntryType` (#269): The number of bid and offer prices is typically not even.
* `MDEntryPositionNo` (#290): 0 (each price is independent)


#### Quote cancel

To remove or pull a price, you need to send a new Market Data Snapshot/Full Refresh message in the currency pair with the `QuoteCondition` (#276) field set to B (Closed / Inactive) or with a `MDEntrySize` (#271) value of 0 (zero).

Do not send a Market Data Snapshot/Full Refresh message with a `MDEntryPx` (#270) value of 0 (zero).

#### Stream ID

Your organization can provide multiple streams and assign each stream to a customer category. You and Integral must agree on an ID for each stream.

The `QuoteID` (#117) value must be unique across all of your streams. It is your organization’s responsibility to validate that the quote from a correct stream is used for a customer order.

Integral sends the stream ID in the Market Data Request message in the Stream `ID` (#7540) custom field. The stream ID is optional. If your organization does not support multiple streams of prices, the Stream `ID` (#7540) field is left empty.

### Orders workflow

Order messages are exchanged on order sessions. See [Sessions](#sessions) for more information about order and price sessions. Orders originate with Integral sending a New Order – Single message to the maker as part of a pricing workflow.

The following FIX messages implement the order trading flow:

Order trading messages 

| Message (Direction) | Session | Comments |
|  --- | --- | --- |
| [New Order – Single](#new-order-single) | Order | Customer through Integral submits an order to the maker. |
| [Execution Report](#execution-report) | Order | Maker sends the current order status to the customer through Integral. The Execution Report with `ExecType` (#150) value 0 (New) is optional and may be skipped. See [Order state transition](#order-state-transition) for details. |
| [Order Status Request](#order-status-request) | Order | Customer through Integral requests the current status of a specific order. |
| [Order Cancel Request](#order-cancel-request) | Order | Customer through Integral requests cancellation of a previously submitted order. |
| [Business Message Reject](#business-message-reject) | Order | * The maker rejects an order status request if the order does not exist (`RefMsgType` (#372)=H).
* The maker rejects an order cancel request if the order does not exist (`RefMsgType` (#372)=F).
* If an Execution Report message for a fill or partial fill is received with the `LastQty` (#32) field not specified or set to zero, Integral rejects it with a Business Message Reject message. See [LastQty](#tag-execution-report-lastqty).

 |
| [Order Timeout](#order-timeout) | Order | If autocancellation is configured, maker receives this message if Integral does not receive a rejection or trade verification before the order times out. |
| [Don’t Know Trade (DK)](#dont-know-trade-dk) | Order | If autocancellation is configured, maker receives this message if Integral receives a trade response after the order times out and an Order Timeout message is sent. |


#### Order submission and execution

After Integral submits an order, the maker sends an Execution Report message with an `ExecType` (#150) value of A=“Pending New” to confirm receipt. After the maker has checked the order’s validity, the maker sends an Execution Report message with an `ExecType` (#150) value of 0 (zero)=“New” to Integral.

An order can have one or more trades executed against it, either one completely filling or multiple trades partially filling the order.

```mermaid
sequenceDiagram
  accTitle: Order submission and execution
  participant API
  participant Maker

  API->>Maker: New Order - Single: MsgType(#num;35)=D
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=A (Pending New) | OrdStatus(#num;39)=0 (Pending New)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=0 (New) | OrdStatus(#num;39)=0 (New)
  rect rgba(94, 43, 255, 0.1)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=F (Trade) | OrdStatus(#num;39)=1 (Partially Filled)
  note over Maker,API: OR
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=F (Trade) | OrdStatus(#num;39)=2 (Filled)
  end
```

Order submission and execution 

#### Order rejection

After Integral submits an order, the maker immediately sends an Execution Message with an `ExecType` (#150) value of A=“Pending New” to confirm receipt. If the order fails the maker’s validity check, the maker sends an Execution Report message with an `ExecType` (#150) value of 8 “Rejected” to Integral.

```mermaid
sequenceDiagram
  accTitle: Order rejection
  participant API
  participant Maker

  API->>Maker: New Order - Single: MsgType(#num;35)=D
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=A (Pending New) | OrdStatus(#num;39)=0 (Pending New)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=8 (Rejected) | OrdStatus(#num;39)=8 (Rejected)
```

Order rejection 

#### Order expiry

An IOC order expires immediately after the initial match. Any residual amount is canceled by the maker by sending an Execution Report message with an `ExecType` (#150) value of C “Expired” to Integral.

```mermaid
sequenceDiagram
  accTitle: Order expiry
  participant API
  participant Maker

  API->>Maker: New Order - Single: MsgType(#num;35)=D
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=A (Pending New) | OrdStatus(#num;39)=0 (Pending New)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=0 (New) | OrdStatus(#num;39)=0 (New)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=F (Trade) | OrdStatus(#num;39)=1 (Partially Filled)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=C (Restateed) | OrdStatus(#num;39)=C (Expired)
```

Order expiry 

#### Order timeout

When autocancellation is enabled, if Integral does not receive a trade rejection or verification from the maker by the end of the timeout interval, an Order Timeout message is sent to the maker. This order timeout informs the maker that no valid Execution Report with a fill or rejection was received within the autocancellation timeout interval and the order is timed out (effectively rejected).

If a rejection or verification is received from the maker after the Order Timeout message is sent, a Don’t Know Trade (DK) message is sent to the maker.

In addition, when an order reaches a terminal state (verification, rejection, expiry for a partial fill, or expiry/complete fill for a multiple fill order), then any terminal state message that is sent by the maker triggers a Don’t Know Trade (DK) message in response.

```mermaid
sequenceDiagram
  accTitle: Order timeout
  participant API
  participant Maker

  API->>Maker: New Order - Single: MsgType(#num;35)=D
  Note over API,Maker: Timeout interval passes with no response from the Maker
  API->>Maker: Order Timeout: MsgType(#num;35)=OT
  rect rgba(94, 43, 255, 0.1)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=8 (Rejected) | OrdStatus(#num;39)=8 (Rejected)
  API->>Maker: Don't Know Trade (DK): MsgType(#num;35)=Q
  end
  rect rgba(94, 43, 255, 0.1)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=C (Restateed) | OrdStatus(#num;39)=C (Expired)
  API->>Maker: Don't Know Trade (DK): MsgType(#num;35)=Q
  end
  rect rgba(94, 43, 255, 0.1)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=F (Trade) | OrdStatus(#num;39)=2 (Filled)
  API->>Maker: Don't Know Trade (DK): MsgType(#num;35)=Q
  end
```

Order timeout 

#### Order status

Integral uses the Order Status Request message to query the maker about pending trades.

If the “PendingNew” Execution Report is not received by Integral for a predefined time period, Integral raises a pending trade alert to Integral support personnel and sends an Order Status Request message to the maker to query the status of the pending order.

Alternatively, Integral can automatically cancel the pending trade to the customer by following policies established between Integral and the maker before deployment of the API. See [Order timeout](#order-timeout).

If the Order Status Request message is rejected or if an Execution Report is not forthcoming, the trade remains pending and requires manual intervention from Integral and the maker’s support staff.

If Integral receives an Execution Report from the maker for a pending trade, Integral updates the status of the trade. Integral support staff may still contact the maker regarding the delayed response because of the possibility of customer exposures.

```mermaid
sequenceDiagram
  accTitle: Order status request
  participant API
  participant Maker

  API->>Maker: Order Status Request: MsgType(#num;35)=H | OrderID(#num;37)=Order ID
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=I (Order Status) | OrdStatus(#num;39)=Status code
  rect rgba(94, 43, 255, 0.1)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=I (Order Status) | OrdStatus(#num;39)=Status code
  note over Maker,API: OR
  Maker->>API: Business Message Reject: MsgType(#num;35)=j |<br/>RefMsgType(#num;372)=H (Order Status Request) |<br/> BusinessRejectRefID(#num;379)=Order ID |<br/>BusinessRejectReason (#num;380)=1 (Unknown ID)
  end
```

Order status request 

#### Order cancel

Integral uses the Order Cancel Request message to cancel a previously submitted order.

```mermaid
sequenceDiagram
  accTitle: Order cancel request
  participant API
  participant Maker

  API->>Maker: Order Cancel Request: MsgType(#num;35)=F | OrderID(#num;37)=Order ID
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=6 (Pending Cancel) | OrdStatus(#num;39)=6 (Pending Cancel)
  rect rgba(94, 43, 255, 0.1)
  Maker->>API: Execution Report: MsgType(#num;35)=8 |<br/>ExecType(#num;150)=4 (Cancel) | OrdStatus(#num;39)=4 (Cancel)
  note over Maker,API: OR
  Maker->>API: Business Message Reject: MsgType(#num;35)=j |<br/>RefMsgType(#num;372)=F (Order Cancel Request) |<br/> BusinessRejectRefID(#num;379)=Order ID |<br/>BusinessRejectReason (#num;380)=1 (Unknown ID)
  end
```

Order cancel request 

#### Supported order types

The API supports orders with the following `OrdType` (#40) values. Integral rejects messages from customers with unsupported order types.

Order types 

| Order type | OrdType (#40) value | Description |
|  --- | --- | --- |
| Previously Quoted | D | The client sends new orders with a reference to a previously received executable price in `QuoteEntryID` (#299) from a price ([Market Data Snapshot/Full Refresh](#market-data-snapshotfull-refresh%22)). |
| Limit | 2 | Orders executed at the limit price or better until they are filled, rejected, or expired ([Order expiry (time in force)](#order-expiry-time-in-force)). Orders must include the requested price and size (`Price` (#44) and `OrderQty` (#38)). |
| Market | 1 | Orders are executed at the best available price in the system.until they are filled, rejected, or expired ([Order expiry (time in force)](#order-expiry-time-in-force)). |


#### Order expiry (time in force)

The FIX Maker ESP API supports orders with the following `TimeInForce` (#59) values:

Order expiry 

| Expiry type | Description | TimeInForce (#59) | Applicable order types |
|  --- | --- | --- | --- |
| Day | The order remains active for the entire day until it is completely filled, canceled by the customer, or until the end of the business day (the roll time). | 0=Day | * Market
* Limit

 |
| IOC (Immediate or Cancel) | The order is matched with the available order book in the system after the submission. If the order is not completely filled (or after the expiry/cancel message is received) any remaining amount is cancelled. If no fill/expiry/cancel message is received, the entire order is assumed to be cancelled.
If `MinQty` (#110) is specified, the first fill must be greater than or equal to the minimum quantity and lesser than or equal to the order quantity, otherwise the order goes into a pending state. Subsequent fills, if any, may be of any size.
If `MinQty` (#110) is not specified, the first fill may be of any size less than or equal to the order size. Subsequent fills, if any, may be of any size. | 3=IOC | * Market
* Limit
* Previously Quoted

 |
| FOK (Fill or Kill) | The order is matched with the available order book in the system after the submission. The order amount must be completely filled with one fill or canceled in its entirety. No partial fill is allowed. | 4=FOK | * Market
* Limit
* Previously Quoted

 |
| GTT/GTD (Good Till Date/Time) | The order remains active until completely filled, canceled by the submitter, or expired.
Applicable to limit orders only. See [Supported order types](#supported-order-types).
You must specify the expiry time in GMT in the `ExpireTime` (#126) field in the format *YYYYMMDD*-*hh*:*mm*:*ss*.*sss*.
For example, to set the order to expire at 17:00 on August 14th, 2025, you would specify `126=20250814-17:00:00.000`. | 6=GTT/GTD | Limit |


#### Partial fills

Partial fills apply only to the order trading workflow. See [Orders workflow](#orders-workflow) for information.

You can specify how orders are filled with the `MinQty` (#110) field in the New Order – Single message:

* Partial fill: The order amount can be filled multiple times until the entire amount is filled.
* Partial fill with market minimum: The order amount can be filled multiple times, but the first fill must be no less than the market minimum defined by the `MinQty` (#110) field. Subsequent fills have no size requirement.
* No partial fill: The order amount must be filled in its entirety with exactly one fill. The value of the `MinQty` (#110) field equals the value of the `OrderQty` (#38) field. This is effectively a fill-or-kill order.


For more details about partial fills, see the `MinQty` field in the [New Order – Single message](#new-order--single).

#### Order state transition

The maker maintains an order’s status and propagates changes in status via Execution Report messages to Integral. The order states and state transitions are shown in [Order state transitions](#fig-order-state-transitions). Each circle represents a value of the `OrdStatus` (#39) field of an Execution Report message. The event names on the transition lines represent the `ExecType` (#150) values of the Execution Report message. Multiple transitions from the same `OrdStatus` (#39) may have the same `ExecType` (#150) value. The destination `OrdStatus` (#39) is determined by other attributes of the order as described in [Orders workflow](#orders-workflow).

Order state transitions 

```mermaid
stateDiagram-v2
  accTitle: Order state transitions
  direction LR
  Pending: Pending New
  Partially: Partially Filled
  Cancelled: Cancelled#nbsp;

  [*] --> Pending: Order<br/>submitted
  Pending --> New: New
  Pending --> Rejected: Reject
  Pending --> Cancelled: Cancel#nbsp;
  New --> Rejected: Reject
  New --> Cancelled: Cancel#nbsp;
  New --> Expired: Expire
  New --> Partially: Trade
  New --> Filled: Trade
  Partially --> Filled: Trade
  Partially --> Partially: Trade
  Partially --> Expired: Expire
  Rejected --> [*]
  Cancelled --> [*]
  Expired --> [*]
  Filled --> [*]
```

Order status 

| Order Status | OrdStatus (#39) | Description |
|  --- | --- | --- |
| Pending New | A | An order is received by maker. This order state is optional. |
| New | 0 (zero) | The validity of the order is confirmed. The order is successfully entered maker’s execution management process. |
| Partially filled | 1 | The order is partially filled by maker. |
| Filled | 2 | The total order amount is filled. |
| Rejected | 8 | The maker determines that the order is invalid. The order is rejected. |
| Expired | C | When an order is expired, its residual amount (full amount if the order is New) is canceled. For IOC orders, the order is immediately expired after the initial match. Any remaining amount must be expired or rejected. |
| Canceled | 4 | The order is canceled by the customer. |


`OrdStatus` (#39)=4 (Canceled) is not supported in the FIX Maker ESP API.

## Application messages

The FIX Maker ESP API offers the following order workflow features to makers:

* Order submission
* Order execution reports for accept/acknowledge, reject, trade execution, and partial fill events


All messages sent from the maker to Integral must include millisecond precision in the `SendingTime` (#52) field.

### Supported message types

The API order workflow supports the following FIX messages types:

Supported message types 

| MsgType (#35) | Message name | Inbound to Maker (I), Outbound from Maker (O), or Bidirectional (B) |
|  --- | --- | --- |
| g | [Trading Session Status Request](#trading-session-status-request) | I |
| h | [Trading Session Status](#trading-session-status) | O |
| V | [Market Data Request](#market-data-request) | I |
| W | [Market Data Snapshot/Full Refresh](#market-data-snapshotfull-refresh) | O |
| X | [Market Data – Incremental Refresh](#market-data-incremental-refresh) | O |
| Y | [Market Data Request Reject](#market-data-request-reject) | O |
| D | [New Order – Single](#new-order-single) | I |
| H | [Order Status Request](#order-status-request) | I |
| F | [Order Cancel Request](#order-cancel-request) | I |
| OT | [Order Timeout](#order-timeout) | I |
| Q | [Don’t Know Trade (DK)](#dont-know-trade-dk) | I |
| 8 | [Execution Report](#execution-report) | O |
| j | [Business Message Reject](#business-message-reject) | B |


### Trading session

#### Trading Session Status Request

(Integral to Maker)

This message is sent by Integral to query the maker’s status and as part of starting a trading session with the maker. For more information, see [Starting the trading session](#starting-the-trading-session).

Trading Session Status Request message fields 

| Tag | Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | g | — | String(2) |
| 263 | SubscriptionRequestType | Y | — | 0 (zero)=Snapshot | char(1) |
| 335 | TradSesReqID | Y | — | Unique ID assigned by the customer for the request message | String(20) |


#### Trading Session Status

(Maker to Integral)

This message is sent by the maker to notify Integral of intra-day closing and opening of the market, and as part of starting a trading session with the maker. For more information, see [Starting the trading session](#starting-the-trading-session).

Trading Session Status message fields 

| Tag | Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | h | — | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |
| 325 | UnsolicitedIndicator | N | * Y
* N

 | If the message is sent unsolicited, the value of this field should be “Y”. If the message is sent as a response to a customer request, this field should have a value of “N” or may be omitted or left empty. For more information, see [Stopping the trading session](#stopping-the-trading-session). | Boolean(1) |
| 335 | TradSesReqID | N | — | Reference to the value of `TradSesReqID` (#335) field on the customer request, if any. If the status message is sent unsolicited, this field should be left empty or not included. | String(20) |
| 336 | TradingSessionID | Y | — | ID of the trading session. Can be any string. | String(20) |
| 340 | TradSesStatus | Y | — | 0=Unknown
1=Halted (trading temporarily suspended)
2=Open
3=Closed | int(1) |


### Market data messages

The messages in this section are used to access the ESP workflow (see [Executable streaming prices (ESP) workflow](#executable-streaming-prices-esp-workflow)).

#### Market Data Request

(Integral to Maker)

Integral sends one Market Data Request message per currency pair per price stream (across all customers) to initiate trading in the ESP workflow with the maker. If a customer subscribes to five currency pairs in a price stream, the maker receives five Market Data Request messages. For two price streams with five unique currency pairs each across multiple customers, the maker receives ten Market Data Request messages. The subscription is sent when the first customer set up for a currency pair on the stream subscribes. Because a subscription is already sent, when a subsequent customer requests prices for the same currency pair on the stream, no further subscription is sent to the maker.

Integral also sends a single Market Data Request message on behalf of a customer to unsubscribe from all rates. The unsubuscription message is sent per currency pair per price stream and is sent only when the last customer receiving pricing for the currency pair per stream no longer needs it. See [Executable streaming prices (ESP) workflow](#executable-streaming-prices-esp-workflow) for information.

Makers can be certified to send both full refresh and incremental data modes, however a maker can only price in one mode at a time. Please contact your Integral Technical Account Manager to inform them of which modes you want to support.

Market Data Request message fields 

| Tag  | Field name | Req’d | Valid values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | V | — | String(2) |
| 262  | MDReqID | Y | — | The customer-assigned unique ID for the market data request. This ID must not contain the ampersand character “@”. Integral rejects all requests with duplicate IDs. | String(11) |
| 263  | SubscriptionRequestType | Y | * 1
* 2

 | This field indicates to the receiving party what type of response is expected. A subscribe request asks for updates as the status changes. Unsubscribe cancels any future update messages from the organization.
1=Snapshot + Updates (subscribe to stream, default)
2=Disable previous Snapshot + Update Request (Unsubscribe) | char(1) |
| 264  | MarketDepth | Y | 0=Full book | Depth of market for book snapshot. The only valid value for this field in the API is 0=Full book. | int(1) |
| 265  | MDUpdateType | Y | 0=Full Refresh
1=Incremental Refresh | This value specifies the type of Market Data update. This field is required with the `SubscriptionRequestType` (#263) value of 1 (Snapshot + Updates).
Makers can be certified to send both full refresh and incremental data modes, however a maker can only price in one mode at a time. Please contact your Integral Technical Account Manager to inform them of which modes you want to support.\ | int(1) |
| 7540  | StreamID | N | — | The ID for the stream agreed by Integral and the maker.
If the maker does not support multi-stream pricing, this field is not included or is left empty. | String(30) |
| → | 146 | NoRelatedSym | Y | 1 (one) | The number of repeating symbols specified. This indicates the number of currency pairs that the market data request message is associated with. Because the client must submit a Market Data Request Message for each currency pair, there is a one-to-one relationship between the quote request message and currency pair. Thus, the value of this field is always 1 (one). | NumInGroup(1) |
| → | 55 | Symbol | Y | — | The symbol for the base and variable currencies of the currency pair in the following format:
*baseCCY/variableCCY*
(for example, “EUR/USD”) | String(35) |
| → | 460 | Product | Y | 4 | The asset class. The value is always 4=CURRENCY. | int(1) |
| → | 167 | SecurityType | N | * FOR
* FXFWD
* FXNDF

 | The security type or trade type:* FOR=Foreign Exchange Contract
* FXFWD=FX Forward (streaming outrights)
* FXNDF=Non-deliverable forward (streaming NDFs)
You must include `SettlType` (#63) for FXFWD or FXNDF.

 | String(20) |
| → | 63 | SettlType | See descr. | See descr. | The requested tenor. Required when `SecurityType` (#167)=FXFWD or FXNDF. Broken dates are not supported. The following tenors are supported:* 1W, 2W, 3W
* 1M, 2M, 3M, 4M, 5M, 6M, 7M, 8M, 9M, 10M, 11M
* 1Y
* 15M, 18M

 | String(3) |
| 267  | NoMDEntryTypes | Y | 2 | Number of `MDEntryType` (#269) fields requested. This number is always set to “2” (bid/offer). | NumInGroup(1) |
| → | 269 | MDEntryType | Y | See descr.* 0 (zero)
* 1 (one)

 | The API supports only two-way market data. This field is required by the FIX specification but is ignored by the FIX Maker ESP API. There must be two instances of the `MDEntryType` (#269) field. One instance is set to “0” (zero) and one instance is set to “1” (one). | char(1) |


#### Market Data Snapshot/Full Refresh

(Maker to Integral)

The maker sends a Market Data Snapshot/Full Refresh message to Integral in response to a Market Data Request message for each currency pair stream.

The API maintains a one-to-one relationship between customers, currency pairs, and Market Data Snapshot/Full Refresh message targets. Integral sends Market Data Snapshot/Full Refresh messages for each customer and each currency pair stream in the ESP workflow.

The Market Data Snapshot/Full Refresh message may contain multiple rates. The `NoMDEntries` (#268) field indicates the number of rates in the message. If you want to send multi-tier or multi-price quotes, see [Quote type](#quote-type). The customer receives the fully qualified customer rate and associated limits. The customer rate is specified by the `MDEntryPx` (#270) field.

Each rate consists of a repeating group of fields, as indicated by arrows in the table below.

Makers can be certified to send both full refresh and incremental data modes, however a maker can only price in one mode at a time. Please contact your Integral Technical Account Manager to inform them of which modes you want to support.

Market Data Snapshot/Full Refresh message fields 

| Tag  | Field name | Req’d | Valid values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35  | MsgType | Y | W | — | String(2) |
| 52  | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |
| 55  | Symbol | Y | — | The symbol for the base and variable currencies of the currency pair in the following format:
*baseCurrency/termCurrency*
(for example, “EUR/USD”)
For inverted quotes, this field should be specified as:
*termCurrency/baseCurrency*
(for example, “USD/EUR”) | String(35) |
| 262  | MDReqID | Y | — | Unique identifier from the originating Market Data Request | String(30) |
| 460  | Product | N | 4 | The asset class. The value is always 4=CURRENCY. | int(1) |
| 167  | SecurityType | N | * FOR
* FXFWD
* FXNDF

 | The security type or trade type:* FOR=Foreign Exchange Contract
* FXFWD=FX Forward (streaming outrights)
* FXNDF=Non-deliverable forward (streaming NDFs)
If FXFWD or FXNDF, then `SettlType` (#63) must be included.

 | String(20) |
| 63  | SettlType | See descr. | See descr. | The requested tenor. Required when `SecurityType` (#167)=FXFWD or FXNDF. Broken dates are not supported. The following tenors are supported:* 1W, 2W, 3W
* 1M, 2M, 3M, 4M, 5M, 6M, 7M, 8M, 9M, 10M, 11M
* 1Y
* 15M, 18M

 | String(3) |
| 541  | MaturityDate | N | — | You should leave this field empty and specify `SettlDate` (#64) instead. The value of the `MaturityDate` (#541) field is populated by Integral. Date of maturity in *YYYYMMDD* format. | LocalMktDate(8) |
| 64  | SettlDate | N | See descr. | * FX spot (`SecurityType` (#167)=FOR): spot date in *YYYYMMDD* format:
* FX outright and NDF (`SecurityType` (#167)=FXFWD): value date in *YYYYMMDD* format:
* NDF (`SecurityType` (#167)=FXNDF): value date in *YYYYMMDD* format:

 | * LocalMktDate(8)
* String(10)

 |
| 268  | NoMDEntries | Y | — | Number of currency pairs in market data message represented by a repeating group of fields. The required fields must be included as a group for each currency pair or your request will be rejected. Each bid and offer represents one market data entry. If three bid/offer dealing prices are included, the value of the `NoMDEntries` (#268) field is 6. | NumInGroup(1) |
| → | 269 | MDEntryType | Y | — | The side of the rate. Part of the repeating group of fields for each rate in the update.
0=Bid
1=Offer
2=Trade | char(1) |
| → | 1026 | MDEntrySpotRate | N | — | The spot rate. Applicable when `SecurityType` (#167)=FXFWD or FXNDF. | float(20) |
| → | 1027 | MDEntryForwardPoints | N | — | The forward points. Must be specified as the raw basis points and not the value applied to the spot rate. For example, 34.9 points should be specified as “34.9” and not “0.000000349”. Applicable when `SecurityType` (#167)=FXFWD or FXNDF. | PriceOffset(20) |
| → | 270 | MDEntryPx | Y | — | The price. For example, if `MDEntryType` (#269) field of a repeating group is 0 (bid), this field holds the bid price. The value of this field should not be set to 0 (zero). Part of the repeating group of fields for each rate in the update.
The all-in price when `SecurityType` (#167)=FXFWD or FXNDF. | Price(20) |
| → | 15 | Currency | Y | — | The value of this field represents the denomination of the quantity fields (for example, JPY represents a quantity of JPY). This may be the base or term currency of a currency pair. Part of the repeating group of fields for each rate in the update. | String(3) |
| → | 271 | MDEntrySize | Y | — | The quantity (in the case of multiple tiers, the limit). Part of the repeating group of fields for each rate in the update. | Qty(20) |
| → | 276 | QuoteCondition | Y | — | Indicates whether the rate is tradable or only indicative. Part of the repeating group of fields for each rate in the update.
A=Open/Active
B=Closed/Inactive | char(1) |
| → | 282 | MDEntryOriginator | Y | — | The maker organization ID. The maker associated with the bid or offer quote. Part of the repeating group of fields for each rate in the update. This field is not used in Integral processing. | String(30) |
| → | 299 | QuoteEntryID | Y | — | Uniquely identifies each rate as part of a quote set. The reference ID for the dealing price. Part of the repeating group of fields for each rate in the update. | String(15) |
| → | 290 | MDEntryPositionNo | Y | — | The integer value indicates the tier of the price. For multi-tier quotes, the value will be greater than zero. For single price or multi-price quotes, this field equals zero. See [Quote type](#quote-type) for information about business rules regarding multi-price and multi-tier quotes. | int(1) |


#### Market Data – Incremental Refresh

(Maker to Integral)

The maker sends a Market Data – Incremental Refresh message to Integral in response to a successful Market Data Request message for a currency pair. The Market Data Request message must have the `MDUpdateType` (#265) field set to 1 (one).

The Market Data – Incremental Refresh message may contain one or more rates. The `NoMDEntries` (#268) field indicates the number of rates in the message.

Each rate consists of a repeating group of fields, as indicated by arrows in the table below.

Only new rate entries (`MDUpdateAction` (#279)=0) include currency pair and bid/offer information for the entry. Subsequent updates to and deletion of the rate refer to the rate’s `MDEntryID` (#278) and do not include fields like `Currency` (#15) and `MDEntryType` (#269).

Makers can be certified to send both full refresh and incremental data modes, however a maker can only price in one mode at a time. Please contact your Integral Technical Account Manager to inform them of which modes you want to support.

Market Data – Incremental Refresh message fields 

| Tag  | Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35  | MsgType | Y | X | — | String(2) |
| 52  | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |
| 262  | MDReqID | Y | — | Unique identifier from the originating Market Data Request | String(20) |
| 167  | SecurityType | N | * FOR
* FXFWD
* FXNDF

 | The security type or trade type:* FOR=Foreign Exchange Contract
* FXFWD=FX Forward (streaming outrights)
* FXNDF=Non-deliverable forward (streaming NDFs)
If FXFWD or FXNDF, then `SettlType` (#63) must be included.

 | String(20) |
| 63  | SettlType | See descr. | See descr. | The requested tenor. Required when `SecurityType` (#167)=FXFWD or FXNDF. Broken dates are not supported. The following tenors are supported:* 1W, 2W, 3W
* 1M, 2M, 3M, 4M, 5M, 6M, 7M, 8M, 9M, 10M, 11M
* 1Y
* 15M, 18M

 | String(3) |
| 268  | NoMDEntries | Y | — | Number of entries in market data message as repeating groups of fields that represent one rate. The required fields must be included as a group for each rate. Each bid and offer represents one market data entry. If three bid/offer dealing prices are included, the value of the `NoMDEntries` (#268) field is 6. | NumInGroup(1) |
| → | 279 | MDUpdateAction | Y | * 0=New
* 1=Change
* 2=Delete

 | The Market Data update action type. It must be the first field in the repeating group. Valid values are:* 0=New: New price or replace existing price. To replace a price, entry must include `MDEntryID` (#278) of existing price. Entry includes currency and bid/offer fields.
* 1=Change: Update existing price. Entry must include `MDEntryID` (#278) of existing price.
* 2=Delete: Delete existing price. Entry must include `MDEntryID` (#278) of existing price.

 | char(1) |
| → | 269 | MDEntryType | See descr. | — | The side of the rate:* 0=Bid
* 1=Offer
Required for entries with `MDUpdateAction` (#279) value of 0 (New).

 | char(1) |
| → | 278 | MDEntryID | Y | — | Unique identifier for the market data entry. Unique per level (amount) and per side (bid and offer).
For makers who support previously quoted orders, this ID is sent from Integral in the `QuoteID` (#117) field of the New Order - Single message. | char(1) |
| → | 55 | Symbol | See descr. | — | Required for entries with `MDUpdateAction` (#279) value of 0 (New).
The currency pair in the format *baseCCY*/*variableCCY* (for example, “EUR/USD”). | String(35) |
| → | 1026 | MDEntrySpotRate | N | — | The spot rate. Applicable when `SecurityType` (#167)=FXFWD or FXNDF. | float(20) |
| → | 1027 | MDEntryForwardPoints | N | — | The forward points. Must be specified as the raw basis points and not the value applied to the spot rate. For example, 34.9 points should be specified as “34.9” and not “0.000000349”. Applicable when `SecurityType` (#167)=FXFWD or FXNDF. | PriceOffset(20) |
| → | 270 | MDEntryPx | See descr. | — | Required for entries with `MDUpdateAction` (#279) value of 0 (New).
The price. The side of the price is indicated by the `MDEntryType` (#269) field. If the value of this field is 0 (zero), your client should ignore the quote.
The all-in price when `SecurityType` (#167)=FXFWD or FXNDF. | Price(20) |
| → | 15 | Currency | See descr. | — | The dealt currency. Required for entries with `MDUpdateAction` (#279) value of 0 (New). | String(3) |
| → | 271 | MDEntrySize | See descr. | — | The size of the price. Required for entries with `MDUpdateAction` (#279) value of 0 (New). | Qty(20) |


#### Market Data Request Reject

(Maker to Integral)

The maker sends a Market Data Request Reject message to Integral in response to an unsuccessful Market Data Request message.

Market Data Request Reject message fields 

| Tag | Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | Y | — | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |
| 58 | Text | N | — | Your organization’s description of the rejection should be sent in this field. | String(150) |
| 262 | MDReqID | Y | — | The unique identifier from the originating Market Data Request. | String(11) |
| 281 | MDReqRejReason | N | — | The reason for the reject. If the client attempts to subscribe to a currency pair that they are not permissioned for, the value of the `MDReqRejReason` (#281) field is 3.
0=Unknown symbol
1=Duplicate MDReqID
3=Insufficient Permissions | char(1) |


### Trading messages

The messages in this section are used to access the trading workflow of the API.

#### New Order – Single

(Integral to Maker)

Integral sends a New Order – Single message to submit an order to the maker.

Groups of associated fields are indicated by arrows in the table below.

New Order – Single message fields 

| Tag  | Field name | Req’d | Valid values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35  | MsgType | Y | D | — | String(2) |
| 1  | Account | Y | — | The account ID. The value of this field is agreed upon by your organization and Integral. | String(30) |
| 11  | ClOrdID | Y | — | A session-scoped unique order ID assigned by Integral. | String(11) |
| 15  | Currency | Y | — | The dealt currency. This may be the base or term currency of a currency pair. | String(3) |
| 21  | HandlInst | Y | 1 (one) | Instructions for order handling on the broker trading floor.
The value of this field is always:
1=Automated execution order, private, no Broker intervention | char(1) |
| 38  | OrderQty | Y | — | FX spot, outright, NDF: The amount of the dealt currency (as specified by the `Currency` (#15) field) to be either bought or sold (as determined by the `Side` (#54) field). | Qty(20) |
| 40  | OrdType | Y | D=Previously quoted
2=Limit
1=Market | Other order types are not currently supported. See [Supported order types](#supported-order-types). | char(1) |
| 44  | Price | Y | — | FX spot, outright, NDF: The execution price or limit price. The precision of this float value must be agreed upon by both the sending and the receiving parties. For outrights and NDFs this is the all-in price. | Price(20) |
| 54  | Side | Y | 1=Buy (Bid)
2=Sell (Offer) | FX spot, outright, NDF: The side of the order from the customer’s perspective and in terms of the dealt currency `Currency` (#15). | char(1) |
| 55  | Symbol | Y | — | The symbol for the base and variable currencies of the currency pair in the following format:
*baseCurrency*/*termCurrency*
(for example, “EUR/USD”)
For inverted quotes, this field should be specified as:
*termCurrency*/*baseCurrency*
(for example, “USD/EUR”) | String(35) |
| 58  | Text | N | — | Free format text string | String(150) |
| 59  | TimeInForce | Y | * 0
* 3
* 4
* 6

 | See [Order expiry](#order-expiry-time-in-force) for a description of order expiry types.
0=Day
3=IOC
4=FOK
6=GTT/GTD | char(1) |
| 126  | ExpireTime | C | — | Required when `TimeInForce` (#59)=6(GTT/GTD).
The expiry time in the format *YYYYMMDD*-*hh*:*mm*:*ss*.*sss*.
For example, to set the order to expire at 17:00 on August 14th, 2025, you would specify `126=20250814-17:00:00.000`. | UTCTimestamp(21) |
| 60  | TransactTime | Y | — | Time automatically stamped by the server that this order request was initiated/released by the trader, trading system, or intermediary in the format: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |
| 64  | SettlDate | Y | See descr. | Settlement date in *YYYYMMDD* format:* FX spot: spot date.
* FX outright and NDF: Value date.

 | LocalMktDate(8) |
| 110  | MinQty | N | * 0 (zero)
* Less than `OrderQty` (#38)
* Equal to `OrderQty` (#38)

 | This field is sent only if the incoming customer order specifies a minimum quantity. This field can be ignored if `TimeInForce` (#59) is 4 (FOK).
Specifies how the order can be filled:* Partial fill: If the value is 0 (zero), the order amount can be filled multiple times until the entire amount is filled.
* Partial fill with market minimum: The order amount can be filled multiple times, but the first fill must be no less than the market minimum defined by the `MinQty` (#110) field. Subsequent fills have no size requirement.
* No partial fill: If the value is equal to the value of the `OrderQty` (#38) field, the order amount must be filled in its entirety with one fill. This is effectively an FOK order.

 | Qty(20) |
| 117  | QuoteID | See descr. | — | This is only required for `OrdType` (#40)=D (previously quoted) orders. The reference ID of the bid or offer dealing price. | String(11) |
| 167  | SecurityType | Y | * FOR
* FXFWD
* FXNDF

 | The security type or trade type:* FOR=Foreign Exchange Contract
* FXFWD=FX Forward (streaming outrights)
* FXNDF=Non-deliverable forward (streaming NDFs)

 | String(20) |
| 7540  | StreamID | N | — | The ID for the stream agreed by Integral and the maker.
If the maker does not support multi-stream pricing, this field is not included or is left empty. | String(30) |
| 100  | ExDestination | N | — | For external algos and other directed orders, the name of the target venue. | String(20) |
| 957  | NoStrategyParameters | N | — | Number of strategy parameters in this repeating group. | NumInGroup(3) |
| → | 958 | StrategyParameterName | N | — | Name of the parameter. | String(255) |
| → | 959 | StrategyParameterType | N | See descr. | Datatype of the parameter.
1=Int
2=Length
3=NumInGroup
4=SeqNum
5=TagNum
6=Float
7=Qty
8=Price
9=PriceOffset
10=Amt
11=Percentage
12=Char
13=Boolean
14=String
15=MultipleCharValue
16=Currency
17=Exchange
18=Month-Year
19=UTCTimeStamp
20=UTCTimeOnly
21=LocalMktDate
22=UTCDateOnly
23=Data
24=MultipleStringValue | int(2) |
| → | 960 | StrategyParameterValue | N | — | Value of the parameter. | String(1023) |
| 453  | NoPartyIDs | N | 1 | The number of groups of `PartyID` (#448), `PartyIDSource` (#447) and `PartyRole` (#452) fields that represent the ClientTag on the trade request, if any. If this component is included in the message, the value of the `NoPartyIDs` (#453) field always has the value of 1 (one), indicating a ClientTag. | NumInGroup(1) |
| → | 448 | PartyID | N | — | The ClientTag on the trade request. | String(20) |
| → | 447 | PartyIDSource | See descr. | D=Proprietary/Custom code | Identifies class or source of the `PartyID` (#448) value. Required if `PartyID` is specified. | char(1) |
| → | 452 | PartyRole | N | 3=Client ID | Identifies the type or role of the `PartyID` (#448) specified. | int(2) |


#### Order Status Request

(Integral to Maker)

Integral sends this message to the maker to request an Execution Report be sent with the order’s current status.
You should respond with an Execution Report message with the order's status and with the following fields set with values from the request when available:

* `ClOrdID` (#11)
* `OrderID` (#37)
* `OrdStatusReqID` (#790)


Order Status Request message fields 

| Tag | Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | H | — | String(2) |
| 790 | OrdStatusReqID | N | — | Optional, can be used to uniquely identify a specific Order Status Request message. Returned on Execution Report if provided. | String(11) |
| 11 | ClOrdID | See descr. | — | Required by the FIX specification, but not required by the FIX Maker ESP API. The unique ID assigned by Integral to the order, the `ClOrdID` (#11) of the originating New Order – Single message. This field is ignored if `OrderID` (#37) is included. | String(11) |
| 37 | OrderID | N | — | The order’s ID as assigned by Integral. If this field is included, the `ClOrdID` (#11) field is ignored. | String(20) |
| 54 | Side | Y | — | The order side from customer’s perspective. For FX swap, it is the side of the far leg.
1=Buy (Bid)
2=Sell (Offer)
This should be the same value as the one received from the associated New Order - Single message. | char(1) |
| 55 | Symbol | N | — | The symbol for the base and variable currencies of the currency pair in the following format:
*baseCCY*/*variableCCY*
(for example, “EUR/USD”) | String(35) |


#### Order Cancel Request

(Integral to Maker)

Integral sends this message to the maker to request cancellation of a previously submitted order.

You should respond with two Execution Report messages in the following order:

1. Execution Report (pending cancel): `ExecType` (#150)=6 and `OrdStatus` (#39)=6
2. Execution Report (canceled): `ExecType` (#150)=4 and `OrdStatus` (#39)=4


The following fields on the Execution Report should be set with values from the request when available:

* `ClOrdID` (#11)
* `OrderID` (#37)


Order Cancel Request message fields 

| Tag | Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | F | — | String(2) |
| 41 | OrigClOrdID | Y | — | The `ClOrdID` (#11) of the original order to be canceled. | String(11) |
| 11 | ClOrdID | See descr. | — | Unique ID of the cancel request. | String(11) |
| 37 | OrderID | N | — | The order’s ID as assigned by Integral. | String(20) |
| 54 | Side | Y | — | The order side from customer’s perspective. For FX swap, it is the side of the far leg.
1=Buy (Bid)
2=Sell (Offer)
This should be the same value as the one received from the associated New Order - Single message. | char(1) |
| 55 | Symbol | N | — | The symbol for the base and variable currencies of the currency pair in the following format:
*baseCCY*/*variableCCY*
(for example, “EUR/USD”) | String(35) |
| 60 | TransactTime | Y | — | The timestamp of the Execution Report creation in the format: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |


#### Order Timeout

(Integral to Maker)

When Integral is configured to automatically cancel timed-out orders, this message is sent to inform the maker that Integral did not receive an Execution Report message response (either an order rejection or a trade verification) for the order within the time-out period. The original order is effectively rejected. If Integral receives a trade verification or rejection after the order has been timed out, Integral sends a Don’t Know Trade message to the maker. This order time-out conversation happens in an order session. See [Order timeout](#order-timeout) for more information about the order timeout workflow.

Order Timeout message fields 

| Tag | Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | OT | — | String(2) |
| 11 | ClOrdID | Y | — | The unique ID assigned by Integral to the order, the `ClOrdID` (#11) of the originating New Order – Single message. This is the order for which no response was received. | String(11) |


#### Don’t Know Trade (DK)

(Integral to Maker)

The Don’t Know Trade (DK) message is sent to the maker if a fill, rejection, or any other terminal-state message is received by Integral for an order that has been timed out. See [Order timeout](#order-timeout) for more information about the order timeout workflow.

Don’t Know Trade (DK) message fields 

| Tag | Field Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | Q | — | String(2) |
| 17 | ExecID | Y | — | The maker’s unique trade ID of problem execution | String(20) |
| 54 | Side | See descr. | — | Required by the FIX specification, but not required by the FIX Maker ESP API. This field is included if it is present in the Execution Report from the maker. .The trade’s side from customer’s perspective. For FX swap, it is the side of the far leg.
1=Buy (Bid)
2=Sell (Offer) | char(1) |
| 37 | OrderID | Y | — | The maker’s order ID on the problem execution | String(20) |
| 55 | Symbol | Y | — | The symbol for the base and variable currencies of the currency pair in the following format:
*baseCCY/variableCCY*
(for example, “EUR/USD”) | String(35) |
| 127 | DKReason | Y | D | Reason for execution rejection.
D=No matching order | char(1) |


#### Execution Report

(Maker to Integral)

The maker sends an Execution Report message for the following events:

* Order filled/partially filled.
* Order status request received from Integral.
* Order cancellation in response to a cancel request.


The combination of the `OrdStatus` (#39) and `ExecType` (#150) fields indicate the current state of the order. See [Order state transition](#order-state-transition) for more information about order status.

Execution Report message fields 

| Tag | Field Name | Req’d | Values | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | 8 | — | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |
| 37 | OrderID | Y | — | The unique order ID assigned by your organization. | String(20) |
| 11 | ClOrdID | Y | — | A unique order ID assigned by Integral. It is the same value as sent by the customer in:* New Order - Single
* Order Status Request
* Order Cancel Request

 | String(11) |
| 790 | OrdStatusReqID | N | — | Uniquely identifies a specific Order Status Request message sent by Integral. Required if the Execution Report is a response to an Order Status Request. The `ExecType` (#150) is `I`=Order Status for this Execution Report. | String(1) |
| 17 | ExecID | Y | — | Unique ID for each order execution report. | String(20) |
| 40 | OrdType | N | D=Previously quoted
2=Limit
1=Market | The order type. See [Supported order types](#supported-order-types). | char(1) |
| 150 | ExecType | Y | — | Describes the type of execution report. These are the state transition events illustrated in [Order state transitions](#fig-order-state-transitions) except Order Status:
A=Pending new
0=New
4=Canceled
6=Pending Cancel
8=Rejected
C=Expired
F=Trade
I=Order Status
2=Fill | char(1) |
| 39 | OrdStatus | Y | — | Describes the current state of the order. The value 4=Canceled is not applicable to the API.
Valid values:
A=Pending New
0=New (outstanding)
1=Partial Fill (after order matching)
2=Filled (after order matching)
4=Canceled
6=Pending Cancel
8=Rejected (before or after order matching)
C=Expired | char(1) |
| 103 | OrdRejReason | N | — | Code to identify reason for order rejection.
Valid values:
0=Broker / Exchange option
1=Unknown symbol
2=Exchange closed
3=Order exceeds limit
4=Too late to enter
5=Unknown Order
6=Duplicate Order (duplicate `ClOrdID` (#11))
7=Duplicate of a verbally communicated order
8=Stale Order
9=Trade Along required
10=Invalid Investor ID
11=Unsupported order characteristic
12=Surveillance Option | int(2) |
| 1 | Account | N | — | The account ID. The value of this field is agreed upon by your organization and Integral. | String(30) |
| 32 | LastQty  | See descr. | — | For fills or partial fills, the quantity bought or sold on this fill.
If a fill or partial fill is received with this field not specified or set to zero, Integral rejects it with a Business Message Reject message. | Qty(20) |
| 119 | SettlCurrAmt | Y | — | FX spot, outright, NDF: Settled amount in terms of settlement currency specified by the `SettlCurrency` (#120) field. | Amt(20) |
| 120 | SettlCurrency | Y | — | FX spot, outright, NDF: Settled currency | Currency(3) |
| 64 | SettlDate | N (See descr.) | *YYYYMMDD* | Settlement date on the fill message at the maker’s end in *YYYYMMDD* format.
Integral strongly recommend that makers send their settlement date in all ESP fill messages. This field is required for streaming outrights and streaming NDFs.* FX spot: Spot date.
* FX outright and NDF: Value date (`MaturityDate` (#541) NDFs)

 | LocalMktDate(8) |
| 55 | Symbol | Y | — | The symbol for the base and variable currencies of the currency pair in the following format:
*baseCCY/variableCCY*
(for example, “EUR/USD”)
This should be the same value as the one received from the associated New Order - Single message. | String(35) |
| 54 | Side | Y | — | The order side from customer’s perspective.
1=Buy (Bid)
2=Sell (Offer)
This should be the same value as the one received from the associated New Order - Single message. | char(1) |
| 38 | OrderQty | N | — | FX spot: The total quantity ordered | Qty(20) |
| 44 | Price | N | — | Do not use this field to determine the price of a fill. Use `LastPx` (#31) instead. This should be the same value as the one received from the associated New Order - Single message.
The precision of this float value must be agreed upon by both the sending and the receiving parties
FX spot, outright, NDF: Spot price. | Price(20) |
| 15 | Currency | N | — | The dealt currency. This may be the base or term currency of a currency pair. | String(3) |
| 167 | SecurityType | Y | * FOR
* FXFWD
* FXNDF

 | The security type or trade type:* FOR=Foreign Exchange Contract
* FXFWD=FX Forward (streaming outrights)
* FXNDF=Non-deliverable forward (streaming NDFs)

 | String(20) |
| 60 | TransactTime | Y | — | The timestamp of the Execution Report creation.
The format is: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |
| 59 | TimeInForce | N | 0=Day
1=GTC
3=IOC
4=FOK
6=GTD | The time-in-force of the order. See [Order Expiry](#order-expiry-time-in-force). | char(1) |
| 151 | LeavesQty | Y | — | Amount not filled (equals `OrderQty` (#38) minus `CumQty` (#14)
FX spot, outright, NDF: Open amount. Responses for a complete fill or rejection are “0” (zero). Any value other than zero indicates a partial fill. | Qty(20) |
| 14 | CumQty | Y | — | FX spot, outright, NDF: Total filled amount. If `OrdStatus` (#39)=F (partial fill), this value is total amount filled at the time of the current fill. If `OrdStatus` (#39)=2 (filled), the value of this field is the same as the `OrderQty` (#38) field. If `OrdStatus` (#39)=8 (rejected), the value of this field is “0” (zero). | Qty(20) |
| 31 | LastPx | See descr. | — | The price of a fill to ensure trade reconciliation and to determine any price improvement.
FX spot, outright, NDF: Price at which the current or last fill was made. | Price(20) |
| 194 | LastSpotRate | See descr. | — | FX spot: Not applicable.
FX outright or NDF: Spot rate | Price(20) |
| 195 | LastForwardPoints | See descr. | — | FX spot: Not applicable.
FX outright or NDF: Forward points | PriceOffset(20) |
| 6 | AvgPx | Y | — | The average execution price for the filled amount specified in `CumQty` (#14) field). If this field is set, then the `CumQty` (#14) field must be set to a non-zero value to avoid errors. The precision of this float value must be agreed upon by both the sending and the receiving parties. Do not use this field to determine the price of a fill. Use `LastPx` (#31) instead. | Price(20) |
| 58 | Text | N | — | Free format text explaining the reason for rejection if the Order Execution Report message is sent because of order rejection (the `ExecType` (#150) field=“8”).
If the `Text` (#58) field includes the text “INTERNAL_SERVER_ERROR”, this indicates a serious error. Stop trading immediately and contact Business Support to resolve the issue. | String(150) |
| 75 | TradeDate | N | — | The trade date (*YYYYMMDD*) | LocalMktDate(8) |


#### Business Message Reject

(Bidirectional)

The Business Message Reject message is sent by both Integral and the maker:

* The maker rejects an order status request if the order does not exist (`RefMsgType` (#372)=H). See [Orders workflow](#orders-workflow).
* The maker rejects an order cancel request if the order does not exist (`RefMsgType` (#372)=F). See [Orders workflow](#orders-workflow).
* If an Execution Report message for a fill or partial fill is received with the `LastQty` (#32) field not specified or set to zero, Integral rejects it with a Business Message Reject message. See [LastQty](#tag-execution-report-lastqty).


Business Message Reject message fields 

| Tag | Field Name | Req’d | Value | Description | Type(length) |
|  --- | --- | --- | --- | --- | --- |
| 35 | MsgType | Y | j | — | String(2) |
| 52 | SendingTime | Y | — | All messages sent from the maker to Integral must include millisecond precision: `YYYYMMDD-HH:MM:SS.sss` | UTCTimestamp(21) |
| 372 | RefMsgType | Y | * H
* F
* Z

 | The `MsgType` (#35) of the message referred to:
H=Order Status Request (from server to reject an order status request if the order does not exist)
F=Order Cancel Request
Z=Quote Cancel (from client to cancel a Quote Request) | String(2) |
| 379 | BusinessRejectRefID | N | — | If the message is sent in response to an order status request (`RefMsgType` (#372)=H), this field contains the `ClOrdID` (#11) of the order status request being rejected.
If the message is sent to cancel an order (`RefMsgType` (#372)=F), this field contains the `ClOrdID` (#11) of the order being canceled.
If the message is sent to cancel a quote request (`RefMsgType` (#372)=Z), this field contains the `QuoteID` (#117) of the quote being canceled. | String(11) |
| 380 | BusinessRejectReason | Y | * 1
* 5

 | The reason for a Business Message Reject message. Required only for the order status reject from the maker.
1=Unknown ID is supported
5=Conditionally Required Field Missing | int(1) |
| 58 | Text | N | — | Free-format text string | String(150) |


## Examples

The FIX protocol uses the non-printing ASCII "Start of Heading" (SOH) character (also shown as "Control A" or "^A") as the delimiter between tags in the message.

The following examples replace the SOH character with "| " (pipe and space) characters so that the delimiters are visible and examples break across lines.

### Session management

#### Logon (order session)

`8=FIX.4.3| 9=78| 35=A| 34=1| 49=demo.fxgrid| 52=20250624-09:50:57.031| 56=order.MakerOrg| 98=0| 108=30| 141=N| 10=107| `

#### Logon (price session)

`8=FIX.4.3| 9=78| 35=A| 34=1| 49=demo.fxgrid| 52=20250624-09:50:57.032| 56=price.MakerOrg| 98=0| 108=30| 141=Y| 10=090| `

#### Logon (response, order session)

`8=FIX.4.3| 9=78| 35=A| 34=1| 49=order.MakerOrg| 52=20250624-09:50:56.967| 56=demo.fxgrid| 98=0| 108=30| 141=Y| 10=124| `

#### Logon (response, price session)

`8=FIX.4.3| 9=78| 35=A| 34=1| 49=price.MakerOrg| 52=20250624-09:50:56.968| 56=demo.fxgrid| 98=0| 108=30| 141=Y| 10=107| `

#### Logout (order session)

`8=FIX.4.3| 9=78| 35=5| 34=109| 49=demo.fxgrid| 52=20250624-13:58:16.225| 56=order.MakerOrg| 10=133| `

#### Logout (price session)

`8=FIX.4.3| 9=77| 35=5| 34=93| 49=demo.fxgrid| 52=20250624-13:58:16.225| 56=price.MakerOrg| 10=087| `

#### Logout (response, failed logon)

`8=FIX.4.4| 9=75| 35=5| 34=2889| 49=demo.maker| 52=20250704-21:01:00.971| 56=price.MakerOrg| 58=Unknown user ID| 10=100| `

#### Logout (response, order session)

`8=FIX.4.3| 9=78| 35=5| 34=135| 49=order.MakerOrg| 52=20250624-13:58:16.155| 56=demo.fxgrid| 10=134| `

#### Logout (response, price session)

`8=FIX.4.3| 9=80| 35=5| 34=17098| 49=price.MakerOrg| 52=20250624-13:58:16.155| 56=demo.fxgrid| 10=240| `

#### Heartbeat (incoming)

`8=FIX.4.3| 9=66| 35=0| 34=4| 49=order.MakerOrg| 52=20250624-09:51:27.963| 56=demo.fxgrid| 10=077| `

#### Heartbeat (outgoing)

`8=FIX.4.3| 9=66| 35=0| 34=5| 49=demo.fxgrid| 52=20250624-09:52:27.989| 56=order.MakerOrg| 10=087| `

#### Resend Request

`8=FIX.4.3| 9=107| 35=2| 34=240| 49=price.MakerOrg| 52=20250704-10:01:56.324| 56=demo.fxgrid| 7=2647| 16=0| 10=229| `

#### Sequence Reset

`8=FIX.4.3| 9=137| 35=4| 34=2672| 43=Y| 49=demo.fxgrid| 52=20250704-10:02:04.098| 56=price.MakerOrg| 122=20250704-10:02:04| 36=2680| 123=Y| 10=214| `

#### Session Level Reject

`8=FIX.4.3| 9=169| 35=3| 34=11| 49=order.MakerOrg| 50=FI220LE| 52=20250705-14:14:34.070| 56=demo.fxgrid| 57=DBNB| 128=orgID| 45=13| 58=Invalid tag number| 371=50| 372=8| 373=0| 10=113| `

#### Test Request

`8=FIX.4.3| 9=105| 35=1| 34=1089| 49=demo.fxgrid| 52=20250705-09:06:30.882| 56=price.MakerOrg| 112=TEST| 10=034| `

### Market data

#### Market Data Request

`8=FIX.4.3| 9=159| 35=V| 34=5| 49=demo.fxgrid| 52=20250518-21:51:48.272| 56=price.MakerOrg| 262=FXLP71300517de30117| 263=1| 264=0| 265=0| 7540=Stream1| 146=1| 55=EUR/USD| 460=4| 267=2| 269=0| 269=1| 10=183| `

#### Market Data Request Reject

`8=FIX.4.3| 9=132| 35=Y| 34=579967| 49=price.MakerOrg| 52=20250629-09:07:10.231| 56=demo.fxgrid| 58=USD/NOK is not supported| 262=FXLP130d828bd0c155| 10=041| `

#### Market Data Incremental Refresh

`8=FIX4.3| 9=1962| 35=X| 34=459648| 49=price.MakerOrg| 52=20250705-06:59:59.640| 56=demo.fxgrid| 268=29| 279=0| 269=0| 55=GBP/USD| 461=RCSXXX| 270=1.46934| 271=20000000| 63=0| 279=0| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47084| 271=20000000| 63=0| 279=0| 269=0| 55=GBP/USD| 461=RCSXXX| 270=1.46929| 271=25000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47034| 271=10000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47034| 271=10000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47039| 271=15000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47044| 271=20000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47044| 271=12000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47044| 271=12000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47049| 271=17000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47054| 271=22000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47054| 271=14000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47054| 271=14000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47059| 271=19000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47064| 271=24000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47064| 271=16000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47064| 271=16000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47069| 271=21000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47074| 271=26000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47074| 271=18000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47074| 271=18000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47079| 271=23000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47084| 271=28000000| 63=0| 279=2| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47084| 271=20000000| 63=0| 279=0| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47089| 271=25000000| 63=0| 279=0| 269=0| 55=GBP/USD| 461=RCSXXX| 270=1.46924| 271=30000000| 63=0| 279=0| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47094| 271=30000000| 63=0| 279=0| 269=0| 55=GBP/USD| 461=RCSXXX| 270=1.46934| 271=20000000| 63=0| 279=0| 269=1| 55=GBP/USD| 461=RCSXXX| 270=1.47084| 271=20000000| 63=0| 10=027| `

#### Market Data Snapshot/Full Refresh (multi-price quote)

`8=FIX.4.3| 9=505| 35=W| 34=4| 49=price.MakerOrg| 52=20250518-21:51:53.884| 56=demo.fxgrid| 55=EUR/USD| 262=FXLP71300517de30117| 268=6| 269=0| 270=1.403| 15=EUR| 271=1000000| 276=A| 282=1| 299=26 903010307270408449| 290=0| 269=0| 270=1.4046| 15=EUR| 271=5000000| 276=A| 282=1| 299=27 221090307220403130| 290=0| 269=0| 270=0| 15=EUR| 271=0| 276=A| 282=1| 299=28 4| 290=0| 269=1| 270=1.4074| 15=EUR| 271=1000000| 276=A| 282=1| 299=26 783080909280801987| 290=0| 269=1| 270=0| 15=EUR| 271=0| 276=A| 282=1| 299=27 3| 290=0| 269=1| 270=0| 15=EUR| 271=0| 276=A| 282=1| 299=28 5| 290=0| 460=4| 10=045| `

#### Market Data Snapshot/Full Refresh (multi-price quote, example 2)

`8=FIX.4.3| 9=505| 35=W| 34=4| 49=price.MakerOrg| 52=20250518-21:51:53.884| 56=demo.fxgrid| 55=EUR/USD| 262=FXLP71300517de30117| 268=6| 269=0| 270=1.403| 15=EUR| 271=1000000| 276=A| 282=1| 299=26 903010307270408449| 290=0| 269=0| 270=1.4046| 15=EUR| 271=5000000| 276=A| 282=1| 299=27 221090307220403130| 290=0| 269=0| 270=0| 15=EUR| 271=0| 276=A| 282=1| 299=28 4| 290=0| 269=1| 270=1.4074| 15=EUR| 271=1000000| 276=A| 282=1| 299=26 783080909280801987| 290=0| 269=1| 270=0| 15=EUR| 271=0| 276=A| 282=1| 299=27 3| 290=0| 269=1| 270=0| 15=EUR| 271=0| 276=A| 282=1| 299=28 5| 290=0| 460=4| 10=045| `

#### Market Data Snapshot/Full Refresh (multi-tier quote)

`8=FIX.4.3| 9=587| 35=W| 34=211847| 49=price.MakerOrg| 52=20250530-15:00:00.511| 56=demo.fxgrid| 55=USD/JPY| 262=PROVIDER1303fbc1e6211| 460=4| 541=20250601| 268=6| 269=0| 270=80.919| 15=USD| 271=1000000| 276=A| 282=PROVIDER| 299=151675397639\_B| 290=1| 269=1| 270=80.928| 15=USD| 271=1000000| 276=A| 282=PROVIDER| 299=151675397639\_O| 290=1| 269=0| 270=80.92| 15=USD| 271=3000000| 276=A| 282=PROVIDER| 299=151675397639\_B1| 290=2| 269=0| 270=80.91| 15=USD| 271=5000000| 276=A| 282=PROVIDER| 299=151675397639\_B2| 290=3| 269=1| 270=80.93| 15=USD| 271=3000000| 276=A| 282=PROVIDER| 299=151675397639\_O1| 290=2| 269=1| 270=80.94| 15=USD| 271=5000000| 276=A| 282=PROVIDER| 299=151675397639\_O2| 290=3| 10=161| `

### Trading

#### Order reject (New Order – Single, rejected order)

`8=FIX.4.3| 9=219| 35=D| 34=5|  49=demo.fxgrid| 52=20250518-21:28:47.037| 56=order.MakerOrg| 1=MakerAccnt| 11=FXI57748726| 15=EUR| 21=1| 38=1000000| 40=D| 44=1.4048| 54=2| 55=EUR/USD| 59=3| 60=20250518-21:28:47.036| 117=27 718040708200504334| 167=FOR| 7540=Stream1| 10=225| `

#### Order reject (reject, Execution Report)

`8=FIX.4.3| 9=253| 35=8| 34=6| 49=order.MakerOrg| 52=20250518-21:28:47.081| 56=demo.fxgrid| 1=MakerAccnt| 6=0| 11=FXI57748726| 14=0| 17=10130575412707914| 32=0| 37=CA-FXI57748726| 38=1000000| 39=8| 54=2| 55=EUR/USD| 58=Rate Moved| 60=20250518 21:28:47| 75=19700101| 119=0| 120=EUR| 150=8| 151=0| 167=FOR| 10=090| `

#### Order timeout (Execution Report)

`8=FIX.4.3| 9=92| 35=OT| 34=412| 49=demo.fxgrid| 52=20250601-00:54:25.130| 56=order.MakerOrg| 11=FXI107111| 10=157| `

#### Trade, full fill, multi fill, New Order – Single

`8=FIX.4.3| 9=219| 35=D| 34=4| 49=demo.fxgrid| 52=20250517-22:17:16.035| 56=order.MakerOrg| 1=MakerAccnt| 11=FXI57677008| 15=EUR| 21=1| 38=5000000| 40=D| 44=1.4047| 54=2| 55=EUR/USD| 59=3| 60=20250517-22:17:16.034| 117=27 299010107270301260| 167=FOR| 7540=Stream1| 10=196| `

#### Trade, full fill, multi fill, ExecutionReport, trade 1

`8=FIX.4.3| 9=302| 35=8| 34=4| 49=order.MakerOrg| 52=20250517-22:17:16.085| 56=demo.fxgrid| 1=MakerAccnt| 6=1.4047| 11=FXI57677008| 14=1000000| 17=FXI57677008-1305670636084-1| 31=1.4047| 32=1000000| 37=FXI57677008AC-| 38=5000000| 39=1| 54=2| 55=EUR/USD| 60=20250517-22:17:16| 75=20250518| 119=1000000| 120=EUR| 150=1| 151=4000000| 167=FOR| 10=211| `

#### Trade, full fill, multi fill, ExecutionReport, trade 2

`8=FIX.4.3| 9=296| 35=8| 34=5| 49=order.MakerOrg| 52=20250517-22:17:16.088| 56=demo.fxgrid| 1=MakerAccnt| 6=1.4047| 11=FXI57677008| 14=5000000| 17=FXI57677008-1305670636087-2| 31=1.4047| 32=4000000| 37=FXI57677008AC-| 38=5000000| 39=2| 54=2| 55=EUR/USD| 60=20250517-22:17:16| 75=20250518| 119=4000000| 120=EUR| 150=F| 151=0| 167=FOR| 10=207| `

#### Trade, full fill, single fill, New Order – Single

`8=FIX.4.3| 9=221| 35=D| 34=54| 49=demo.fxgrid| 52=20250505-21:35:35.375| 56=order.MakerOrg| 1=MakerAccnt1| 11=FXI57002344| 15=EUR| 21=1| 38=1000000| 40=D| 44=1.45455| 54=2| 55=EUR/USD| 59=3| 60=20250505-21:35:35.375| 64=20250510| 117=FXLP1312fc20dd75936| 167=FOR| 7540=Stream1| 10=056| `

#### Trade, full fill, single fill, Execution Report, pending new

`8=FIX.4.3| 9=229| 35=8| 34=65| 49=order.MakerOrg| 52=20250505-21:35:34.528| 56=demo.fxgrid| 1=MakerAccnt1| 6=0| 11=FXI57002344| 14=0| 17=FXI57002344| 37=FXI57002344| 38=1000000| 39=A| 44=1.45455| 54=2| 55=EUR/USD| 60=20250505-21:35:34| 119=0| 120=USD| 150=0| 151=0| 167=FOR| 10=180| `

#### Trade, full fill, single fill, Execution Report, new

`8=FIX.4.3| 9=229| 35=8| 34=66| 49=order.MakerOrg| 52=20250505-21:35:34.530| 56=demo.fxgrid| 1=MakerAccnt1| 6=0| 11=FXI57002344| 14=0| 17=FXI57002344| 37=FXI57002344| 38=1000000| 39=0| 44=1.45455| 54=2| 55=EUR/USD| 60=20250505-21:35:34| 119=0| 120=USD| 150=0| 151=0| 167=FOR| 10=157| `

#### Trade, full fill, single fill, Execution Report, trade

`8=FIX.4.3| 9=251| 35=8| 34=67| 49=order.MakerOrg| 52=20250505-21:35:34.986| 56=demo.fxgrid| 6=1.45455| 11=FXI57002344| 14=1000000| 17=S000000A0577ECA9E| 31=1.45455| 32=1000000| 37=FXI57002344| 38=1000000| 39=2| 54=2| 55=EUR/USD| 60=20250505-16:35:34| 119=1454550| 120=USD| 150=F| 151=0| 167=FOR| 10=049| `

#### Trade, partial fill, multi fill, New Order – Single

`8=FIX.4.3| 9=221| 35=D| 34=51| 49=demo.fxgrid| 52=20250505-21:34:17.255| 56=order.MakerOrg| 1=MakerAccnt1| 11=FXI57002340| 15=EUR| 21=1| 38=1000000| 40=D| 44=1.45453| 54=2| 55=EUR/USD| 59=3| 60=20250505-21:34:17.255| 64=20250510| 117=FXLP1312fc20dd75936| 167=FOR| 7540=Stream1| 10=039| `

#### Trade, partial fill, multi fill, Execution Report, order, pending new

`8=FIX.4.3| 9=229| 35=8| 34=59| 49=order.MakerOrg| 52=20250505-21:34:16.413| 56=demo.fxgrid| 1=MakerAccnt1| 6=0| 11=FXI57002340| 14=0| 17=FXI57002340| 37=FXI57002340| 38=1000000| 39=A| 44=1.45453| 54=2| 55=EUR/USD| 60=20250505-21:34:16| 119=0| 120=USD| 150=0| 151=0| 167=FOR| 10=160| `

#### Trade, partial fill, multi fill, Execution Report, order, new

`8=FIX.4.3| 9=229| 35=8| 34=60| 49=order.MakerOrg| 52=20250505-21:34:16.416| 56=demo.fxgrid| 1=MakerAccnt1| 6=0| 11=FXI57002340| 14=0| 17=FXI57002340| 37=FXI57002340| 38=1000000| 39=0| 44=1.45453| 54=2| 55=EUR/USD| 60=20250505-21:34:16| 119=0| 120=USD| 150=0| 151=0| 167=FOR| 10=138| `

#### Trade, partial fill, multi fill, Execution Report, trade 1

`8=FIX.4.3| 9=256| 35=8| 34=61| 49=order.MakerOrg| 52=20250505-21:34:16.877| 56=demo.fxgrid| 6=1.45453| 11=FXI57002340| 14=125000| 17=S000000A052D6F5AE| 31=1.45453| 32=125000| 37=FXI57002340| 38=1000000| 39=1| 54=2| 55=EUR/USD| 60=20250505-16:34:16| 119=181816.25| 120=USD| 150=1| 151=875000| 167=FOR| 10=027| `

#### Trade, partial fill, multi fill, Execution Report, trade 2

`8=FIX.4.3| 9=256| 35=8| 34=62| 49=order.MakerOrg| 52=20250505-21:34:18.568| 56=demo.fxgrid| 6=1.45453| 11=FXI57002340| 14=250000| 17=S000000A052F0BDAD| 31=1.45453| 32=125000| 37=FXI57002340| 38=1000000| 39=1| 54=2| 55=EUR/USD| 60=20250505-16:34:18| 119=181816.25| 120=USD| 150=1| 151=750000| 167=FOR| 10=026| `

#### Trade, partial fill, multi fill, Execution Report, order expiry

`8=FIX.4.3| 9=247| 35=8| 34=63| 49=order.MakerOrg| 52=20250505-21:34:36.098| 56=demo.fxgrid| 1=MakerAccnt1| 6=1.45453| 11=FXI57002340| 14=250000| 17=FXI57002340| 37=FXI57002340| 38=1000000| 39=C| 44=1.45453| 54=2| 55=EUR/USD| 60=20250505-21:34:16| 119=363632.5| 120=USD| 150=C| 151=750000| 167=FOR| 10=080| `

#### Trade, partial fill, single fill, New Order – Single

`8=FIX.4.3| 9=221| 35=D| 34=43| 49=demo.fxgrid| 52=20250505-21:31:01.762| 56=order.MakerOrg| 1=MakerAccnt1| 11=FXI57002334| 15=EUR| 21=1| 38=1000000| 40=D| 44=1.45444| 54=2| 55=EUR/USD| 59=3| 60=20250505-21:31:01.762| 64=20250510| 117=FXLP1312fc20dd75936| 167=FOR| 7540=Stream1| 10=029| `

#### Trade, partial fill, single fill, Execution Report, Order, pending new

`8=FIX.4.3| 9=229| 35=8| 34=48| 49=order.MakerOrg| 52=20250505-21:31:00.921| 56=demo.fxgrid| 1=MakerAccnt1| 6=0| 11=FXI57002334| 14=0| 17=FXI57002334| 37=FXI57002334| 38=1000000| 39=A| 44=1.45444| 54=2| 55=EUR/USD| 60=20250505-21:31:00| 119=0| 120=USD| 150=0| 151=0| 167=FOR| 10=151| `

#### Trade, partial fill, single fill, Execution Report, Order, new

`8=FIX.4.3| 9=229| 35=8| 34=49| 49=order.MakerOrg| 52=20250505-21:31:00.923| 56=demo.fxgrid| 1=MakerAccnt1| 6=0| 11=FXI57002334| 14=0| 17=FXI57002334| 37=FXI57002334| 38=1000000| 39=0| 44=1.45444| 54=2| 55=EUR/USD| 60=20250505-21:31:00| 119=0| 120=USD| 150=0| 151=0| 167=FOR| 10=137| `

#### Trade, partial fill, single fill, Execution Report, trade

`8=FIX.4.3| 9=253| 35=8| 34=50| 49=order.MakerOrg| 52=20250505-21:31:01.382| 56=demo.fxgrid| 6=1.45444| 11=FXI57002334| 14=125000| 17=S000000A0472FF846| 31=1.45444| 32=125000| 37=FXI57002334| 38=1000000| 39=1| 54=2| 55=EUR/USD| 60=20250505-16:31:01| 119=181805| 120=USD| 150=1| 151=875000| 167=FOR| 10=083| `

#### Trade, partial fill, single fill, Execution Report, order expiry

`8=FIX.4.3| 9=245| 35=8| 34=51| 49=order.MakerOrg| 52=20250505-21:31:07.263| 56=demo.fxgrid| 1=MakerAccnt1| 6=1.45444| 11=FXI57002334| 14=125000| 17=FXI57002334| 37=FXI57002334| 38=1000000| 39=C| 44=1.45444| 54=2| 55=EUR/USD| 60=20250505-21:31:00| 119=181805| 120=USD| 150=C| 151=0| 167=FOR| 10=221| `

#### Trade, term currency, New Order – Single

`8=FIX.4.3| 9=219| 35=D| 34=4| 49=demo.fxgrid| 52=20250518-21:52:29.916| 56=order.MakerOrg| 1=MakerAccnt| 11=FXI57748770| 15=USD| 21=1| 38=5000000| 40=D| 44=1.4045| 54=1| 55=EUR/USD| 59=3| 60=20250518-21:52:29.916| 117=27800090007270703184| 167=FOR| 7540=Stream1| 10=230| `

#### Trade, term currency, Execution Report, trade 1

`8=FIX.4.3| 9=303| 35=8| 34=4| 49=order.MakerOrg| 52=20250518-21:52:29.962| 56=demo.fxgrid| 1=MakerAccnt| 6=1.4045| 11=FXI57748770| 14=1404500| 17=FXI57748770-1305755549961-55| 31=1.4045| 32=1404500| 37=FXI57748770AC-| 38=5000000| 39=1| 54=1| 55=EUR/USD| 60=20250518-21:52:29| 75=20250519| 119=1404500| 120=USD| 150=1| 151=3595500| 167=FOR| 10=110| `

#### Trade, term currency, Execution Report, trade 2

`8=FIX.4.3| 9=303| 35=8| 34=5| 49=order.MakerOrg| 52=20250518-21:52:29.962| 56=demo.fxgrid| 1=MakerAccnt| 6=1.4045| 11=FXI57748770| 14=2809000| 17=FXI57748770-1305755549961-56| 31=1.4045| 32=1404500| 37=FXI57748770AC-| 38=5000000| 39=1| 54=1| 55=EUR/USD| 60=20250518-21:52:29| 75=20250519| 119=1404500| 120=USD| 150=1| 151=2191000| 167=FOR| 10=103| `

#### Trade, term currency, Execution Report, order expiry

`8=FIX.4.3| 9=260| 35=8| 34=6| 49=order.MakerOrg| 52=20250518-21:52:29.963| 56=demo.fxgrid| 1=MakerAccnt| 6=1.4045| 11=FXI57748770| 14=2809000| 17=COMPLETE| 32=0| 37=COMPLETEFXI57748770| 38=5000000| 39=C| 54=1| 55=EUR/USD| 60=20250518-21:52:29| 75=19700101| 119=0| 120=USD| 150=C| 151=0| 167=FOR| 10=057| `

### Trading session

#### Trading Session Status Request (order session)

`8=FIX.4.3| 9=95| 35=g| 34=2| 49=demo.fxgrid| 52=20250624-09:50:57.032| 56=order.MakerOrg| 263=0| 335=Order1308909057032| 10=246| `

#### Trading Session Status Request (price session)

`8=FIX.4.3| 9=95| 35=g| 34=2| 49=demo.fxgrid| 52=20250624-09:50:57.032| 56=price.MakerOrg| 263=0| 335=Price1308909057032| 10=219| `

#### Trading Session Status (open, order session)

`8=FIX.4.3| 9=111| 35=h| 34=2| 49=order.MakerOrg| 52=20250505-21:05:07.185| 56=demo.fxgrid| 325=N| 335=Order1304629507988| 336=20250505| 340=2| 10=096| `

#### Trading Session Status (open, price session)

`8=FIX.4.3| 9=111| 35=h| 34=2| 49=price.MakerOrg| 52=20250505-21:05:07.189| 56=demo.fxgrid| 325=N| 335=Price1304629507988| 336=20250505| 340=2| 10=073| `

## Changes

This appendix provides information about the changes to the last five versions of this document. The information is in chronological order from newest to oldest.

Document changes 

| Date | API Version | Enhancements |
|  --- | --- | --- |
| November 2025
(2.1v24) | 2.1 | Expanded and corrected description of values and formats for `SettlDate` (#64) in:* [Market Data Snapshot/Full Refresh](#market-data-snapshotfull-refresh)
* [New Order – Single](#new-order--single)
* [Execution Report](#execution-report)

 |
| October 2025
(2.1v23) | 2.1 | * Added "Day" to `TimeInForce` (#59) in [Order expiry](#order-expiry-time-in-force).
* Added `ExpireTime` (#126) to [New Order – Single](#new-order--single) to support GTT/GTD time in force (`TimeInForce` (#59)=6).
* Added [Directed orders](#directed-orders) and [External algos](#external-algos).
* Added `SettlDate` (#64) to [Market Data Snapshot/Full Refresh](#market-data-snapshotfull-refresh).
* Added to [New Order – Single](#new-order--single) to support external algos:
  * `ExDestination` (#100).
  * `NoStrategyParameters` (#957) repeating group.
* Added the following messages and related workflow fields and values to existing messages:
  * Workflow description in [Order status](#order-status).
  * [Order Status Request](#order-status-request).
  * Response to Order Status Request `OrdStatusReqID` (#790) to [Execution Report](#execution-report).
  * Workflow description in [Order cancel](#order-cancel).
  * [Order Cancel Request](#order-cancel-request).
  * Response to cancel request values 4=Canceled and 6=Pending Cancel to `OrdStatus` (#39) and `ExecType` (#150) to [Execution Report](#execution-report).

 |
| May 2024
(2.1v22) | 2.1 | Minor edits. No API change. |