Synpath
Overview

Errors and pagination

What a non-2xx response carries, which status means what, and how cursors work.

The error body

Every non-2xx response, on every route of your server, carries one shape. Branch on code; show message to people.

application/json
{
  "error": {
    "code": "risk_rejected",
    "message": "10000 contracts is over the 100 limit",
    "details": { "rule": "max_order_contracts", "venue": "kalshi", "retryable": false }
  }
}
FieldMeaning
codeMachine-readable, snake_case. The library's exception in snake case (market_not_found, insufficient_funds, order_rejected, risk_rejected, rate_limit_exceeded), or unauthorized, forbidden, not_found, validation_error, unknown_venue
messageWhat happened, with the venue's own reason where there is one
details.venueThe venue that answered, or null when your server refused on its own
details.retryableTrue when the request never got a verdict: a timeout, a rate limit, a venue down. Wait and retry those; do not retry the rest
details.ruleOn risk_rejected: the rule that refused, such as max_order_contracts or kill_switch
details.errorsOn validation_error: one entry per field, {field, message}
details.retry_afterOn a rate limit, when known: seconds to wait. Also sent as the Retry-After header

Status codes

StatusMeaning
400Bad parameters: an unknown venue, a status outside the four, an id from another venue. On an order, also the venue's refusal, such as insufficient balance, with its reason
401No key, or an unknown one (trading API)
403The key lacks the permission this route needs
404No such market, order or series
409Refused before sending, by a risk rule or a halt; the message names the rule. Also a market the venue has halted
422The request body does not match the schema: a missing field or a value of the wrong type
429Slow down. The venue's limit, passed through; retryable is true
501The venue has no such capability. Read has on GET /venues first
502The venue failed the request
504The venue did not answer

Pagination

Lists page by cursor, never by offset: the underlying set changes between calls, and an offset would skip or repeat rows. Pass next_cursor back as cursor, unchanged, with the same filters. null means the venue returned no continuation.

curl "https://api.synpath.dev/venues/kalshi/markets?limit=100"
# { "data": [...], "next_cursor": "eyJjIjoiQ0RJIiwibyI6NX0", "count": 100 }

curl "https://api.synpath.dev/venues/kalshi/markets?limit=100&cursor=eyJjIjoiQ0RJIiwibyI6NX0"

Search results are ranked by relevance, so paging deep into a large result set is best effort. To enumerate a whole catalog, walk without query.