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)
status | Meaning | Version |
|---|---|---|
omitted or New | Book a new trade | Starts at 1 |
Amend | Full replacement of a live trade | Increments (2, 3, …) |
Cancel | Cancel a live trade | Unchanged |
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)
| Field | Who may omit it | What happens |
|---|---|---|
executingBroker | Uploading company is an executing broker or full-service broker | Filled with the uploader (or the uploader's alias) |
clearingBroker | Uploading company is an executing or full-service broker, or executingBroker is supplied | Derived 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).
clientcannot 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).statusandversiondo not count as a change. - Confirmation is reset to
Unconfirmed(including trades that wereAutoConfirmed). - Multi-leg: replace the whole
legsarray 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
| Strategy | Min Legs | Description |
|---|---|---|
| CalendarSpread | 2 | Different expiration dates, same strike |
| CalendarStrip | 2 | Buy/Sell consecutive expiries |
| VerticalSpread | 2 | Same expiration, different strikes |
| Straddle | 2 | Buy/Sell both call and put at same strike |
| Strangle | 2 | Buy/Sell call and put at different strikes |
| Butterfly | 3 | Three strikes with defined wings |
| Condor | 4 | Four different strikes |
| IronButterfly | 4 | Short butterfly with protective wings |
| IronCondor | 4 | Short strangle with protective collars |
| Strip | 3 | One call + two puts |
| Strap | 3 | Two calls + one put |
| Custom | 2 | User-defined structure |
Multi-Leg Validation Rules
- Legs inherit
client,tradeDate,clearingBroker,clearingAccount,executingBroker, andexecutingAccountfrom 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
tradeIDper 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)
| Condition | Typical message |
|---|---|
Duplicate tradeID in this request | Trade ID [%s] is not unique within file |
| New collides with a live row | Trade ID [%s] is not unique |
| Amend, original archived or missing | Trade ID [%s] cannot be amended — original not available |
| Amend of a cancelled trade | Trade ID [%s] is cancelled and cannot be amended |
Amend changes client | Trade ID [%s] cannot be amended — client cannot be changed; cancel the original and re-book |
| Amend with no business-field change | Trade ID [%s] cannot be amended — no fields changed |
| Cancel, original archived or missing | Trade ID [%s] cannot be cancelled — original not available |
| Cancel matches several live rows | Trade ID [%s] matches more than one live trade — include tradeDate |
| Cancel of an already cancelled trade | Trade ID [%s] is already cancelled |
| Invalid / ambiguous LEI | Invalid 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