Errors

RFC 9457 problem+json, and every status code the API returns.

Errors are RFC 9457 problem details, served as Content-Type: application/problem+json.

{
  "type": "https://www.cruxal.in/docs/errors#rate-limit-exceeded",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit of 300 requests per minute exceeded. Limits are measured in fixed one-minute windows.",
  "instance": "/v1/filings"
}

type is a URL that resolves to a page explaining that specific error. Branch your code on type or on the HTTP status — never on the wording of detail, which may be reworded.

Status codes

StatustypeMeaning
400bad-requestMalformed request — most often a cursor reused after a filter changed.
400invalid-requestA parameter failed validation. Carries an errors array.
401unauthorizedMissing, malformed, unknown, revoked or expired key.
403quota-exceededMonthly quota exhausted. Retrying will not help.
404not-foundNo such filing, company or article — or it is outside your plan's freshness window.
405method-not-allowedWrong HTTP verb. Every endpoint here is GET.
429rate-limit-exceededPer-minute rate exceeded. Honour Retry-After.
500internal-errorOur fault. Carries a trace_id — quote it when you contact support.

Validation errors

A 400 from validation carries an errors array naming each offending field:

{
  "type": "https://www.cruxal.in/docs/errors#invalid-request",
  "title": "Invalid Request",
  "status": 400,
  "detail": "One or more request parameters are invalid.",
  "instance": "/v1/filings",
  "errors": [
    { "field": "limit", "message": "Input should be less than or equal to 200", "type": "less_than_equal" }
  ]
}

A note on 404

A 404 on a specific filing can mean either that it does not exist, or that it exists but is newer than your plan's freshness window allows. These are deliberately indistinguishable — otherwise a delayed plan could confirm that a filing had landed and read its timing, which is exactly the real-time signal the plan does not include.

Retrying

  • 429 — wait for Retry-After, then retry. Safe.
  • 500 — retry with backoff. All endpoints are GET and idempotent.
  • 400, 401, 403, 404, 405 — do not retry. Nothing will change until you change the request.

Error reference

Each heading below is the target of the type URL on that error.

bad-request — 400

The request could not be processed as sent. The most common cause is reusing a pagination cursor after changing a filter; see pagination. Do not retry without changing the request.

invalid-request — 400

A parameter failed validation. The errors array names each offending field and why it was rejected. Fix the parameter and retry.

unauthorized — 401

The key was missing, malformed, unknown, revoked or expired. These cases are deliberately indistinguishable — see authentication. Check that you are sending Authorization: Bearer ck_live_… and that the key is still active on your API Keys page.

forbidden — 403

The key is valid but is not permitted to do this. Check the scopes on the key.

quota-exceeded — 403

Your monthly quota is exhausted. Retrying will not help — that is why this is a 403 and not a 429, and why it carries no Retry-After. Upgrade your plan, or wait for the next billing month, which begins at midnight IST on the 1st. Check consumption at /v1/usage.

not-found — 404

No such filing, company or article — or it exists but is newer than your plan's freshness window. The two are deliberately indistinguishable; see limits and caveats.

method-not-allowed — 405

Wrong HTTP verb. Every endpoint in this API is a GET.

rate-limit-exceeded — 429

You exceeded your per-minute rate. Honour the Retry-After header and retry — this limit recovers on its own. See rate limits.

internal-error — 500

Our fault. The response carries a trace_id; quote it when you contact support. Retry with backoff — every endpoint is a GET and safe to repeat.

Get started

Create a free account, then mint an API key and make your first request in under two minutes.