Skip to content
/api/v1/policy

Rate-limit, metering, versioning and freshness policy

The complete, machine-readable API policy: request-rate limits by enforcement layer (with an honest 429-headers statement), the token-metering / 402 quota model, WebSocket connection limits, the semantic-versioning + deprecation promise, request body-size + timeout limits, and per-data-family freshness. Static and free (`cost: 0`) — safe to poll.

Why use this

The single source for how to integrate safely. (1) RATE LIMITS — two enforcement layers. An app-wide default limiter (per client IP) allows 60 requests/minute + 1000/hour on every endpoint and emits `Retry-After` + `X-RateLimit-Limit`/`Remaining`/`Reset` on its 429. In FRONT of that, a gateway rate-limits two families by IP: Company Financials at 30/min (burst 10) and XBRL financial statements at 120/min (burst 30) — a gateway 429 carries NEITHER `Retry-After` NOR `X-RateLimit-*`. A few routes are tighter (and DO emit headers): account registration 5/hour per IP + 3/hour per email, and the SQL proxy 30/minute. The insider service is a separate service with its own per-plan limiter (free 100/min, paid 600/min). Every over-limit response is HTTP 429 with `error.code='RATE_LIMIT_EXCEEDED'`. (2) METERING & QUOTA — metered endpoints debit a per-request token cost from your plan's balance; the debited amount is returned on the `X-Tokens-Charged` header, and a failed call (4xx/5xx) is automatically refunded so you only pay for a result. When your balance is exhausted a metered call returns HTTP 402 with your current balance, the cost it needed, your next refill time, your plan and an upgrade link. Quotas are set per your plan. Token metering is a pilot and is enabled per account. (3) WEBSOCKET — real-time feeds run over Socket.IO with concurrent connections capped per plan (free 1, paid 5); on reconnect, missed events replay up to 20 per connection. (4) VERSIONING — semantic versioning: additive changes bump the MINOR version and appear in the changelog; breaking changes are flagged **BREAKING** with a migration path and a deprecation window. A deprecated endpoint keeps serving during its window, is marked `deprecated: true` in the OpenAPI spec, and carries `Deprecation` + (when scheduled) `Sunset` headers (RFC 8594). No endpoint is deprecated today. Every response carries the live contract version in the `X-API-Version` header. (5) REQUEST LIMITS — request bodies are capped at 50 MB; the server applies a 300-second timeout. (6) FRESHNESS — stated per data family; see the freshness object. Live ingestion timestamps are at `/api/v1/financials/status`; covered XBRL companies are at `/api/v1/xbrl/coverage`. No authentication required.

Common use case

Reading the rate-limit ceilings, quota model and freshness promise before wiring a client, and knowing precisely which 429s carry a Retry-After to back off on.

The complete published rules of engagement — rate limits (by enforcement layer), token metering / 402 quota, WebSocket limits, versioning/deprecation, request limits, and per-family data freshness — served as JSON. Honest 429-headers rule: the app-wide default limiter and the tighter per-route limits emit Retry-After + X-RateLimit-*; the gateway-enforced Company Financials and XBRL zones do not. The contract version is on every response via X-API-Version. Live ingestion timing is at /api/v1/financials/status; the covered XBRL universe is at /api/v1/xbrl/coverage. Human-readable versions live on the Changelog and OpenAPI pages.

Response schema

FieldTypeNullableDescription
api_versionstringnoThe current public API contract version (semantic version). Matches the `X-API-Version` header stamped on every response and `info.version` in the OpenAPI spec.
rate_limitsobjectnoRequest-rate limits by enforcement layer. The app-wide default limiter allows `global_default_per_minute` (60) + `global_default_per_hour` (1000) and emits `Retry-After` + `X-RateLimit-*` on its 429 (`global_limit_headers_on_429`). Two families are rate-limited at the gateway instead: `financials_endpoints_per_minute` (30, burst 10) and `xbrl_endpoints_per_minute` (120, burst 30) — a gateway 429 carries NO rate-limit headers (`gateway_429_carries_rate_limit_headers: false`). Tighter per-route limits: `register_per_hour_per_ip` (5), `register_per_hour_per_email` (3), `sql_proxy_per_minute` (30). The separate insider service limits per plan: `insider_service_per_minute_free` (100), `insider_service_per_minute_paid` (600). Every over-limit response is `over_limit_status` (429) with `over_limit_error_code` (`RATE_LIMIT_EXCEEDED`).
meteringobjectnoThe token-metering / quota model. `model` (per-request token debit); the debited amount is returned on the `cost_header` (`X-Tokens-Charged`); a failed call is refunded (`failed_call_refunded: true`). When your balance is exhausted a metered call returns `over_quota_status` (402) with `over_quota_error` (`insufficient_tokens`) and a payload carrying balance / required cost / next refill / plan / upgrade link. `quota_source` is `per_account_plan` (quotas are per your plan, not a published constant). `pilot: true` — metering is enabled per account.
websocketobjectnoReal-time feed limits: `transport` (socket.io), concurrent connections capped per plan — `concurrent_connections_free` (1), `concurrent_connections_paid` (5) — and `catchup_events_per_connect` (20) replayed on reconnect.
versioningobjectnoThe semantic-versioning + deprecation promise: `scheme` (semver), `current` version, `version_header` (`X-API-Version`), `additive_change` (minor bump), `breaking_change` (flagged BREAKING with migration path), `deprecation_headers` (`Deprecation` + `Sunset`, RFC 8594), `no_endpoints_currently_deprecated` (true), and links to the changelog and OpenAPI spec.
request_limitsobjectnoRequest size + timeout limits: `max_request_body_bytes` (50 MB) and `server_timeout_seconds` (300).
freshnessobjectnoPer-data-family freshness statements: `sec_filings`, `insider`, `form_13f`, `form_13dg`, `prices`, `xbrl_fundamentals`, plus `vintage_fields` each response cell carries, the `freshness_endpoint` for live ingestion timing, and the `coverage_endpoint` for the covered XBRL universe. No claim of point-in-time replay on every cell: XBRL point-in-time selection is scoped to standardized annual/quarterly base-metric cells for covered companies.
toolingobjectnoThe client-side tooling that ships alongside the API: `openapi_spec_url` (/openapi.json — the machine-readable spec, generated from these docs), `python_sdk_install` (`pipx install finradar-cli` — the Python client + CLI), `cli_install` (the branded one-line installer), and `mcp_server_docs` (/integrations/mcp — an MCP server for AI agents), plus a plain-English `statement`.

Sample response

·
  • "status": "success"
  • "request_id": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
  • "timestamp": "2026-07-16T12:00:00Z"
  • "data":
    • "api_version": "3.106.0"
    • "rate_limits":
    • "metering":
    • "websocket":
    • "versioning":
    • "request_limits":
    • "freshness":
    • "tooling":
    }
}

Errors

StatusLabelDescription
200OKRequest succeeded.
400Bad RequestInvalid query, body, or path parameter.
401UnauthorizedMissing or invalid Authorization header / api_Token.
402Payment RequiredInsufficient token balance for this call. Top up
429Too Many RequestsRate limit exceeded for your tier (see /pricing for tier limits). Tier limits
500Server ErrorUnexpected server-side failure. Retry with backoff; report if persistent.

Code samples

curl "https://api.finradar.ai/api/v1/policy" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).