Skip to main content

Upload Active Trades

Allow the user with a valid API key to upload trades into the daily blotter. The same endpoint creates, amends, and cancels. There is no PUT or PATCH.

URL : /api/trade

Method : POST

Auth required : YES (API Key)

Permissions required : None

Request headers

X-API-KEY: "<api_key>"
X-API-SECRET: "<api_secret>"
Content-Type: application/json

The body is always a JSON array of trade objects, including a single-trade upload.


Lifecycle (status)

statusMeaningVersion
omitted or NewBook a new tradeStarts at 1
AmendFull replacement of a live tradeIncrements (2, 3, …)
CancelCancel a live tradeUnchanged

Unknown values are rejected. version is server-owned and ignored on input. The user tradeID is never rewritten.


Uniqueness

A live trade is unique on (tradeID, tradeDate, executingBroker), not on tradeID alone. The same tradeID may exist for a different date or executing broker.

Duplicates in the same request fail with Trade ID […] is not unique within file. A New that collides with a live row fails with Trade ID […] is not unique. Historical (EOD-archived) rows are not part of that key: Amend or Cancel after archive fails with “original not available”.


Company identifiers

client, executingBroker, clearingBroker, and carryBroker accept either:

  • the VOCSET short name shown in the GUI, or
  • an ISO 17442 LEI (20 characters, valid checksum).

An invalid checksum returns Invalid LEI for {field} [{value}]. A LEI that maps to more than one company returns Ambiguous LEI for {field} [{value}].


Omitting brokers (1.2.0)

