Authentication

The Bearer scheme

Every request must carry an API key in the Authorization header using the Bearer scheme.

Request · Authorization header
POST /v1/options/tool/gainers-losers HTTP/1.1
Host: api.quantdata.us
Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/json

{}

Key format

Keys are 35 characters long, always start with the qd_ prefix, and use the URL-safe alphabet (A–Z, a–z, 0–9). The format check is regex-equivalent to ^qd_[0-9A-Za-z]{32}$.

A malformed key always returns a 401 with the Invalid API key format detail, so you cannot probe for valid keys by sending values close to the expected shape.

<YOUR_API_KEY>

A representative key. Yours will look the same shape with different random characters.

Managing keys

Keys are issued, listed, and revoked from your Quant Data dashboard. The API itself has no key-management endpoints.

Generate
Open the API keys page in your dashboard and click Create API key. The full key is displayed only once at creation, so copy it into your secrets store before navigating away. After that, only the first few characters are shown, so the dashboard can identify the key without exposing it.
Rotate
Generate a new key, swap it into your application, then revoke the old one. A rotation has no downtime if you do it in that order, since the API accepts every active key your account owns simultaneously.
Revoke
Click Revoke API key in the dashboard. The key becomes inactive immediately; requests carrying it return 401 on the very next call. Revocation is not undoable: generate a new key if you need to reverse course.

Storing keys safely

A few habits that keep a key from showing up in places it should not.

Safe handling
  • Treat the key like a password. Anyone who has it can spend your quota and read every endpoint you have access to.
  • Read it from an environment variable or a secrets manager. Never check it into source control, even in a private repo.
  • Use a separate key per environment (local, staging, production). If one leaks you can revoke just that one without breaking everything else.
  • Rotate keys when someone with access leaves. Generating a new key, swapping it in, and revoking the old one takes well under a minute.

Authentication errors

Every authentication failure is an RFC 9457 problem-detail response with Content-Type: application/problem+json. The type URI groups failures by category; the detail string names the exact case. There are three categories and six concrete cases.

Missing or malformed header · 401

The Authorization header is absent, or it does not start with the literal string Bearer . Most commonly this is a forgotten header on the first request from a new client.

Response · missing header
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json

{
  "type": "https://quantdata.us/errors/authentication",
  "title": "Authentication Required",
  "status": 401,
  "detail": "Missing or malformed Authorization header. Expected: Bearer qd_...",
  "instance": "/v1/options/tool/gainers-losers"
}

Invalid key format · 401

The header is present and uses the Bearer scheme, but the key after the prefix does not match ^qd_[0-9A-Za-z]{32}$. Usually a truncation, a stray whitespace, or an accidental paste of a placeholder.

Response · invalid format
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json

{
  "type": "https://quantdata.us/errors/authentication",
  "title": "Authentication Failed",
  "status": 401,
  "detail": "Invalid API key format.",
  "instance": "/v1/options/tool/gainers-losers"
}

Unknown key · 401

The key matches the expected shape but is not recognized. Either it was mistyped, never issued, or belongs to a different environment than the one you are calling.

Response · unknown key
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json

{
  "type": "https://quantdata.us/errors/authentication",
  "title": "Authentication Failed",
  "status": 401,
  "detail": "Invalid API key.",
  "instance": "/v1/options/tool/gainers-losers"
}

Revoked key · 401

The key exists but is in an inactive state. It was revoked from the dashboard at some point; any traffic still using it should be cut over to a fresh key.

Response · revoked key
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json

{
  "type": "https://quantdata.us/errors/authentication",
  "title": "Authentication Failed",
  "status": 401,
  "detail": "API key has been revoked.",
  "instance": "/v1/options/tool/gainers-losers"
}

Subscription required · 403

The key authenticated successfully and the account exists, but the account does not have an active API subscription. This returns 403 Forbidden rather than 401: the request was authenticated, just not authorized. Resolve it by renewing or upgrading from your dashboard's billing panel.

Response · subscription required
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json

{
  "type": "https://quantdata.us/errors/authorization",
  "title": "API Subscription Required",
  "status": 403,
  "detail": "An active API subscription is required to access this endpoint.",
  "instance": "/v1/options/tool/gainers-losers"
}

OPRA agreement required · 403

The key authenticated and the account has an active API subscription, but the user has not yet signed the OPRA market-data subscriber agreement that the Options Price Reporting Authority requires before any OPRA-sourced quotes can be returned. The signing URL is in detail and also surfaced as an agreementUrl extension property, so programmatic clients can branch on type and read the link directly. Sign at the OPRA subscriber agreement page, then retry.

Response · OPRA agreement required
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json

{
  "type": "https://quantdata.us/errors/opra-agreement-required",
  "title": "OPRA Agreement Required",
  "status": 403,
  "detail": "You must sign the OPRA market-data agreement before using this API. Sign at: https://v3.quantdata.us/legal/agreement",
  "instance": "/v1/options/tool/gainers-losers",
  "agreementUrl": "https://v3.quantdata.us/legal/agreement"
}

Where to go next