Pascal Exchange API#
Public reference for integrating Pascal's exchange REST and WebSocket API for trading.
For request signing, see signing.md. Most integrators should use the Pascal client SDKs when available; the raw protocol is documented here for SDK authors, market makers, and direct integrations.
Base URLs#
| Canary | Staging | |
|---|---|---|
| Web | https://canary.pascal.trade | https://staging.pascal.trade |
| Write API | https://trade.canary.pascal.trade | https://trade.staging.pascal.trade |
| REST Read API | https://data.canary.pascal.trade | https://data.staging.pascal.trade |
| WebSocket | wss://data.canary.pascal.trade/ws | wss://data.staging.pascal.trade/ws |
All /api/v1/... examples use the canary hosts.
Authentication#
Pascal separates account ownership from trading authorization.
| Key | Use | Used by |
|---|---|---|
| Wallet key | Custody, withdrawals, and trading-key lifecycle | Create/revoke trading keys, withdraw collateral, register deposit addresses |
| Trading key | Order placement and cancellation | Place and cancel orders |
In every signed request, owner is the wallet public key and signer is the key that produced the Ed25519 signature. Wallet-signed requests require signer == owner.
Replay Protection#
Every signed request carries replay and staleness protection fields client_ts_ms and recv_window_ms:
Signature Object
| Field | Type | Required | Description |
|---|---|---|---|
client_ts_ms | integer string | Yes | Client ts ms. |
recv_window_ms | integer string | Yes | Recv window ms. |
deployment_id | integer string | Yes | Deployment id. |
owner | base58 string | Yes | Owner. |
signer | base58 string | Yes | Signer. |
signature | base58 string | Yes | Signature. |
Response Envelopes#
Read API success responses use status: "success", endpoint-specific data, and round context. Validation and lookup failures use status: "error" with data.code and optional data.details.
Write API responses use one envelope per command. Batch endpoints return an array of write envelopes; single-command endpoints return one write envelope.
{
"status": "success",
"data": {
"server_time_ms": "1731536000050"
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}{
"status": "error",
"data": {
"code": "invalid_request",
"details": {
"reason": "count_back must be positive"
}
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}[
{
"status": "success",
"data": {
"type": "place_order",
"order": {
"symbol": "SIM_EVENT_1.MARKET_1",
"side": "BID",
"size_original": "10",
"size_filled": "3",
"notional_filled": "1.650000",
"size_remaining": "7",
"price": "0.550000",
"status": "OPEN",
"tif": "GTC",
"type": "LIMIT",
"post_only": false,
"reduce_only": false,
"expires_ts_ms": "0",
"client_order_id": "42",
"id": "987654321",
"place_ts_ms": "1731536000050",
"place_round": "12345",
"update_ts_ms": "1731536000050",
"update_round": "12345"
},
"fills": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"client_order_id": "42",
"order_id": "987654321",
"trade_id": "555001",
"trade_ts_ms": "1731536000050",
"cursor": "00000000000000067891:0000000000",
"round": "12345",
"side": "BID",
"liquidity": "TAKER",
"fill_size": "3",
"fill_price": "0.550000",
"fee_usd": "-0.020000",
"collateral_change_usd": "-1.650000",
"position_size_prev": "0",
"realized_pnl_usd": "0.000000"
}
]
},
"correlation_id": "170000000000000123",
"round": "12345",
"exchange_time_ms": "1731536000050"
}
]{
"status": "error",
"data": {
"code": "duplicate_client_order_id",
"details": "client_order_id 42 is already open"
},
"correlation_id": "170000000000000123",
"round": "12345",
"exchange_time_ms": "1731536000050"
}JSON Conventions#
| Shape | Encoding |
|---|---|
| Decimal prices, USD amounts, rates, and fees | String with 6 decimal places unless the field description says otherwise. |
| Contract sizes, sequence numbers, ids, timestamps, and cursors | String when the value can exceed JavaScript's safe integer range. |
| Timestamps | Unix milliseconds. |
| Public keys and Ed25519 signatures | Base58 strings. |
| Market symbols | Uppercase string identifiers. |
Trading Endpoints#
All write endpoints accept a tagged WriteRequest body. The current HTTP router uses a shared handler, but clients should send each request variant to the path documented here.
Place And Replace Orders#
POST <write_base_url>/api/v1/order
Places or amends one or more orders. Each order is independently signed and independently succeeds or fails. The maximum batch size is 50.
curl -X POST https://trade.canary.pascal.trade/api/v1/order \
-H 'Content-Type: application/json' \
--data @- <<'EOF'
{
"type": "batch_place",
"orders": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"side": "BID",
"size": "10",
"price": "0.550000",
"tif": "GTC",
"type": "LIMIT",
"post_only": false,
"reduce_only": false,
"expires_ts_ms": "0",
"client_order_id": "42",
"metadata": "0",
"signature": {
"client_ts_ms": "1731536000000",
"recv_window_ms": "5000",
"deployment_id": "2",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signer": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1",
"signature": "FVmKzV22fyPA1sjJ7uTVBxLYXyGSNZN299PWGMGBNCqPd9gikZsetPTC4snfCG223fWGpbT9T7vBeLdUVUCm6wi"
}
}
]
}
EOF[
{
"status": "success",
"data": {
"type": "place_order",
"order": {
"symbol": "SIM_EVENT_1.MARKET_1",
"side": "BID",
"size_original": "10",
"size_filled": "3",
"notional_filled": "1.650000",
"size_remaining": "7",
"price": "0.550000",
"status": "OPEN",
"tif": "GTC",
"type": "LIMIT",
"post_only": false,
"reduce_only": false,
"expires_ts_ms": "0",
"client_order_id": "42",
"id": "987654321",
"place_ts_ms": "1731536000050",
"place_round": "12345",
"update_ts_ms": "1731536000050",
"update_round": "12345"
},
"fills": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"client_order_id": "42",
"order_id": "987654321",
"trade_id": "555001",
"trade_ts_ms": "1731536000050",
"cursor": "00000000000000067891:0000000000",
"round": "12345",
"side": "BID",
"liquidity": "TAKER",
"fill_size": "3",
"fill_price": "0.550000",
"fee_usd": "-0.020000",
"collateral_change_usd": "-1.650000",
"position_size_prev": "0",
"realized_pnl_usd": "0.000000"
}
]
},
"correlation_id": "170000000000000123",
"round": "12345",
"exchange_time_ms": "1731536000050"
}
]JSON Response Payload
Batch responses are JSON arrays of write envelopes. On success, each envelope's data object has type: "place_order" and these fields:
| Field | Type | Required | Description |
|---|---|---|---|
order | OrderMsg | Yes | Order. |
fills | array of FillMsg | Yes | Fills. |
order object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
side | Side | Yes | Side. |
size_original | integer string | Yes | Size original. |
size_filled | integer string | Yes | Size filled. |
notional_filled | decimal string, 6 d.p. | Yes | Cumulative notional fill value: sum of fill_price * fill_size for all fills. Divide by size_filled to get the average fill price. |
size_remaining | integer string | Yes | Size remaining. |
price | decimal string, 6 d.p. | Yes | Price. |
status | OrderStatus | Yes | Status. |
tif | TimeInForce | Yes | Tif. |
type | OrderType | Yes | Type. |
post_only | boolean | Yes | Post only. |
reduce_only | boolean | Yes | Reduce only. |
expires_ts_ms | integer string | Yes | Expires ts ms. |
client_order_id | integer string | Yes | Client order id. |
id | integer string | Yes | Id. |
place_ts_ms | integer string | Yes | Place ts ms. |
place_round | integer string | Yes | Place round. |
update_ts_ms | integer string | Yes | Update ts ms. |
update_round | integer string | Yes | Update round. |
builder_key | base58 string | No | Builder key. |
builder_fee_rate | signed decimal string, 6 d.p. | No | Builder fee rate. |
Every element in fills is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
client_order_id | integer string | Yes | Client order id. |
order_id | integer string | Yes | Order id. |
trade_id | integer string | Yes | Trade id. |
trade_ts_ms | integer string | Yes | Trade ts ms. |
cursor | fixed-width cursor string | Yes | Cursor. |
round | integer string | Yes | Round. |
side | Side | Yes | Side. |
liquidity | Liquidity | Yes | Liquidity. |
fill_size | integer string | Yes | Fill size. |
fill_price | decimal string, 6 d.p. | Yes | Fill price. |
fee_usd | signed decimal string, 6 d.p. | Yes | Fee usd. |
collateral_change_usd | signed decimal string, 6 d.p. | Yes | Collateral change usd. |
builder_key | base58 string | No | Builder key. |
builder_fee_usd | signed decimal string, 6 d.p. | No | Builder fee usd. |
position_size_prev | signed integer string | Yes | Position size prev. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized pnl usd. |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "batch_place" | Yes | Request discriminator. |
orders | array of PlaceOrderRequest | Yes | Orders to submit in this batch. |
Every element in orders is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol for the contract to trade. |
side | Side | Yes | Whether to buy (BID) or sell (ASK). |
size | integer string | Yes | Order size in contracts. |
price | decimal string, 6 d.p. | Yes | Limit price. |
tif | TimeInForce | Yes | Time-in-force policy. MARKET orders must use IOC. |
type | OrderType | Yes | Display order type. MARKET is accepted only with IOC and otherwise behaves like an IOC limit order. |
post_only | boolean | No | If true, reject the order instead of resting it when it would cross immediately. |
reduce_only | boolean | No | If true, only reduce existing exposure and never increase it. |
expires_ts_ms | integer string | No | Expiration timestamp required for GTT orders and zero otherwise. |
client_order_id | integer string | Yes | Client-assigned order identifier, unique per account. |
replace_client_order_id | integer string | No | Existing client order identifier to replace atomically, if any. |
builder_info | BuilderInfo | No | Optional builder attribution and fee settings. |
metadata | integer string | Yes | Opaque metadata byte included in the signed payload. |
signature | RequestSignature | Yes | Request signature and replay-protection metadata. |
Cancel Orders#
POST <write_base_url>/api/v1/order
Cancels one or more orders by client order id or exchange order id. Each cancel is independently signed and independently succeeds or fails. The maximum batch size is 50.
curl -X POST https://trade.canary.pascal.trade/api/v1/order \
-H 'Content-Type: application/json' \
--data @- <<'EOF'
{
"type": "batch_cancel",
"cancels": [
{
"signature": {
"client_ts_ms": "1731536000000",
"recv_window_ms": "5000",
"deployment_id": "2",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signer": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1",
"signature": "64uzbMXBYz6yAJRUnZZxyHYQSri4FqYaVvCF7TPbve38PGQw9grY7ohNT25MPqumkVCrPjVLdkXthZHAV7Rbjp6T"
},
"client_order_id": "42",
"metadata": "1"
}
]
}
EOF[
{
"status": "success",
"data": {
"type": "cancel_order",
"order": {
"symbol": "SIM_EVENT_1.MARKET_1",
"side": "BID",
"size_original": "10",
"size_filled": "3",
"notional_filled": "1.650000",
"size_remaining": "7",
"price": "0.550000",
"status": "OPEN",
"tif": "GTC",
"type": "LIMIT",
"post_only": false,
"reduce_only": false,
"expires_ts_ms": "0",
"client_order_id": "42",
"id": "987654321",
"place_ts_ms": "1731536000050",
"place_round": "12345",
"update_ts_ms": "1731536000050",
"update_round": "12345"
}
},
"correlation_id": "170000000000000123",
"round": "12345",
"exchange_time_ms": "1731536000050"
}
]JSON Response Payload
Batch responses are JSON arrays of write envelopes. On success, each envelope's data object has type: "cancel_order" and these fields:
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "cancel_order" | Yes | Request discriminator. |
order | OrderMsg | Yes | Order. |
order object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
side | Side | Yes | Side. |
size_original | integer string | Yes | Size original. |
size_filled | integer string | Yes | Size filled. |
notional_filled | decimal string, 6 d.p. | Yes | Cumulative notional fill value: sum of fill_price * fill_size for all fills. Divide by size_filled to get the average fill price. |
size_remaining | integer string | Yes | Size remaining. |
price | decimal string, 6 d.p. | Yes | Price. |
status | OrderStatus | Yes | Status. |
tif | TimeInForce | Yes | Tif. |
type | OrderType | Yes | Type. |
post_only | boolean | Yes | Post only. |
reduce_only | boolean | Yes | Reduce only. |
expires_ts_ms | integer string | Yes | Expires ts ms. |
client_order_id | integer string | Yes | Client order id. |
id | integer string | Yes | Id. |
place_ts_ms | integer string | Yes | Place ts ms. |
place_round | integer string | Yes | Place round. |
update_ts_ms | integer string | Yes | Update ts ms. |
update_round | integer string | Yes | Update round. |
builder_key | base58 string | No | Builder key. |
builder_fee_rate | signed decimal string, 6 d.p. | No | Builder fee rate. |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "batch_cancel" | Yes | Request discriminator. |
cancels | array of CancelOrderRequest | Yes | Cancel requests to submit in this batch. |
Every element in cancels is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
signature | RequestSignature | Yes | Signature. |
client_order_id | integer string | One of | Client order id. |
order_id | integer string | One of | Order id. |
metadata | integer string | Yes | Metadata. |
Create A Trading Key#
POST <write_base_url>/api/v1/api-key
Authorizes a trading key for an account. This request is wallet-signed.
curl -X POST https://trade.canary.pascal.trade/api/v1/api-key \
-H 'Content-Type: application/json' \
--data @- <<'EOF'
{
"type": "create_trading_key",
"key": {
"signature": {
"client_ts_ms": "1731536000000",
"recv_window_ms": "5000",
"deployment_id": "2",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signer": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signature": "27ZXesvQMpSKiQDMTZQ9XXyy1Wvv853TPzVVQKxHV6dcZhgjhzzncbes3FmCrRJMFwHc3b84JnK87pNHvUUz8NQT"
},
"trading_key": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1",
"name": "api-doc-key",
"expiration_ts_ms": "1732140800000"
}
}
EOF{
"status": "success",
"data": {
"type": "create_trading_key",
"trading_key": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1",
"name": "api-doc-key",
"expiration_ts_ms": "1732140800000"
},
"correlation_id": "170000000000000123",
"round": "12345",
"exchange_time_ms": "1731536000050"
}JSON Response Payload
On success, the response envelope's data object has type: "create_trading_key" and these fields:
| Field | Type | Required | Description |
|---|---|---|---|
trading_key | base58 string | Yes | Trading key. |
name | string | Yes | Name. |
expiration_ts_ms | integer string | Yes | Expiration ts ms. |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "create_trading_key" | Yes | Request discriminator. |
key | CreateTradingKeyRequest | Yes | Trading key creation payload. |
| Field | Type | Required | Description |
|---|---|---|---|
signature | RequestSignature | Yes | Signature. |
trading_key | base58 string | Yes | Trading key. |
name | string | Yes | Name. |
expiration_ts_ms | integer string | Yes | Expiration ts ms. |
Revoke A Trading Key#
POST <write_base_url>/api/v1/api-key
Revokes a previously authorized trading key. This request is wallet-signed.
curl -X POST https://trade.canary.pascal.trade/api/v1/api-key \
-H 'Content-Type: application/json' \
--data @- <<'EOF'
{
"type": "revoke_trading_key",
"key": {
"signature": {
"client_ts_ms": "1731536000000",
"recv_window_ms": "5000",
"deployment_id": "2",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signer": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signature": "uApf45JWVGXK4D95WJcWEc4rkC5mP6BbsG43t7H7eXYrvUiHiwQVSCB3KgB3ygRZJgM5o313xhyHk9mWXEHdJz1"
},
"trading_key": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1"
}
}
EOF{
"status": "success",
"data": {
"type": "revoke_trading_key",
"trading_key": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1"
},
"correlation_id": "170000000000000123",
"round": "12345",
"exchange_time_ms": "1731536000050"
}JSON Response Payload
On success, the response envelope's data object has type: "revoke_trading_key" and these fields:
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "revoke_trading_key" | Yes | Request discriminator. |
trading_key | base58 string | Yes | Trading key. |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "revoke_trading_key" | Yes | Request discriminator. |
key | RevokeTradingKeyRequest | Yes | Trading key revocation payload. |
| Field | Type | Required | Description |
|---|---|---|---|
signature | RequestSignature | Yes | Signature. |
trading_key | base58 string | Yes | Trading key. |
Withdraw Collateral#
POST <write_base_url>/api/v1/withdraw
Requests withdrawal of collateral to a destination token account. This request is wallet-signed.
curl -X POST https://trade.canary.pascal.trade/api/v1/withdraw \
-H 'Content-Type: application/json' \
--data @- <<'EOF'
{
"type": "withdraw",
"withdraw": {
"signature": {
"client_ts_ms": "1731536000000",
"recv_window_ms": "5000",
"deployment_id": "2",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signer": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signature": "3AdcFDayePHf2G2F9jzAE8Xp7nC2MNVanHYn5Vg44pKmuT32Aj8YffaNT8qRpTDiJwqEheBy7Lvdinr9cbW9xA7m"
},
"amount": "25.000000",
"destination_authority": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"destination_token_account": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB"
}
}
EOF{
"status": "success",
"data": {
"type": "withdrawal",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"amount": "25.000000",
"destination_authority": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"destination_token_account": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB"
},
"correlation_id": "170000000000000123",
"round": "12345",
"exchange_time_ms": "1731536000050"
}JSON Response Payload
On success, the response envelope's data object has type: "withdrawal" and these fields:
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "withdrawal" | Yes | Request discriminator. |
owner | base58 string | Yes | Owner. |
amount | decimal string, 6 d.p. | Yes | Amount. |
destination_authority | base58 string | Yes | Destination authority. |
destination_token_account | base58 string | Yes | Destination token account. |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "withdraw" | Yes | Request discriminator. |
withdraw | WithdrawRequest | Yes | Withdrawal payload. |
| Field | Type | Required | Description |
|---|---|---|---|
signature | RequestSignature | Yes | Signature. |
amount | decimal string, 6 d.p. | Yes | Amount. |
destination_authority | base58 string | Yes | Destination authority. |
destination_token_account | base58 string | Yes | Destination token account. |
Register A Deposit Address#
POST <write_base_url>/api/v1/deposit-address
Registers the owner's deposit address for balance scanning. This request is wallet-signed.
curl -X POST https://trade.canary.pascal.trade/api/v1/deposit-address \
-H 'Content-Type: application/json' \
--data @- <<'EOF'
{
"type": "register_deposit_address",
"registration": {
"signature": {
"client_ts_ms": "1731536000000",
"recv_window_ms": "5000",
"deployment_id": "2",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signer": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"signature": "SmycN1kHAggVjooQvGSKCkqUMtk17h5ZZZudtoqBVGvjQyZxEutXTHVG7bZEYurfT4jmrBc7wFFW6pL9yvJbyMc"
},
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB"
}
}
EOF{
"status": "success",
"data": {
"type": "empty"
},
"correlation_id": "170000000000000123",
"round": "12345",
"exchange_time_ms": "1731536000050"
}JSON Response Payload
On success, the response envelope's data object has type: "empty" and no additional fields.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "register_deposit_address" | Yes | Request discriminator. |
registration | RegisterDepositAddressRequest | Yes | Deposit address registration payload. |
| Field | Type | Required | Description |
|---|---|---|---|
signature | RequestSignature | Yes | Signature. |
owner | base58 string | Yes | Owner. |
Market Data Endpoints#
Server Time#
GET <read_base_url>/api/v1/time
Returns the read API server's current wall-clock time in milliseconds.
curl 'https://data.canary.pascal.trade/api/v1/time'{
"status": "success",
"data": {
"server_time_ms": "1731536000050"
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}JSON Response Payload
| Field | Type | Required | Description |
|---|---|---|---|
server_time_ms | integer string | Yes | Server time ms. |
ESM Version#
GET <read_base_url>/api/v1/esm-version
Returns the active ESM protocol version replicated by the read API.
curl 'https://data.canary.pascal.trade/api/v1/esm-version'{
"status": "success",
"data": {
"esm_version": 2
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}JSON Response Payload
| Field | Type | Required | Description |
|---|---|---|---|
esm_version | integer | Yes | Esm version. |
Markets#
GET <read_base_url>/api/v1/markets
Returns listed markets and their current derived state.
curl 'https://data.canary.pascal.trade/api/v1/markets?strict=true'{
"status": "success",
"data": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"taker_fee_rate": "0.001000",
"maker_rebate_share": "0.500000",
"tick_size_min": "0.010000",
"tick_sig_figs": 2,
"event_description": "API documentation sample market",
"expected_resolution_time_ms": "1735000000000",
"market_description": "Yes",
"reverse_description": "No",
"sort_order": "SymbolAsc",
"tags": [
"docs"
],
"topic": {
"id": "docs",
"description": "Documentation examples"
},
"mark_price": "0.550000",
"open_interest": "250",
"resolution": null,
"mark_price_24h_baseline": "0.520000",
"market_stats_by_window": {},
"market_stats_all_time": null
}
],
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
strict | boolean | No | If true, only return markets whose [MarketDisplayAttributes] parse successfully on the current version. |
JSON Response Payload
Returns a JSON array of market objects. Every element in the array is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Human-readable identifier for a market. Globally Unique. See ontology.md for details Eg "NYCMAYOR_20251104.MAMDANI" The markets event is derived from it's symbol see [Symbol::event_code()] |
taker_fee_rate | signed decimal string, 6 d.p. | Yes | Base fee rate paid by takers. Decimal string, e.g. "0.0010" for 10 bps. See [pascal_types::math::taker_fee] for more details. |
maker_rebate_share | signed decimal string, 6 d.p. | Yes | Share of taker fee rebated to makers. Decimal string, e.g. "0.50" for 50%. See [pascal_types::math::fee_share] for more details. |
tick_size_min | decimal string, 6 d.p. | Yes | Minimum tick size. The tick size for a given price px is: max(tick_size_min, 10^(floor(log10(px')) - tick_sig_figs + 1)) where px' = min(px, 1 - px) The intuition is that we want some amount of decimal precision available, but we don't want to count 0 prefixes. For example, 0.0025, 0.025 and 0.25 all have 2 digits of precision. |
tick_sig_figs | integer | Yes | Number of significant figures in the tick size formula. Must be in [1, 6]. |
display_attributes.* | object mapping string to JSON value | Yes | Flattened display-only metadata fields. |
mark_price | decimal string, 6 d.p. | No | Median of whichever of (best bid, best ask, last trade) are available. Defaults to 50 cents if no mark price exists yet. |
open_interest | integer string | Yes | Current open interest. |
resolution | MarketResolutionMsg | No | Final market resolution, if this market has resolved. |
mark_price_24h_baseline | decimal string, 6 d.p. | No | Mark price baseline used to calculate 24h mark price change. None means no 24h baseline mark price is available. |
market_stats_by_window | object mapping MarketStatsWindowKey to MarketStatsSnapshotMsg | No | Rolling market statistics snapshots for this market. Keys are window durations in milliseconds encoded as JSON object keys (string form). For example, "86400000" is the 1-day window. Empty means no stats are available for this market yet (for example, newly listed markets). |
market_stats_all_time | MarketStatsSnapshotMsg | No | All-time cumulative market statistics snapshot for this market. None means no all-time stats are available for this market yet. |
resolution object:
| Field | Type | Required | Description |
|---|---|---|---|
price | decimal string, 6 d.p. | Yes | Price. |
time_ms | integer string | Yes | Time ms. |
round | integer string | Yes | Round. |
Each market_stats_by_window value and market_stats_all_time object:
| Field | Type | Required | Description |
|---|---|---|---|
taker_buy_volume | integer string | Yes | Total base-asset volume bought by takers in the window. |
taker_sell_volume | integer string | Yes | Total base-asset volume sold by takers in the window. |
taker_buy_volume_notional | decimal string, 6 d.p. | Yes | Total quote-notional bought by takers in the window. |
taker_sell_volume_notional | decimal string, 6 d.p. | Yes | Total quote-notional sold by takers in the window. |
taker_buy_trade_count | integer string | Yes | Total number of buy-side taker trades included in the snapshot window. |
taker_sell_trade_count | integer string | Yes | Total number of sell-side taker trades included in the snapshot window. |
end_ms_exclusive | integer string | Yes | Exclusive upper-bound timestamp for the aggregation window. |
as_of_round | integer string | Yes | Sequencer round watermark used when this snapshot was computed. Trades from rounds greater than as_of_round are excluded. |
as_of_exchange_time_ms | integer string | Yes | As-of watermark exchange time at query time. |
Order Book#
GET <read_base_url>/api/v1/book
Returns the current order book for one market.
curl 'https://data.canary.pascal.trade/api/v1/book?symbol=SIM_EVENT_1.MARKET_1'{
"status": "success",
"data": {
"asks": [
[
"0.560000",
"12"
],
[
"0.570000",
"20"
]
],
"bids": [
[
"0.540000",
"15"
],
[
"0.530000",
"7"
]
],
"spec": {
"symbol": "SIM_EVENT_1.MARKET_1",
"taker_fee_rate": "0.001000",
"maker_rebate_share": "0.500000",
"tick_size_min": "0.010000",
"tick_sig_figs": 2
}
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
JSON Response Payload
| Field | Type | Required | Description |
|---|---|---|---|
asks | array of tuple (decimal string, 6 d.p., integer string) | Yes | Asks. |
bids | array of tuple (decimal string, 6 d.p., integer string) | Yes | Bids. |
spec | MarketSpec | No | Spec. |
spec object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Human-readable identifier for a market. Globally Unique. See ontology.md for details Eg "NYCMAYOR_20251104.MAMDANI" The markets event is derived from it's symbol see [Symbol::event_code()] |
taker_fee_rate | signed decimal string, 6 d.p. | Yes | Base fee rate paid by takers. Decimal string, e.g. "0.0010" for 10 bps. See [pascal_types::math::taker_fee] for more details. |
maker_rebate_share | signed decimal string, 6 d.p. | Yes | Share of taker fee rebated to makers. Decimal string, e.g. "0.50" for 50%. See [pascal_types::math::fee_share] for more details. |
tick_size_min | decimal string, 6 d.p. | Yes | Minimum tick size. The tick size for a given price px is: max(tick_size_min, 10^(floor(log10(px')) - tick_sig_figs + 1)) where px' = min(px, 1 - px) The intuition is that we want some amount of decimal precision available, but we don't want to count 0 prefixes. For example, 0.0025, 0.025 and 0.25 all have 2 digits of precision. |
tick_sig_figs | integer | Yes | Number of significant figures in the tick size formula. Must be in [1, 6]. |
Order Books#
GET <read_base_url>/api/v1/books
Returns order books for multiple comma-delimited symbols.
curl 'https://data.canary.pascal.trade/api/v1/books?symbols=SIM_EVENT_1.MARKET_1%2CSIM_EVENT_1.MARKET_2'{
"status": "success",
"data": {
"books": {
"SIM_EVENT_1.MARKET_1": {
"asks": [
[
"0.560000",
"12"
],
[
"0.570000",
"20"
]
],
"bids": [
[
"0.540000",
"15"
],
[
"0.530000",
"7"
]
],
"spec": {
"symbol": "SIM_EVENT_1.MARKET_1",
"taker_fee_rate": "0.001000",
"maker_rebate_share": "0.500000",
"tick_size_min": "0.010000",
"tick_sig_figs": 2
}
},
"SIM_EVENT_1.MARKET_2": {
"asks": [
[
"0.560000",
"12"
],
[
"0.570000",
"20"
]
],
"bids": [
[
"0.540000",
"15"
],
[
"0.530000",
"7"
]
]
}
}
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
symbols | comma-separated array of string | Yes | Symbols. |
JSON Response Payload
| Field | Type | Required | Description |
|---|---|---|---|
books | object mapping string to OrderBookMsg | Yes | Books. |
Each value in books is an order book object:
| Field | Type | Required | Description |
|---|---|---|---|
asks | array of tuple (decimal string, 6 d.p., integer string) | Yes | Asks. |
bids | array of tuple (decimal string, 6 d.p., integer string) | Yes | Bids. |
spec | MarketSpec | No | Spec. |
spec object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Human-readable identifier for a market. Globally Unique. See ontology.md for details Eg "NYCMAYOR_20251104.MAMDANI" The markets event is derived from it's symbol see [Symbol::event_code()] |
taker_fee_rate | signed decimal string, 6 d.p. | Yes | Base fee rate paid by takers. Decimal string, e.g. "0.0010" for 10 bps. See [pascal_types::math::taker_fee] for more details. |
maker_rebate_share | signed decimal string, 6 d.p. | Yes | Share of taker fee rebated to makers. Decimal string, e.g. "0.50" for 50%. See [pascal_types::math::fee_share] for more details. |
tick_size_min | decimal string, 6 d.p. | Yes | Minimum tick size. The tick size for a given price px is: max(tick_size_min, 10^(floor(log10(px')) - tick_sig_figs + 1)) where px' = min(px, 1 - px) The intuition is that we want some amount of decimal precision available, but we don't want to count 0 prefixes. For example, 0.0025, 0.025 and 0.25 all have 2 digits of precision. |
tick_sig_figs | integer | Yes | Number of significant figures in the tick size formula. Must be in [1, 6]. |
Candles#
GET <read_base_url>/api/v1/candles
Returns OHLCV candles for one market and interval. Ranges are end-exclusive. If start_time_ms is omitted, count_back controls how many candles are returned before end_time_ms.
curl 'https://data.canary.pascal.trade/api/v1/candles?symbol=SIM_EVENT_1.MARKET_1&interval=1m&end_time_ms=1731536000000&count_back=2'{
"status": "success",
"data": [
{
"time": "1731535960000",
"open": "0.520000",
"high": "0.570000",
"low": "0.510000",
"close": "0.550000",
"volume": "120",
"taker_buy_volume": "70",
"taker_sell_volume": "50",
"volume_notional": "66.000000",
"taker_buy_volume_notional": "38.500000",
"taker_sell_volume_notional": "27.500000",
"trade_count": "8",
"taker_buy_count": "5",
"taker_sell_count": "3"
}
],
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
interval | string | Yes | Interval. |
end_time_ms | integer | Yes | End time ms. |
start_time_ms | integer | No | Start time ms. |
count_back | integer | No | Count back. |
JSON Response Payload
Returns a JSON array of candle objects. Every element in the array is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
time | integer string | Yes | Time. |
open | decimal string, 6 d.p. | Yes | Open. |
high | decimal string, 6 d.p. | Yes | High. |
low | decimal string, 6 d.p. | Yes | Low. |
close | decimal string, 6 d.p. | Yes | Close. |
volume | integer string | Yes | Volume. |
taker_buy_volume | integer string | Yes | Taker buy volume. |
taker_sell_volume | integer string | Yes | Taker sell volume. |
volume_notional | decimal string, 6 d.p. | Yes | Volume notional. |
taker_buy_volume_notional | decimal string, 6 d.p. | Yes | Taker buy volume notional. |
taker_sell_volume_notional | decimal string, 6 d.p. | Yes | Taker sell volume notional. |
trade_count | integer string | Yes | Trade count. |
taker_buy_count | integer string | Yes | Taker buy count. |
taker_sell_count | integer string | Yes | Taker sell count. |
Public Trades#
GET <read_base_url>/api/v1/trades
Returns public trade history for one or more markets.
curl 'https://data.canary.pascal.trade/api/v1/trades?symbols=SIM_EVENT_1.MARKET_1&before_cursor=&limit=50'{
"status": "success",
"data": {
"items": [
{
"trade_id": "555001",
"trade_ts_ms": "1731536000050",
"taker_side": "BID",
"size": "3",
"price": "0.550000",
"maker": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"taker": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1",
"cursor": "00000000000000067891:0000000000"
}
],
"next_cursor": "00000000000000067890:0000000000",
"historical_context": {
"as_of_round": "12345",
"as_of_esm_seq": "67891"
}
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
symbols | comma-separated array of string | No | Symbols. |
before_cursor | fixed-width cursor string | No | Before cursor. |
limit | integer | No | Limit. |
JSON Response Payload
Returns a paginated JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
items | array of PublicTradeMsg | Yes | Items. |
next_cursor | fixed-width cursor string | No | Next cursor. |
historical_context | HistoricalReadApiQueryContext | Yes | Historical context. |
Every element in items is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
trade_id | integer string | Yes | Trade id. |
trade_ts_ms | integer string | Yes | Trade ts ms. |
taker_side | Side | Yes | Taker side. |
size | integer string | Yes | Size. |
price | decimal string, 6 d.p. | Yes | Price. |
maker | base58 string | Yes | Maker. |
taker | base58 string | Yes | Taker. |
cursor | fixed-width cursor string | Yes | Cursor token for keyset pagination. For journaler-backed history and live trade streams, the first cursor component is esm_seq. The second component is an intra-effect tie-break index, which is always 0 for trades. |
historical_context object:
| Field | Type | Required | Description |
|---|---|---|---|
as_of_round | integer string | Yes | As of round. |
as_of_esm_seq | integer string | Yes | Serialized as a string for JS safety. |
Account Data Endpoints#
Account Snapshot#
GET <read_base_url>/api/v1/account
Returns open orders, fills, positions, deposits, transfers, and collateral for one owner.
curl 'https://data.canary.pascal.trade/api/v1/account?user=GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB'{
"status": "success",
"data": {
"orders": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"side": "BID",
"size_original": "10",
"size_filled": "3",
"notional_filled": "1.650000",
"size_remaining": "7",
"price": "0.550000",
"status": "OPEN",
"tif": "GTC",
"type": "LIMIT",
"post_only": false,
"reduce_only": false,
"expires_ts_ms": "0",
"client_order_id": "42",
"id": "987654321",
"place_ts_ms": "1731536000050",
"place_round": "12345",
"update_ts_ms": "1731536000050",
"update_round": "12345"
}
],
"fills": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"client_order_id": "42",
"order_id": "987654321",
"trade_id": "555001",
"trade_ts_ms": "1731536000050",
"cursor": "00000000000000067891:0000000000",
"round": "12345",
"side": "BID",
"liquidity": "TAKER",
"fill_size": "3",
"fill_price": "0.550000",
"fee_usd": "-0.020000",
"collateral_change_usd": "-1.650000",
"position_size_prev": "0",
"realized_pnl_usd": "0.000000"
}
],
"positions": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"size": "7",
"mark_price": "0.550000",
"average_entry_price": "0.520000",
"remaining_entry_notional_usd": "3.640000",
"realized_pnl_usd": "0.000000",
"open_size": "10",
"open_notional": "5.200000",
"close_size": "3",
"close_notional": "1.650000",
"cumulative_fees_paid": "-0.020000",
"open_ts_ms": "1731535900000",
"open_round": "12340",
"update_ts_ms": "1731536000050",
"update_round": "12345"
}
],
"resolutions": [],
"inflight_deposits": [
{
"deposit_seq": "9",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"amount": "100.000000",
"status": "FINALIZED"
}
],
"transfers": [
{
"collateral_change": "100.000000",
"type": "DEPOSIT",
"time_ms": "1731535900000",
"cursor": "00000000000000067880:0000000000"
}
],
"collateral_usd": "100.000000"
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
user | string | Yes | User. |
JSON Response Payload
| Field | Type | Required | Description |
|---|---|---|---|
orders | array of OrderMsg | Yes | Orders. |
fills | array of FillMsg | Yes | Fills. |
positions | array of PositionMsg | Yes | Positions. |
resolutions | array of PositionResolutionMsg | Yes | Resolutions. |
inflight_deposits | array of DepositMsg | Yes | Inflight deposits. |
transfers | array of TransferMsg | Yes | Transfers. |
collateral_usd | decimal string, 6 d.p. | No | Collateral usd. |
Every element in orders is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
side | Side | Yes | Side. |
size_original | integer string | Yes | Size original. |
size_filled | integer string | Yes | Size filled. |
notional_filled | decimal string, 6 d.p. | Yes | Cumulative notional fill value: sum of fill_price * fill_size for all fills. Divide by size_filled to get the average fill price. |
size_remaining | integer string | Yes | Size remaining. |
price | decimal string, 6 d.p. | Yes | Price. |
status | OrderStatus | Yes | Status. |
tif | TimeInForce | Yes | Tif. |
type | OrderType | Yes | Type. |
post_only | boolean | Yes | Post only. |
reduce_only | boolean | Yes | Reduce only. |
expires_ts_ms | integer string | Yes | Expires ts ms. |
client_order_id | integer string | Yes | Client order id. |
id | integer string | Yes | Id. |
place_ts_ms | integer string | Yes | Place ts ms. |
place_round | integer string | Yes | Place round. |
update_ts_ms | integer string | Yes | Update ts ms. |
update_round | integer string | Yes | Update round. |
builder_key | base58 string | No | Builder key. |
builder_fee_rate | signed decimal string, 6 d.p. | No | Builder fee rate. |
Every element in fills is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
client_order_id | integer string | Yes | Client order id. |
order_id | integer string | Yes | Order id. |
trade_id | integer string | Yes | Trade id. |
trade_ts_ms | integer string | Yes | Trade ts ms. |
cursor | fixed-width cursor string | Yes | Cursor. |
round | integer string | Yes | Round. |
side | Side | Yes | Side. |
liquidity | Liquidity | Yes | Liquidity. |
fill_size | integer string | Yes | Fill size. |
fill_price | decimal string, 6 d.p. | Yes | Fill price. |
fee_usd | signed decimal string, 6 d.p. | Yes | Fee usd. |
collateral_change_usd | signed decimal string, 6 d.p. | Yes | Collateral change usd. |
builder_key | base58 string | No | Builder key. |
builder_fee_usd | signed decimal string, 6 d.p. | No | Builder fee usd. |
position_size_prev | signed integer string | Yes | Position size prev. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized pnl usd. |
Every element in positions is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
size | signed integer string | Yes | Signed position size. Positive for long, negative for short. |
mark_price | decimal string, 6 d.p. | Yes | Median of whichever of (best bid, best ask, last trade) are available. |
average_entry_price | decimal string, 6 d.p. | No | Display value for UI: average entry price of the remaining open position. Do not use for PnL accounting; use remaining_entry_notional_usd. None means there is no remaining open position. |
remaining_entry_notional_usd | decimal string, 6 d.p. | Yes | Total entry notional still assigned to the current open position. This is the entry notional of the remaining position after accounting for partial closes. For example, after opening 10 contracts and closing 4, this is the entry notional still assigned to the remaining 6 contracts. Use this with the latest mark price and size to compute exact unrealized PnL. average_entry_price is derived from this value for display. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized PnL accumulated in the current position lifecycle, excluding fees. |
open_size | integer string | Yes | Cumulative size of opening trades since last zero crossing. |
open_notional | decimal string, 6 d.p. | Yes | Cumulative notional of opening trades (sum of price * size for openings) |
close_size | integer string | Yes | Cumulative size of closing trades since last zero crossing. |
close_notional | decimal string, 6 d.p. | Yes | Cumulative notional of closing trades (sum of price * size for closings) |
cumulative_fees_paid | signed decimal string, 6 d.p. | Yes | Cumulative fees paid on the position. |
open_ts_ms | integer string | Yes | When this position was opened. Resets on zero crossing (direction flip). |
open_round | integer string | Yes | Open round. |
update_ts_ms | integer string | Yes | When this position last changed. Advances on every fill and resolution. |
update_round | integer string | Yes | Update round. |
Every element in resolutions is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
resolution | decimal string, 6 d.p. | Yes | Resolution. |
size | signed integer string | Yes | Size. |
collateral_change_usd | decimal string, 6 d.p. | Yes | Collateral change usd. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized pnl usd. |
time_ms | integer string | Yes | Time ms. |
round | integer string | Yes | Round. |
Every element in inflight_deposits is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
deposit_seq | integer string | Yes | Deposit seq. |
owner | base58 string | Yes | Owner. |
amount | decimal string, 6 d.p. | Yes | Amount. |
status | DepositStatus | Yes | Status. |
Every element in transfers is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
collateral_change | signed decimal string, 6 d.p. | Yes | Collateral change. |
type | TransferType | Yes | Type. |
time_ms | integer string | Yes | Time ms. |
cursor | fixed-width cursor string | Yes | Cursor. |
Trading Keys#
GET <read_base_url>/api/v1/api-keys
Returns active trading keys for one owner.
curl 'https://data.canary.pascal.trade/api/v1/api-keys?owner=GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB'{
"status": "success",
"data": [
{
"trading_key": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1",
"name": "api-doc-key",
"expiration_ts_ms": "1732140800000"
}
],
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
owner | base58 string | Yes | Owner. |
JSON Response Payload
Returns a JSON array of trading key objects. Every element in the array is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
trading_key | base58 string | Yes | Trading key. |
name | string | Yes | Name. |
expiration_ts_ms | integer string | Yes | Expiration ts ms. |
Deposit Address#
GET <read_base_url>/api/v1/deposit-address
Returns the wallet-facing deposit address for one owner.
curl 'https://data.canary.pascal.trade/api/v1/deposit-address?owner=GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB'{
"status": "success",
"data": {
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"deposit_address": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"registered": true
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
owner | base58 string | Yes | Owner. |
JSON Response Payload
| Field | Type | Required | Description |
|---|---|---|---|
owner | base58 string | Yes | Owner. |
deposit_address | base58 string | Yes | Wallet-facing deposit address for manual sends. This is the deposit PDA, not the derived token ATA that backend services watch and credit. |
registered | boolean | Yes | Registered. |
Withdrawals#
GET <read_base_url>/api/v1/withdrawal
Returns in-flight withdrawals for one owner.
curl 'https://data.canary.pascal.trade/api/v1/withdrawal?owner=GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB'{
"status": "success",
"data": [
{
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"correlation_id": "170000000000000123",
"amount": "25.000000",
"destination_authority": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"destination_token_account": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"status": "RUNNING_PRE_CHECK",
"deadline_ts_ms": "1731536060000"
}
],
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
owner | base58 string | Yes | Owner. |
JSON Response Payload
Returns a JSON array of withdrawal status objects. Every element in the array is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
owner | base58 string | Yes | Owner. |
correlation_id | integer string | Yes | Correlation id. |
amount | decimal string, 6 d.p. | Yes | Amount. |
destination_authority | base58 string | Yes | Destination authority. |
destination_token_account | base58 string | Yes | Destination token account. |
status | WithdrawalStatus | Yes | Status. |
deadline_ts_ms | integer string | No | Deadline ts ms. |
User Fills#
GET <read_base_url>/api/v1/user-fills
Returns authenticated fill history for one owner, optionally filtered by symbols.
curl 'https://data.canary.pascal.trade/api/v1/user-fills?user=GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB&symbols=SIM_EVENT_1.MARKET_1&before_cursor=&limit=50'{
"status": "success",
"data": {
"items": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"client_order_id": "42",
"order_id": "987654321",
"trade_id": "555001",
"trade_ts_ms": "1731536000050",
"cursor": "00000000000000067891:0000000000",
"round": "12345",
"side": "BID",
"liquidity": "TAKER",
"fill_size": "3",
"fill_price": "0.550000",
"fee_usd": "-0.020000",
"collateral_change_usd": "-1.650000",
"position_size_prev": "0",
"realized_pnl_usd": "0.000000"
}
],
"historical_context": {
"as_of_round": "12345",
"as_of_esm_seq": "67891"
}
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
user | string | No | User. |
symbols | comma-separated array of string | No | Symbols. |
before_cursor | fixed-width cursor string | No | Before cursor. |
limit | integer | No | Limit. |
JSON Response Payload
Returns a paginated JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
items | array of FillMsg | Yes | Items. |
next_cursor | fixed-width cursor string | No | Next cursor. |
historical_context | HistoricalReadApiQueryContext | Yes | Historical context. |
Every element in items is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
client_order_id | integer string | Yes | Client order id. |
order_id | integer string | Yes | Order id. |
trade_id | integer string | Yes | Trade id. |
trade_ts_ms | integer string | Yes | Trade ts ms. |
cursor | fixed-width cursor string | Yes | Cursor. |
round | integer string | Yes | Round. |
side | Side | Yes | Side. |
liquidity | Liquidity | Yes | Liquidity. |
fill_size | integer string | Yes | Fill size. |
fill_price | decimal string, 6 d.p. | Yes | Fill price. |
fee_usd | signed decimal string, 6 d.p. | Yes | Fee usd. |
collateral_change_usd | signed decimal string, 6 d.p. | Yes | Collateral change usd. |
builder_key | base58 string | No | Builder key. |
builder_fee_usd | signed decimal string, 6 d.p. | No | Builder fee usd. |
position_size_prev | signed integer string | Yes | Position size prev. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized pnl usd. |
historical_context object:
| Field | Type | Required | Description |
|---|---|---|---|
as_of_round | integer string | Yes | As of round. |
as_of_esm_seq | integer string | Yes | Serialized as a string for JS safety. |
User Transfers#
GET <read_base_url>/api/v1/user-transfers
Returns deposit and withdrawal transfer history for one owner.
curl 'https://data.canary.pascal.trade/api/v1/user-transfers?user=GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB&before_cursor=&limit=50'{
"status": "success",
"data": {
"items": [
{
"collateral_change": "100.000000",
"type": "DEPOSIT",
"time_ms": "1731535900000",
"cursor": "00000000000000067880:0000000000"
}
],
"historical_context": {
"as_of_round": "12345",
"as_of_esm_seq": "67891"
}
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
user | base58 string | Yes | User. |
before_cursor | fixed-width cursor string | No | Before cursor. |
limit | integer | No | Limit. |
JSON Response Payload
Returns a paginated JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
items | array of TransferMsg | Yes | Items. |
next_cursor | fixed-width cursor string | No | Next cursor. |
historical_context | HistoricalReadApiQueryContext | Yes | Historical context. |
Every element in items is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
collateral_change | signed decimal string, 6 d.p. | Yes | Collateral change. |
type | TransferType | Yes | Type. |
time_ms | integer string | Yes | Time ms. |
cursor | fixed-width cursor string | Yes | Cursor. |
historical_context object:
| Field | Type | Required | Description |
|---|---|---|---|
as_of_round | integer string | Yes | As of round. |
as_of_esm_seq | integer string | Yes | Serialized as a string for JS safety. |
User Position Resolutions#
GET <read_base_url>/api/v1/user-position-resolutions
Returns historical position-resolution payouts for one owner.
curl 'https://data.canary.pascal.trade/api/v1/user-position-resolutions?user=GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB&before_cursor=&limit=50'{
"status": "success",
"data": {
"items": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"resolution": "1.000000",
"size": "7",
"collateral_change_usd": "7.000000",
"realized_pnl_usd": "3.360000",
"time_ms": "1731536000050",
"round": "12345"
}
],
"historical_context": {
"as_of_round": "12345",
"as_of_esm_seq": "67891"
}
},
"round": "12345",
"exchange_time_ms": "1731536000050"
}Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
user | base58 string | Yes | User. |
before_cursor | fixed-width cursor string | No | Before cursor. |
limit | integer | No | Limit. |
JSON Response Payload
Returns a paginated JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
items | array of PositionResolutionMsg | Yes | Items. |
next_cursor | fixed-width cursor string | No | Next cursor. |
historical_context | HistoricalReadApiQueryContext | Yes | Historical context. |
Every element in items is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
resolution | decimal string, 6 d.p. | Yes | Resolution. |
size | signed integer string | Yes | Size. |
collateral_change_usd | decimal string, 6 d.p. | Yes | Collateral change usd. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized pnl usd. |
time_ms | integer string | Yes | Time ms. |
round | integer string | Yes | Round. |
historical_context object:
| Field | Type | Required | Description |
|---|---|---|---|
as_of_round | integer string | Yes | As of round. |
as_of_esm_seq | integer string | Yes | Serialized as a string for JS safety. |
WebSocket API#
GET <ws_base_url> upgrades to a WebSocket connection. Clients send JSON text frames.
Client Messages#
Subscribe
{
"type": "subscribe",
"channels": [
{
"channel": "book",
"symbol": "SIM_EVENT_1.MARKET_1"
},
{
"channel": "trades",
"symbol": "SIM_EVENT_1.MARKET_1"
}
]
}{
"type": "unsubscribe",
"channels": [
{
"channel": "book",
"symbol": "SIM_EVENT_1.MARKET_1"
}
]
}{
"type": "ping"
}| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "subscribe" | Yes | Request discriminator. |
channels | array of WsChannel | Yes | Channels. |
Unsubscribe
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "unsubscribe" | Yes | Request discriminator. |
channels | array of WsChannel | Yes | Channels. |
Ping
| Field | Type | Required | Description |
|---|---|---|---|
type | string literal "ping" | Yes | Request discriminator. |
The server responds to ping with the literal JSON text frame {"type":"pong"}.
Channel descriptors
| Value | Payload | Description |
|---|---|---|
"book" | symbol: string | Book. |
"trades" | symbol: string | Trades. |
"account" | user: base58 string | Account. |
"candles" | symbol: string<br>interval: CandleInterval | Candles. |
Server Messages#
For each subscribed channel, the server emits a snapshot message followed by update messages whenever the channel state changes. Error messages flatten the channel descriptor with type: "error" and error fields.
{
"channel": "book",
"symbol": "SIM_EVENT_1.MARKET_1",
"type": "error",
"code": "market_not_found",
"details": {
"symbol": "SIM_EVENT_1.MARKET_1"
}
}Book Channel#
Order book snapshots and updates for one market.
JSON Message Payload
{
"channel": "book",
"symbol": "SIM_EVENT_1.MARKET_1",
"data": {
"asks": [
[
"0.560000",
"12"
],
[
"0.570000",
"20"
]
],
"bids": [
[
"0.540000",
"15"
],
[
"0.530000",
"7"
]
],
"spec": {
"symbol": "SIM_EVENT_1.MARKET_1",
"taker_fee_rate": "0.001000",
"maker_rebate_share": "0.500000",
"tick_size_min": "0.010000",
"tick_sig_figs": 2
}
},
"type": "snapshot",
"round": "12346",
"exchange_time_ms": "1731536000100"
}{
"channel": "book",
"symbol": "SIM_EVENT_1.MARKET_1",
"data": {
"asks": [
[
"0.570000",
"0"
]
],
"bids": [
[
"0.540000",
"15"
]
]
},
"type": "update",
"round": "12346",
"exchange_time_ms": "1731536000100"
}| Field | Type | Required | Description |
|---|---|---|---|
asks | array of tuple (decimal string, 6 d.p., integer string) | Yes | Asks. |
bids | array of tuple (decimal string, 6 d.p., integer string) | Yes | Bids. |
spec | MarketSpec | No | Spec. |
spec object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Human-readable identifier for a market. Globally Unique. See ontology.md for details Eg "NYCMAYOR_20251104.MAMDANI" The markets event is derived from it's symbol see [Symbol::event_code()] |
taker_fee_rate | signed decimal string, 6 d.p. | Yes | Base fee rate paid by takers. Decimal string, e.g. "0.0010" for 10 bps. See [pascal_types::math::taker_fee] for more details. |
maker_rebate_share | signed decimal string, 6 d.p. | Yes | Share of taker fee rebated to makers. Decimal string, e.g. "0.50" for 50%. See [pascal_types::math::fee_share] for more details. |
tick_size_min | decimal string, 6 d.p. | Yes | Minimum tick size. The tick size for a given price px is: max(tick_size_min, 10^(floor(log10(px')) - tick_sig_figs + 1)) where px' = min(px, 1 - px) The intuition is that we want some amount of decimal precision available, but we don't want to count 0 prefixes. For example, 0.0025, 0.025 and 0.25 all have 2 digits of precision. |
tick_sig_figs | integer | Yes | Number of significant figures in the tick size formula. Must be in [1, 6]. |
Channel Descriptor
| Field | Type | Required | Description |
|---|---|---|---|
channel | string literal "book" | Yes | Channel discriminator. |
symbol | string | Yes | Symbol. |
Trades Channel#
Public trades for one market.
JSON Message Payload
{
"channel": "trades",
"symbol": "SIM_EVENT_1.MARKET_1",
"data": [
{
"trade_id": "555001",
"trade_ts_ms": "1731536000050",
"taker_side": "BID",
"size": "3",
"price": "0.550000",
"maker": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"taker": "2KW2XRd9kwqet15Aha2oK3tYvd3nWbTFH1MBiRAv1BE1",
"cursor": "00000000000000067891:0000000000"
}
],
"type": "update",
"round": "12346",
"exchange_time_ms": "1731536000100"
}data is a JSON array of public trade objects. Every element in the array is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
trade_id | integer string | Yes | Trade id. |
trade_ts_ms | integer string | Yes | Trade ts ms. |
taker_side | Side | Yes | Taker side. |
size | integer string | Yes | Size. |
price | decimal string, 6 d.p. | Yes | Price. |
maker | base58 string | Yes | Maker. |
taker | base58 string | Yes | Taker. |
cursor | fixed-width cursor string | Yes | Cursor token for keyset pagination. For journaler-backed history and live trade streams, the first cursor component is esm_seq. The second component is an intra-effect tie-break index, which is always 0 for trades. |
Channel Descriptor
| Field | Type | Required | Description |
|---|---|---|---|
channel | string literal "trades" | Yes | Channel discriminator. |
symbol | string | Yes | Symbol. |
Candles Channel#
Current in-progress candle for one market and interval.
JSON Message Payload
{
"channel": "candles",
"symbol": "SIM_EVENT_1.MARKET_1",
"interval": "1m",
"data": [
{
"time": "1731535960000",
"open": "0.520000",
"high": "0.570000",
"low": "0.510000",
"close": "0.550000",
"volume": "120",
"taker_buy_volume": "70",
"taker_sell_volume": "50",
"volume_notional": "66.000000",
"taker_buy_volume_notional": "38.500000",
"taker_sell_volume_notional": "27.500000",
"trade_count": "8",
"taker_buy_count": "5",
"taker_sell_count": "3"
}
],
"type": "update",
"round": "12346",
"exchange_time_ms": "1731536000100"
}data is a JSON array of candle objects. Every element in the array is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
time | integer string | Yes | Time. |
open | decimal string, 6 d.p. | Yes | Open. |
high | decimal string, 6 d.p. | Yes | High. |
low | decimal string, 6 d.p. | Yes | Low. |
close | decimal string, 6 d.p. | Yes | Close. |
volume | integer string | Yes | Volume. |
taker_buy_volume | integer string | Yes | Taker buy volume. |
taker_sell_volume | integer string | Yes | Taker sell volume. |
volume_notional | decimal string, 6 d.p. | Yes | Volume notional. |
taker_buy_volume_notional | decimal string, 6 d.p. | Yes | Taker buy volume notional. |
taker_sell_volume_notional | decimal string, 6 d.p. | Yes | Taker sell volume notional. |
trade_count | integer string | Yes | Trade count. |
taker_buy_count | integer string | Yes | Taker buy count. |
taker_sell_count | integer string | Yes | Taker sell count. |
Channel Descriptor
| Field | Type | Required | Description |
|---|---|---|---|
channel | string literal "candles" | Yes | Channel discriminator. |
symbol | string | Yes | Symbol. |
interval | CandleInterval | Yes | Interval. |
Account Channel#
Live account updates for one owner.
JSON Message Payload
{
"channel": "account",
"user": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"data": {
"orders": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"side": "BID",
"size_original": "10",
"size_filled": "3",
"notional_filled": "1.650000",
"size_remaining": "7",
"price": "0.550000",
"status": "OPEN",
"tif": "GTC",
"type": "LIMIT",
"post_only": false,
"reduce_only": false,
"expires_ts_ms": "0",
"client_order_id": "42",
"id": "987654321",
"place_ts_ms": "1731536000050",
"place_round": "12345",
"update_ts_ms": "1731536000050",
"update_round": "12345"
}
],
"fills": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"client_order_id": "42",
"order_id": "987654321",
"trade_id": "555001",
"trade_ts_ms": "1731536000050",
"cursor": "00000000000000067891:0000000000",
"round": "12345",
"side": "BID",
"liquidity": "TAKER",
"fill_size": "3",
"fill_price": "0.550000",
"fee_usd": "-0.020000",
"collateral_change_usd": "-1.650000",
"position_size_prev": "0",
"realized_pnl_usd": "0.000000"
}
],
"positions": [
{
"symbol": "SIM_EVENT_1.MARKET_1",
"size": "7",
"mark_price": "0.550000",
"average_entry_price": "0.520000",
"remaining_entry_notional_usd": "3.640000",
"realized_pnl_usd": "0.000000",
"open_size": "10",
"open_notional": "5.200000",
"close_size": "3",
"close_notional": "1.650000",
"cumulative_fees_paid": "-0.020000",
"open_ts_ms": "1731535900000",
"open_round": "12340",
"update_ts_ms": "1731536000050",
"update_round": "12345"
}
],
"resolutions": [],
"inflight_deposits": [
{
"deposit_seq": "9",
"owner": "GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB",
"amount": "100.000000",
"status": "FINALIZED"
}
],
"transfers": [
{
"collateral_change": "100.000000",
"type": "DEPOSIT",
"time_ms": "1731535900000",
"cursor": "00000000000000067880:0000000000"
}
],
"collateral_usd": "100.000000"
},
"type": "update",
"round": "12346",
"exchange_time_ms": "1731536000100"
}| Field | Type | Required | Description |
|---|---|---|---|
orders | array of OrderMsg | Yes | Orders. |
fills | array of FillMsg | Yes | Fills. |
positions | array of PositionMsg | Yes | Positions. |
resolutions | array of PositionResolutionMsg | Yes | Resolutions. |
inflight_deposits | array of DepositMsg | Yes | Inflight deposits. |
transfers | array of TransferMsg | Yes | Transfers. |
collateral_usd | decimal string, 6 d.p. | No | Collateral usd. |
Every element in orders is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
side | Side | Yes | Side. |
size_original | integer string | Yes | Size original. |
size_filled | integer string | Yes | Size filled. |
notional_filled | decimal string, 6 d.p. | Yes | Cumulative notional fill value: sum of fill_price * fill_size for all fills. Divide by size_filled to get the average fill price. |
size_remaining | integer string | Yes | Size remaining. |
price | decimal string, 6 d.p. | Yes | Price. |
status | OrderStatus | Yes | Status. |
tif | TimeInForce | Yes | Tif. |
type | OrderType | Yes | Type. |
post_only | boolean | Yes | Post only. |
reduce_only | boolean | Yes | Reduce only. |
expires_ts_ms | integer string | Yes | Expires ts ms. |
client_order_id | integer string | Yes | Client order id. |
id | integer string | Yes | Id. |
place_ts_ms | integer string | Yes | Place ts ms. |
place_round | integer string | Yes | Place round. |
update_ts_ms | integer string | Yes | Update ts ms. |
update_round | integer string | Yes | Update round. |
builder_key | base58 string | No | Builder key. |
builder_fee_rate | signed decimal string, 6 d.p. | No | Builder fee rate. |
Every element in fills is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
client_order_id | integer string | Yes | Client order id. |
order_id | integer string | Yes | Order id. |
trade_id | integer string | Yes | Trade id. |
trade_ts_ms | integer string | Yes | Trade ts ms. |
cursor | fixed-width cursor string | Yes | Cursor. |
round | integer string | Yes | Round. |
side | Side | Yes | Side. |
liquidity | Liquidity | Yes | Liquidity. |
fill_size | integer string | Yes | Fill size. |
fill_price | decimal string, 6 d.p. | Yes | Fill price. |
fee_usd | signed decimal string, 6 d.p. | Yes | Fee usd. |
collateral_change_usd | signed decimal string, 6 d.p. | Yes | Collateral change usd. |
builder_key | base58 string | No | Builder key. |
builder_fee_usd | signed decimal string, 6 d.p. | No | Builder fee usd. |
position_size_prev | signed integer string | Yes | Position size prev. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized pnl usd. |
Every element in positions is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
size | signed integer string | Yes | Signed position size. Positive for long, negative for short. |
mark_price | decimal string, 6 d.p. | Yes | Median of whichever of (best bid, best ask, last trade) are available. |
average_entry_price | decimal string, 6 d.p. | No | Display value for UI: average entry price of the remaining open position. Do not use for PnL accounting; use remaining_entry_notional_usd. None means there is no remaining open position. |
remaining_entry_notional_usd | decimal string, 6 d.p. | Yes | Total entry notional still assigned to the current open position. This is the entry notional of the remaining position after accounting for partial closes. For example, after opening 10 contracts and closing 4, this is the entry notional still assigned to the remaining 6 contracts. Use this with the latest mark price and size to compute exact unrealized PnL. average_entry_price is derived from this value for display. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized PnL accumulated in the current position lifecycle, excluding fees. |
open_size | integer string | Yes | Cumulative size of opening trades since last zero crossing. |
open_notional | decimal string, 6 d.p. | Yes | Cumulative notional of opening trades (sum of price * size for openings) |
close_size | integer string | Yes | Cumulative size of closing trades since last zero crossing. |
close_notional | decimal string, 6 d.p. | Yes | Cumulative notional of closing trades (sum of price * size for closings) |
cumulative_fees_paid | signed decimal string, 6 d.p. | Yes | Cumulative fees paid on the position. |
open_ts_ms | integer string | Yes | When this position was opened. Resets on zero crossing (direction flip). |
open_round | integer string | Yes | Open round. |
update_ts_ms | integer string | Yes | When this position last changed. Advances on every fill and resolution. |
update_round | integer string | Yes | Update round. |
Every element in resolutions is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Symbol. |
resolution | decimal string, 6 d.p. | Yes | Resolution. |
size | signed integer string | Yes | Size. |
collateral_change_usd | decimal string, 6 d.p. | Yes | Collateral change usd. |
realized_pnl_usd | signed decimal string, 6 d.p. | Yes | Realized pnl usd. |
time_ms | integer string | Yes | Time ms. |
round | integer string | Yes | Round. |
Every element in inflight_deposits is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
deposit_seq | integer string | Yes | Deposit seq. |
owner | base58 string | Yes | Owner. |
amount | decimal string, 6 d.p. | Yes | Amount. |
status | DepositStatus | Yes | Status. |
Every element in transfers is a JSON object:
| Field | Type | Required | Description |
|---|---|---|---|
collateral_change | signed decimal string, 6 d.p. | Yes | Collateral change. |
type | TransferType | Yes | Type. |
time_ms | integer string | Yes | Time ms. |
cursor | fixed-width cursor string | Yes | Cursor. |
Channel Descriptor
| Field | Type | Required | Description |
|---|---|---|---|
channel | string literal "account" | Yes | Channel discriminator. |
user | base58 string | Yes | User. |
Pagination#
Paginated endpoints accept before_cursor and limit. Cursors are opaque strings of the form {esm_seq:020}:{event_index:010}. A request whose cursor references a sequence ahead of the current historical watermark is rejected with service_unavailable.
Paginated responses include items, optional next_cursor, and historical_context. The concrete item table is shown under each paginated endpoint.
Error Codes#
Read API errors use ErrorCode.
| Value | Description |
|---|---|
"invalid_request" | InvalidRequest. |
"market_not_found" | MarketNotFound. |
"symbol_not_found" | SymbolNotFound. |
"user_not_found" | UserNotFound. |
"invalid_market_id" | InvalidMarketId. |
"invalid_interval" | InvalidInterval. |
"invalid_limit" | InvalidLimit. |
"internal_error" | InternalError. |
"service_unavailable" | ServiceUnavailable. |
"not_ready" | NotReady. |
"backpressure" | Backpressure. |
Write-side command errors are returned as stable string code values inside WriteErrorResponse.
| Field | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Code. |
details | JSON value | No | Details. |