Administrative REST API Reference
The Administrative REST API lets operators and automation scripts control a running Ember installation: halt and resume trading, manage risk limits and positions, and control services and FIX sessions. To enable the API and set up authentication, see Administrative API Configuration.
Conventions
- Base URL:
https://<monitor-host>:<port>/api/admin/v1 - Request and response bodies are JSON (
application/json, UTF-8). - Decimal values (position size, average cost, PnL, limits) are transferred as JSON strings to preserve full precision, for example
"-1.5". Absent values are returned asnull. - Projection path identifies a node in the position/risk tree, for example
Source[FIXTRADER1]/Account[GOLD]. An empty string or an omitted value means the root level (system-wide). - Projection is a
/-separated list of projection keys, for exampleExchange/SymbolorAccount/Symbol. An empty string is the root level. - Requests to Ember wait up to 10 seconds for a response.
- Mutating requests are never retried by the server. Do not blindly retry them in clients either: a request that timed out may still have been applied. Re-read the state first.
- Every mutating operation is written to the Ember Monitor log with the name of the user who made it.
OpenAPI Specification
Machine-readable OpenAPI 3.1 documentation is generated by the server and requires the same credentials as the API:
| URL | Description |
|---|---|
/v3/api-docs | OpenAPI document (JSON) |
/swagger-ui.html | Interactive Swagger UI |
Use the OpenAPI document to generate typed clients.
Error Handling
Errors return a JSON body:
{
"status": 400,
"error": "Bad Request",
"message": "Unknown projection key: Acount"
}
| Status | Meaning |
|---|---|
400 Bad Request | Malformed or invalid request (missing required field, invalid decimal, unknown projection key, risk update rejected by Ember) |
401 Unauthorized | Missing, expired or invalid credentials. Returned by the security layer, without the JSON body above |
403 Forbidden | Authenticated user lacks the required permission. The message names the permission |
404 Not Found | Unknown service, FIX gateway or FIX session |
429 Too Many Requests | Ember message bus is overloaded. Retry later |
503 Service Unavailable | Ember message bus is not available |
504 Gateway Timeout | Ember did not respond within 10 seconds |
500 Internal Server Error | Unexpected failure. See the Ember Monitor log |
API Reference
Trading Control
Get Trading Status
GET /api/admin/v1/trading/status
Returns the current kill switch state at a projection path.
| Query parameter | Type | Description |
|---|---|---|
projectionPath | string, optional | Projection path, for example Source[FIXTRADER1]/Account[GOLD]. Default: system-wide |
Response 200
| Field | Type | Description |
|---|---|---|
projectionPath | string | Projection path the state belongs to. Empty means system-wide |
halted | boolean | true when trading is halted |
reason | string | Reason reported by the last kill switch event |
{ "projectionPath": "", "halted": true, "reason": "Emergency drill by alice via Ember admin API" }
Halt Trading
POST /api/admin/v1/trading/halt
Halts trading system-wide or at a projection path. Requires HALT_RESUME_TRADING.
Request body
| Field | Type | Description |
|---|---|---|
projectionPath | string, optional | Projection path. Empty or omitted means system-wide |
reason | string, optional | Reason recorded in the audit log. Default: Trading halted |
cancelOrders | boolean, optional | Cancel working orders. Honored by Ember only for system-wide halt. Default: false |
{ "projectionPath": "", "reason": "Emergency drill", "cancelOrders": false }
Response 200, empty body. The halt is asynchronous, use Get Trading Status to confirm it.
Resume Trading
POST /api/admin/v1/trading/resume
Resumes trading system-wide or at a projection path. Requires HALT_RESUME_TRADING.
Request body
| Field | Type | Description |
|---|---|---|
projectionPath | string, optional | Projection path. Empty or omitted means system-wide |
reason | string, optional | Reason recorded in the audit log. Default: Trading resumed |
Response 200, empty body.
Risk Limits
Get Risk Table
GET /api/admin/v1/risk/table
Returns the risk case table of a projection.
| Query parameter | Type | Description |
|---|---|---|
projection | string, optional | Projection, for example Account/Symbol. Default: root level |
Response 200
| Field | Type | Description |
|---|---|---|
projection | string | Projection of the table |
rows | array | Table rows |
rows[].conditions | object | Conditional columns keyed by projection key, for example {"Account": "GOLD"} |
rows[].limits | object | Limit values keyed by limit name, for example {"MaxOrderSize": "100"}. A null value means unlimited |
{
"projection": "Account",
"rows": [
{ "conditions": { "Account": "GOLD" }, "limits": { "MaxOrderSize": "100", "MaxOrderNotional": null } }
]
}
Update Risk Table
POST /api/admin/v1/risk/update
Applies a batch of changes to a risk case table. Requires CHANGE_RISK_LIMITS. If Ember rejects the update, the API returns 400 with the reason.
Request body
| Field | Type | Description |
|---|---|---|
projection | string, required | Projection of the table, for example Account/Symbol. Empty string for root level |
commands | array, required | One or more commands, must not be empty |
commands[].type | enum, required | INSERT, UPDATE or DELETE |
commands[].conditions | object, required | Conditional columns identifying the row. Keys are projection keys and must follow the order of the projection. Use "*" as a wildcard |
commands[].limits | object | Limits to apply, for example {"MaxOrderSize": "100"}. Ignored for DELETE |
{
"projection": "Account/Symbol",
"commands": [
{ "type": "UPDATE", "conditions": { "Account": "GOLD", "Symbol": "*" }, "limits": { "MaxOrderSize": "100" } },
{ "type": "DELETE", "conditions": { "Account": "SILVER", "Symbol": "*" } }
]
}
Response 200 – the risk table as it looks after the update, same format as Get Risk Table.
Positions
Query Positions
POST /api/admin/v1/positions
Returns positions of a projection across all order sources. This is a read-only operation despite using POST.
Request body
| Field | Type | Description |
|---|---|---|
projection | string, required | Position projection configured in Ember, for example Exchange/Symbol |
source | string, optional | Order source owning the position |
destination | string, optional | Destination owning the position |
account | string, optional | Account |
traderId | string, optional | Trader |
traderGroup | string, optional | Trader group |
exchange | string, optional | Exchange |
userData | string, optional | User data |
symbol | string, optional | Instrument. Also matches Currency and RootSymbol projections |
moduleKey | string, optional | Module key |
portfolioKey | string, optional | Portfolio key |
Optional fields narrow the result.
{ "projection": "Exchange/Symbol", "exchange": "CME" }
Response 200 – array of positions:
| Field | Type | Description |
|---|---|---|
projection | string | Projection path of the position |
source, destination, account, trader, traderGroup, exchange, userData, symbol, moduleKey, portfolioKey | string | Projection keys of the position. Present only for keys that are part of the projection |
size | decimal string | Position size (negative for short) |
averageCost | decimal string | Average cost |
realizedPnL | decimal string | Realized PnL |
unrealizedPnL | decimal string | Unrealized PnL |
marketValue | decimal string | Market value |
totalCommission | decimal string | Total commission |
openBuySize | decimal string | Size of open buy orders |
openSellSize | decimal string | Size of open sell orders |
[
{
"projection": "Exchange[CME]/Symbol[ESZ26]",
"exchange": "CME",
"symbol": "ESZ26",
"size": "10",
"averageCost": "6543.25",
"realizedPnL": "125.5",
"unrealizedPnL": "-12.25",
"marketValue": "65432.5",
"totalCommission": "4.2",
"openBuySize": "0",
"openSellSize": "5"
}
]
Adjust Position
POST /api/admin/v1/positions/adjust
Sets or changes the position at a projection path. Requires POSITION_ADJUSTMENT.
Request body
| Field | Type | Description |
|---|---|---|
projectionPath | string, required | Position projection path, for example Source[FIXTRADER1]/Account[GOLD]. Empty for root level |
size | decimal string, required | New position size, or the change when relative is true |
relative | boolean, optional | When true the size is added to the current value, otherwise it replaces it. Default: false |
averageCost | decimal string, optional | New average cost. NaN stops tracking average cost |
realizedPnL | decimal string, optional | New realized PnL. NaN stops tracking realized PnL |
{ "projectionPath": "Source[FIXTRADER1]/Account[GOLD]/Symbol[ESZ26]", "size": "-1.5", "relative": true }
Response 200, empty body. An invalid decimal results in 400.
Services
A service is a trade connector or an algorithm known to Ember.
List Services
GET /api/admin/v1/services
Response 200 – array of services:
| Field | Type | Description |
|---|---|---|
name | string | Service identifier used to enable or disable it |
type | enum | Service type (for example Algorithm or Connector) |
system | boolean | System algorithms do not accept orders |
dma | boolean | Service provides direct market access |
enabled | boolean | Whether the service currently accepts orders |
status | enum | Connected or Disconnected. Applicable to trade connectors only |
[ { "name": "FIX1", "type": "Connector", "system": false, "dma": true, "enabled": true, "status": "Connected" } ]
Get Service
GET /api/admin/v1/services/{name}
Returns a single service in the format above. 404 if the service is unknown.
Disable Service
POST /api/admin/v1/services/{name}/disable
Requires ENABLE_DISABLE_SERVICE. The request body is optional:
| Field | Type | Description |
|---|---|---|
reason | string, optional | Reason recorded in the audit log. Default: Service disabled |
{ "reason": "Venue maintenance window" }
Response 200, empty body.
Enable Service
POST /api/admin/v1/services/{name}/enable
Requires ENABLE_DISABLE_SERVICE. Same optional request body as Disable Service (default reason Service enabled). Response 200, empty body.
FIX Gateways and Sessions
List FIX Gateways
GET /api/admin/v1/fix/gateways
Response 200 – array of gateways:
| Field | Type | Description |
|---|---|---|
gatewayName | string | Gateway name |
gatewayType | enum | MarketData, OrderEntry, RFQ or TradeConnector |
updateTimestamp | long | Time of the last update, epoch milliseconds |
Get FIX Gateway
GET /api/admin/v1/fix/gateways/{gateway}
Returns the fields above plus statistics:
| Field | Type | Description |
|---|---|---|
sessions | long | Number of sessions |
acceptedConnections, rejectedConnections | long | Connection counters |
messagesSent, messagesReceived | long | Message counters |
bytesSent, bytesReceived | long | Traffic counters |
List FIX Sessions
GET /api/admin/v1/fix/gateways/{gateway}/sessions
Response 200 – array of sessions:
| Field | Type | Description |
|---|---|---|
gatewayName | string | Gateway name |
sessionId | string | Session identifier |
status | enum | Connected, Disconnected or Disabled |
localPort | long | Local port |
remoteIp | string | Remote IP address |
remotePort | long | Remote port |
inboundSequence | long | Next expected inbound sequence number |
outboundSequence | long | Next outbound sequence number |
Get FIX Session
GET /api/admin/v1/fix/gateways/{gateway}/sessions/{session}
Returns the fields above plus:
| Field | Type | Description |
|---|---|---|
gatewayType | enum | Type of the gateway |
senderId, targetId | string | FIX SenderCompID and TargetCompID |
localIp | string | Local IP address |
connectTimestamp, disconnectTimestamp | long | Epoch milliseconds |
messagesSent, messagesReceived | long | Message counters |
bytesSent, bytesReceived | long | Traffic counters |
Disable, Enable and Disconnect a FIX Session
| Method and path | Description |
|---|---|
POST /api/admin/v1/fix/gateways/{gateway}/sessions/{session}/disable | Disable the session |
POST /api/admin/v1/fix/gateways/{gateway}/sessions/{session}/enable | Enable the session |
POST /api/admin/v1/fix/gateways/{gateway}/sessions/{session}/disconnect | Drop the current connection |
All three require CONTROL_FIX_SESSION, take no request body and return the updated session in the Get FIX Session format.
Examples
Using a bearer token:
TOKEN=$(...) # obtain from your identity provider
curl -H "Authorization: Bearer $TOKEN" \
https://monitor.example.com:8988/api/admin/v1/trading/status
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"reason": "Emergency drill", "cancelOrders": true}' \
https://monitor.example.com:8988/api/admin/v1/trading/halt
Using HTTP Basic:
curl -u operator:secret https://monitor.example.com:8988/api/admin/v1/services