FieldWho may omit itWhat happens
executingBrokerUploading company is an executing broker or full-service brokerFilled with the uploader (or the uploader's alias)
clearingBrokerUploading company is an executing or full-service broker, or executingBroker is suppliedDerived from clearingAccount

Everyone else must send both. clearingAccount remains mandatory for New and Amend.


Data constraints (New and Amend)

Amend is a full replacement: send the same mandatory fields as New, plus "status": "Amend". Optional fields that are omitted or blank on an Amend are stored as null (they are not left at the previous value).

{
"tradeID": "<MANDATORY>",
"status": "New|Amend <OPTIONAL — omit for New>",
"traceID": "<OPTIONAL>",
"tradeDate": "YYYY-MM-DD <MANDATORY> cannot be in the future",
"side": "Buy|Sell <MANDATORY>",
"quantity": "676 <MANDATORY> integer — up to 32 digits, no decimals",
"price": "2009 <MANDATORY> decimal — up to 24 digits + 8 dps",
"instrumentCode": "String <MANDATORY> contract code only, no maturity",
"maturity": "YYYY-MM-DD <MANDATORY>",
"strike": "Decimal <MANDATORY when assetClass=Option>",
"optionType": "Call|Put <MANDATORY when assetClass=Option>",
"mic": "String <MANDATORY for Future/Option/Equity>",
"client": "String <MANDATORY> short name or LEI — immutable on Amend",
"executingAccount": "String <OPTIONAL>",
"executingBroker": "String <OPTIONAL for EB/FSB uploaders> short name or LEI",
"productDescription": "String <OPTIONAL>",
"clearingAccount": "String <MANDATORY>",
"clearingBroker": "String <OPTIONAL for EB/FSB, or when executingBroker is sent>",
"carryBroker": "String <OPTIONAL> only when requested",
"subAccountCode": "String <OPTIONAL>",
"comment": "String <OPTIONAL>",
"executionTime": "DateTime(ISO 8601) <MANDATORY> example: 2024-12-01T14:00:04-05:00",
"giveupTime": "DateTime(ISO 8601) <OPTIONAL>",
"assetClass": "Future|Option <MANDATORY>"
}

Amend rules

  • The original must still be on the live blotter (not archived, not cancelled).
  • client cannot change. Cancel the original and re-book if the client is wrong.
  • If no business field differs from the live row, the call is rejected (cannot be amended — no fields changed). status and version do not count as a change.
  • Confirmation is reset to Unconfirmed (including trades that were AutoConfirmed).
  • Multi-leg: replace the whole legs array as a set.

Business fields compared for the no-op check: side, quantity, price, tradeDate, clearingDate, maturity, currency, mic, assetClass, productDescription, instrumentCode, instrumentCodeType, strike, optionType, executingBroker, executingAccount, subAccount, clearingBroker, clearingAccount, carryBroker, comment, executionTime, giveupTime, strategyName, and each leg.


Data constraints (Cancel)

Only tradeID and status are mandatory. tradeDate, executingBroker, and client are optional disambiguators. All other fields are ignored.

{
"tradeID": "<MANDATORY>",
"status": "Cancel",
"tradeDate": "YYYY-MM-DD <OPTIONAL — required if more than one live row matches>",
"executingBroker": "String <OPTIONAL>",
"client": "String <OPTIONAL>"
}

If more than one live row has that tradeID, the row is rejected with matches more than one live trade — include tradeDate. Cancelling a parent cancels the whole multi-leg structure. Confirmation is left as-is (no new confirm cycle).


Data constraints (Multi-Leg Trades)

Multi-leg trades use a parent-child structure. The parent contains a legs array. Strategy parents must not send instrumentCode, optionType, or a product MIC — those live on the legs. The parent exchange is taken from the first resolved leg.

{
"tradeID": "<MANDATORY> unique identifier for parent trade",
"status": "New|Amend|Cancel <OPTIONAL>",
"strategyName": "CalendarSpread|CalendarStrip|VerticalSpread|Straddle|Strangle|Butterfly|Condor|IronButterfly|IronCondor|Strip|Strap|Custom <OPTIONAL>",
"tradeDate": "YYYY-MM-DD <MANDATORY> cannot be in the future",
"side": "Buy|Sell <MANDATORY>",
"quantity": "<MANDATORY>",
"price": "<MANDATORY> can be 0 for spread trades",
"instrumentCode": "omit on the parent",
"maturity": "YYYY-MM-DD <MANDATORY>",
"client": "String <MANDATORY>",
"clearingAccount": "String <MANDATORY>",
"clearingBroker": "String <see Omitting brokers>",
"executionTime": "DateTime(ISO 8601) <MANDATORY>",
"assetClass": "Future|Option <MANDATORY>",
"legs": [
{
"tradeID": "<MANDATORY> unique identifier for leg",
"side": "Buy|Sell <MANDATORY>",
"quantity": "<MANDATORY>",
"price": "<MANDATORY>",
"instrumentCode": "String <MANDATORY>",
"maturity": "YYYY-MM-DD <MANDATORY>",
"mic": "String <MANDATORY>",
"executionTime": "DateTime(ISO 8601) <MANDATORY>",
"assetClass": "Future|Option <MANDATORY>"
}
]
}

Strategy Types and Minimum Leg Requirements

StrategyMin LegsDescription
CalendarSpread2Different expiration dates, same strike
CalendarStrip2Buy/Sell consecutive expiries
VerticalSpread2Same expiration, different strikes
Straddle2Buy/Sell both call and put at same strike
Strangle2Buy/Sell call and put at different strikes
Butterfly3Three strikes with defined wings
Condor4Four different strikes
IronButterfly4Short butterfly with protective wings
IronCondor4Short strangle with protective collars
Strip3One call + two puts
Strap3Two calls + one put
Custom2User-defined structure

Multi-Leg Validation Rules

  • Legs inherit client, tradeDate, clearingBroker, clearingAccount, executingBroker, and executingAccount from the parent.
  • Multi-leg trades must have at least 2 legs (or more depending on strategy).
  • If any leg fails validation, the entire parent trade is rejected.
  • One tradeID per request element; in-file duplicates still error.

Note for client, executingBroker, clearingBroker, executingAccount, clearingAccount: use the company codes visible in the VOCSET GUI (or a LEI as above).


Data examples

New (single-leg)

[
{
"tradeID": "20241119-001",
"tradeDate": "2024-11-19",
"side": "Buy",
"quantity": "676",
"price": "2009",
"instrumentCode": "CL",
"maturity": "2024-12-01",
"mic": "XNYM",
"client": "CTCINC",
"productDescription": "Brent Crude",
"clearingAccount": "GC123",
"clearingBroker": "DBAG",
"executionTime": "2024-11-19T14:00:04-05:00",
"giveupTime": "2024-11-19T14:01:00-05:00",
"assetClass": "Future"
}
]

status may be omitted; the server treats that as New.

Amend (full replacement)

[
{
"tradeID": "20241119-001",
"status": "Amend",
"tradeDate": "2024-11-19",
"side": "Buy",
"quantity": "700",
"price": "2010.5",
"instrumentCode": "CL",
"maturity": "2024-12-01",
"mic": "XNYM",
"client": "CTCINC",
"productDescription": "Brent Crude",
"clearingAccount": "GC123",
"clearingBroker": "DBAG",
"executionTime": "2024-11-19T14:00:04-05:00",
"assetClass": "Future"
}
]

Cancel (identifiers only)

[
{
"tradeID": "20241119-001",
"status": "Cancel"
}
]

Disambiguate if needed:

[
{
"tradeID": "20241119-001",
"status": "Cancel",
"tradeDate": "2024-11-19",
"executingBroker": "JJFUTLTD"
}
]

Multi-Leg Trade Example (Calendar Spread)

[
{
"tradeID": "ML-20241119-001",
"strategyName": "CalendarSpread",
"tradeDate": "2024-11-19",
"side": "Buy",
"quantity": "10",
"price": "0",
"maturity": "2025-01-01",
"client": "CTCINC",
"productDescription": "Crude Oil Calendar Spread",
"clearingAccount": "GC123",
"clearingBroker": "DBAG",
"executionTime": "2024-11-19T14:00:04-05:00",
"assetClass": "Future",
"legs": [
{
"tradeID": "ML-20241119-001-L1",
"side": "Buy",
"quantity": "10",
"price": "70.50",
"instrumentCode": "CL",
"maturity": "2025-01-01",
"mic": "XNYM",
"executionTime": "2024-11-19T14:00:04-05:00",
"assetClass": "Future"
},
{
"tradeID": "ML-20241119-001-L2",
"side": "Sell",
"quantity": "10",
"price": "71.25",
"instrumentCode": "CL",
"maturity": "2025-02-01",
"mic": "XNYM",
"executionTime": "2024-11-19T14:00:04-05:00",
"assetClass": "Future"
}
]
}
]

Success Responses

Condition : Payload is well-formed and the user is authenticated. Inspect each element — some rows may still have failed.

Code : 200 OK

{
"timestamp": "2024-11-21T17:16:12.424011385Z",
"status": 200,
"result": [
{
"id": "20241119-001",
"status": "OK",
"message": ""
}
],
"path": "/api/trade"
}

Success Response (Partial)

Code : 200 OK

{
"timestamp": "2024-11-21T17:16:12.424011385Z",
"status": 200,
"result": [
{
"id": "20241119-001",
"status": "ERROR",
"message": "Trade ID [20241119-001] is not unique",
"field": "tradeID",
"value": "20241119-001"
},
{
"id": "20241119-002",
"status": "OK",
"message": ""
}
],
"path": "/api/trade"
}

A mixed batch is possible: HTTP 200 with per-row status: ERROR. Only the OK rows are booked.


Error table (per-row message)

ConditionTypical message
Duplicate tradeID in this requestTrade ID [%s] is not unique within file
New collides with a live rowTrade ID [%s] is not unique
Amend, original archived or missingTrade ID [%s] cannot be amended — original not available
Amend of a cancelled tradeTrade ID [%s] is cancelled and cannot be amended
Amend changes clientTrade ID [%s] cannot be amended — client cannot be changed; cancel the original and re-book
Amend with no business-field changeTrade ID [%s] cannot be amended — no fields changed
Cancel, original archived or missingTrade ID [%s] cannot be cancelled — original not available
Cancel matches several live rowsTrade ID [%s] matches more than one live trade — include tradeDate
Cancel of an already cancelled tradeTrade ID [%s] is already cancelled
Invalid / ambiguous LEIInvalid LEI for %s [%s] / Ambiguous LEI for %s [%s]
executingBroker required%s is required unless the uploading company is an executing or full-service broker
clearingBroker required%s is required unless the uploading company is an executing or full-service broker, or executingBroker is supplied

Error Response

Condition : The payload cannot be parsed, or every row failed in a way that surfaces as a request error.

Code : 400 BAD REQUEST

Error Response

Condition : Unexpected server error.

Code : 500 INTERNAL SERVER ERROR