HTTP Conventions
Senticore HTTP endpoints use JSON request and response bodies, explicit headers for tracing, rate limits, and idempotency, and a stable top-level error envelope for normalized transport and API errors.
Headers
| Header | Direction | Purpose |
|---|---|---|
Authorization | Request | Bearer session token or delegated credential token where applicable |
Idempotency-Key | Request | Safe retry key for signed action submit, delegated batch, and replace/cancel flows |
X-Client-Order-Id | Request | Strategy-level order identity on delegated place-order surfaces |
X-Request-Id | Response | Support and trace identifier |
X-RateLimit-Limit | Response | Allowed requests in current window |
X-RateLimit-Remaining | Response | Remaining requests in current window |
X-RateLimit-Reset-Ms | Response | Milliseconds until the current window resets |
X-RateLimit-Source | Response | Optional source label for a reported budget. Absence means no source metadata was available. |
Retry-After | Response | Optional authoritative backoff guidance for 429 and 503; use capped exponential backoff with jitter when absent. |
Cache-Control | Response | Route-specific public-read cache policy. Live/private responses are not made cacheable. |
ETag | Response | Validator for cacheable catalog responses such as exchange info; send it back as If-None-Match. |
X-SC-Error-Format: envelope-v1 | Request | Select the common JSON error envelope while legacy clients retain their existing response fields. |
X-SC-Response-Format: canonical-v1 | Request | Select the documented lean JSON response during the compatibility window. |
Deprecation, Sunset, Link | Response | Identify legacy representations/routes, earliest retirement review and the migration/canonical resource. |
JSON conventions
Use integer arithmetic for atoms, nonces and identifiers. JavaScript clients
must preserve values above Number.MAX_SAFE_INTEGER as decimal strings or
bigint; do not round values before signing.
| Field or surface | Units and spelling |
|---|---|
*Micro, raw signed action price / qty | Integer atoms at a scale of 1,000,000. Decimal strings are common on reads. Asset deposit atoms use the asset's advertised decimals. |
*Ppm | Integer parts per million; 10000 is 1%. |
*Bps | Integer basis points; 100 is 1%. |
*Ms, action/trade ts | Unix milliseconds for instants; durations such as retryAfterMs are elapsed milliseconds. A field-specific schema overrides the default. |
| JSON fields | New response fields use camelCase. Existing cursor fields use snake_case; signed canonical bytes retain their specified serialization. |
| Market identifier | Numeric id in canonical market resources; marketId in JSON, market in signed actions. Legacy market_id query aliases remain accepted where documented. Symbols such as SPOT:ETH/USDC (displaySymbol ETH/USDC) are display/catalog identifiers. |
| Order-book levels | GET /api/v1/public/markets/{id}/orderbook?depth=N&book=SPOT (or YES / NO) returns {price_micros, total_qty} per level. total_qty is the base-asset quantity in micro-units, the same scale as trade qty, and a multiple of lotSizeMicro. There is no /book route. |
| Account and order identifiers | Hex strings; a 20-byte engine account differs from a 32-byte trading-account id or order id. |
| Side | Typed signed actions use Bid / Ask; delegated human-order facades use their documented buy / sell values. Feed levels use bid / ask. |
| Book / outcome | Prediction orders use YES / NO; spot orders omit the outcome-book field. Public trade rows may use SPOT; feed levels use lowercase spot / yes / no. |
| Expiry | expiresAt is an order flag; expiryTsMs is market expiry; expiresAtMs is used by credentials and reservations. Consult the schema for legacy expiry fields. |
Enums are case-sensitive. In particular, candle 1d and legacy 1D have
different interval/window semantics; do not lowercase timeframe inputs.
Pagination
{
"items": [],
"next_cursor": null,
"next_since_id": null,
"has_more": false,
"order": "desc"
}
Public trade history uses this shape. Continue a backward scan with the
returned next_cursor while has_more is true. Forward catch-up uses
sinceId and next_since_id; preserve the server's requested direction.
Cursor values can be integers, so preserve their full precision. Other
historical resources have their own schema; do not assume every list uses
these exact keys. The legacy trades array duplicates items during the
compatibility window; use items in new clients.
X-SC-Response-Format: canonical-v1 omits the documented duplicate arrays and
snapshot aliases: account orders retain items and omit orders; public
trades retain items and omit trades. HTTP snapshots omit market_id,
state_version, mid_micro, mid_yes_micro, mid_no_micro,
volume_24h_micro, ref_24h_micro, ref_24h_yes_micro, ref_24h_no_micro,
top_of_book_checksum, and batchSeq, retaining the corresponding canonical
fields. This negotiation applies to HTTP JSON reads; WebSocket/binary frame
layouts have their own contract. Default responses remain compatible through the earliest
retirement review on 2027-03-07; the date does not automatically remove a
field or route.
Public-read caching
Market catalog routes use a short public cache policy. Exchange info also
supports conditional requests and returns 304 Not Modified when
If-None-Match matches its current ETag. Order books, tickers, trades, and
private/account state are intentionally not covered by that catalog cache
policy. Consume live market data over WebSocket instead of polling REST in
parallel.
Idempotency
Signed action submit and delegated batch flows should send Idempotency-Key for safe network retries. Delegated order placement can also use clientOrderId or X-Client-Order-Id as strategy-level order identity.
See Idempotency.
Account freshness
Account reads can be served from a projection that trails a just-acknowledged write. Before placing an order after a deposit, fill, cancel, nonce fence, or risk rejection, request the authoritative bootstrap view:
GET /api/v1/accounts/{account}/bootstrap?fresh=true
Use the 20-byte engine account in the path. Do not substitute the 32-byte
trading-account control-plane id. Until explicit freshness metadata is deployed
and verified on the public API, compare the returned asOf, nonce, balance,
open-order, and projection fields with the receipt or private event you are
waiting for. Do not submit against an older view merely because the request
returned HTTP 200.
See Account freshness and reconciliation.
Errors
JSON API errors use this top-level envelope when the error can be normalized:
{
"ok": false,
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded",
"retriable": true,
"requestId": "req_01JZ...",
"details": {
"retryAfterMs": 500
}
}
}
Business-level order rejects can also be returned inside a successful submit
envelope, especially on BSL and delegated order-entry surfaces. In that case
inspect ok, actionResults[], items[], error, receipts, fills, and
drop-copy before treating an order as live. Do not retry a business reject
unless the documented response envelope or action-level reject reason is
explicitly retriable.
See Error Model.
For a copy-paste incident checklist and the verified support channel, see Troubleshooting HTTP integrations.