API documentation

API Changelog

Every change to the public API, newest first.

API v1: one response envelope, real JSON types and standard errors

2026-09-29

Every /api/v1 endpoint now uses the response format below. The URLs stay the same, the JSON changed, so please check your integration. The MCP server was updated at the same time.

  • Every JSON response is { "data": ..., "meta": { ... } }. meta.generated_at replaces generatedAt and timestamp; meta.as_of replaces dataDate, date and dates.
  • All fields are snake_case, for example computedAt becomes computed_at and sourceTopic becomes source_topic.
  • Numbers are JSON numbers ("189.4500" becomes 189.45 and "+1.25%" becomes 1.25), trading dates are YYYY-MM-DD, timestamps are RFC 3339 UTC, and missing values are null instead of empty strings.
  • Candles and chart pattern points use a date field (YYYY-MM-DD) instead of time in Unix seconds.
  • Errors are RFC 9457 application/problem+json documents with a stable code and a request_id; the error field is replaced by title and detail.
  • Validation is strict: malformed or out-of-range parameters, impossible dates, unknown screener slugs and unknown pattern ids return 400 instead of being adjusted or ignored. Out-of-range values are rejected, not clamped to the nearest valid value.
  • List endpoints page with limit and cursor (meta.pagination.next_cursor and a Link header), which on /screeners/{slug} replaces the old page parameter (now removed) and pins the snapshot date across pages instead of repeating date on every request.
  • New RateLimit and RateLimit-Policy headers, Retry-After on every 429, and requests that end in 400, 401, 403, 404 or 304 no longer count against your quota.
  • Responses carry ETag and Cache-Control: private, max-age=60. Send If-None-Match to get a 304 that costs no quota.
  • The OpenAPI spec at /openapi.yaml and /openapi.json is now version 3.1, using JSON Schema 2020-12 nullability instead of the old nullable keyword.
  • Public endpoints (/screeners, /stocks/{symbol}, /search/*) allow 30 requests per minute per IP without a key, and an invalid key now returns 401 instead of anonymous data.
  • /stocks/{symbol} now only sources data from the screeners included in your plan, so anonymous and free-tier requests no longer see paid-only screener data through this endpoint.
  • /search/screeners now omits screeners above your plan from the results; the 3 free-tier screeners are always included.
  • POST /patterns now returns 403 SCREENER_NOT_ACCESSIBLE when a requested screener is above your plan, instead of silently dropping it from the results.
  • MCP tools are updated in lockstep with this release: the same envelope, fields and error codes, and cursor-based paging in place of page.
  • Fixed: /screeners/market-momentum returns data again, /stocks/{symbol} returns percent_change reliably, and impossible dates return 400 instead of 500.