Authentication
The Bearer scheme
Every request must carry an API key in the Authorization header using the Bearer scheme.
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.
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.
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.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.
- 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.
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.
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.
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.
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.
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.
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"
}