Errors
The structured error envelope, stable code families, HTTP mapping, and retryability rules.
Draft v0.1 — design contract, not yet a live service
This documentation set defines a proposed Time Seventeen protocol for review and implementation planning. https://api.t17.capital is the approved and reserved REST origin, but neither that origin nor any documented endpoint is claimed to be live. The WebSocket origin remains unspecified. Credentials, chain IDs, contract addresses, rate limits, and SLAs remain unapproved; IDs, prices, and timestamps shown throughout are illustrative, not real production data.
HTTP status conveys the transport-level failure class. The stable error.code field conveys the protocol-level behavior a client should branch on — clients SHOULD switch on code, not on the HTTP status or the message text.
Envelope
{
"error": {
"code": "ORDER_POST_ONLY_WOULD_TAKE",
"message": "The order would execute immediately and cannot be posted as maker-only.",
"retryable": false,
"details": {},
"field_violations": [],
"request_id": "req_demo_001"
}
}| Field | Description |
|---|---|
code | Stable, machine-readable error code from one of the families below |
message | Human-readable explanation; not stable across releases |
retryable | Whether an unmodified retry of the same request could plausibly succeed |
details | Structured, code-specific context |
field_violations | Array of { "field": string, "reason": string } for validation failures |
request_id | Correlates the error with meta.request_id / T17-Request-Id for support |
Field violation example
{
"error": {
"code": "VALIDATION_FIELD_INVALID",
"message": "One or more fields failed validation.",
"retryable": false,
"details": {},
"field_violations": [
{ "field": "price", "reason": "must be a positive fixed-point decimal string" },
{ "field": "time_in_force", "reason": "unrecognized enum value" }
],
"request_id": "req_demo_003"
}
}Code families
| Family | Purpose |
|---|---|
AUTH_* | Missing, invalid, expired, or insufficiently scoped credential |
SIGNATURE_* | Request-signature or EIP-712 signature verification failure |
REPLAY_* | Timestamp/nonce outside tolerance, or a previously used (key_id, nonce) |
VALIDATION_* | Malformed input, unknown enum/filter/sort/expand value, schema violation |
MARKET_* | Market/outcome not found, closed, halted, or otherwise ineligible for the request |
ORDER_* | Order-specific rejection (tick/lot size, post-only crossing, duplicate client ID, and so on) |
RISK_* | Position limits, price protection, or account risk-policy rejection |
BALANCE_* | Insufficient balance/collateral for the requested action |
RATE_LIMIT_* | Request exceeds the caller’s configured rate-limit class |
STREAM_* | WebSocket subscription, resume, or sequence-gap error |
SETTLEMENT_* | Settlement/redemption-specific failure |
INTERNAL_* | Unexpected server-side failure; always retryable: true unless documented otherwise |
IDEMPOTENCY_CONFLICT | An Idempotency-Key was reused with a different canonical request body |
Representative failure matrix
code | Typical HTTP status | retryable | Notes |
|---|---|---|---|
AUTH_INVALID_SIGNATURE | 401 | false | Canonical request signature does not verify |
AUTH_KEY_REVOKED | 401 | false | API key has been rotated or revoked |
REPLAY_NONCE_REUSED | 409 | false | (key_id, nonce) pair already accepted |
REPLAY_TIMESTAMP_SKEW | 401 | false | Request timestamp outside the accepted clock-skew window |
SIGNATURE_DOMAIN_MISMATCH | 400 | false | EIP-712 domain does not match the expected protocol/version/environment |
VALIDATION_FIELD_INVALID | 400 | false | One or more fields failed schema/format validation |
IDEMPOTENCY_CONFLICT | 409 | false | Same Idempotency-Key, different canonical body |
MARKET_NOT_TRADABLE | 409 | false | Market/outcome status does not permit new orders |
ORDER_TICK_SIZE_INVALID | 400 | false | Price does not align to the market’s price increment |
ORDER_POST_ONLY_WOULD_TAKE | 409 | false | post_only order would cross the book |
ORDER_DUPLICATE_CLIENT_ID | 409 | false | Client order ID already used by a non-terminal order |
RISK_POSITION_LIMIT_EXCEEDED | 409 | false | Order would breach a configured position limit |
BALANCE_INSUFFICIENT_COLLATERAL | 409 | false | Account lacks sufficient collateral/balance |
RATE_LIMIT_EXCEEDED | 429 | true | Caller exceeded the applicable rate-limit class; honor T17-RateLimit-Reset |
STREAM_RESUME_UNAVAILABLE | — (WS) | false | Resume cursor outside retention; client must request a fresh snapshot |
SETTLEMENT_FAILED | 409 | false | Settlement attempt failed; see Settlement for retry semantics |
INTERNAL_ERROR | 500 | true | Unexpected server failure |
Batch errors
A batch endpoint (see Orders → batch placement) never fails the whole request because one item failed. Each item reports its own status and, on failure, its own error object using the same code families as above.
Where to go next
- Conventions for the response envelope and rate-limit header shape these errors sit inside.
- Authentication for the
AUTH_*,SIGNATURE_*, andREPLAY_*families in context. - Orders for the full order-validation pipeline and its rejection reasons.