Skip to main content

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​

HeaderDirectionPurpose
AuthorizationRequestBearer session token or delegated credential token where applicable
Idempotency-KeyRequestSafe retry key for signed action submit, delegated batch, and replace/cancel flows
X-Client-Order-IdRequestStrategy-level order identity on delegated place-order surfaces
X-Request-IdResponseSupport and trace identifier
X-RateLimit-LimitResponseAllowed requests in current window
X-RateLimit-RemainingResponseRemaining requests in current window
X-RateLimit-Reset-MsResponseMilliseconds until the current window resets
X-RateLimit-SourceResponseOptional source label for a reported budget. Absence means no source metadata was available.
Retry-AfterResponseOptional authoritative backoff guidance for 429 and 503; use capped exponential backoff with jitter when absent.
Cache-ControlResponseRoute-specific public-read cache policy. Live/private responses are not made cacheable.
ETagResponseValidator for cacheable catalog responses such as exchange info; send it back as If-None-Match.
X-SC-Error-Format: envelope-v1RequestSelect the common JSON error envelope while legacy clients retain their existing response fields.
X-SC-Response-Format: canonical-v1RequestSelect the documented lean JSON response during the compatibility window.
Deprecation, Sunset, LinkResponseIdentify 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 surfaceUnits and spelling
*Micro, raw signed action price / qtyInteger atoms at a scale of 1,000,000. Decimal strings are common on reads. Asset deposit atoms use the asset's advertised decimals.
*PpmInteger parts per million; 10000 is 1%.
*BpsInteger basis points; 100 is 1%.
*Ms, action/trade tsUnix milliseconds for instants; durations such as retryAfterMs are elapsed milliseconds. A field-specific schema overrides the default.
JSON fieldsNew response fields use camelCase. Existing cursor fields use snake_case; signed canonical bytes retain their specified serialization.
Market identifierNumeric 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 levelsGET /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 identifiersHex strings; a 20-byte engine account differs from a 32-byte trading-account id or order id.
SideTyped signed actions use Bid / Ask; delegated human-order facades use their documented buy / sell values. Feed levels use bid / ask.
Book / outcomePrediction orders use YES / NO; spot orders omit the outcome-book field. Public trade rows may use SPOT; feed levels use lowercase spot / yes / no.
ExpiryexpiresAt 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.