QM Screener documentation
Everything QM Screener knows is reachable over HTTP: three public endpoints, a handful of authenticated ones, and an MCP server. This page is the human version; /openapi.json is the machine version, and the two are generated from the same registry of screens.
API reference
Machine-readable: https://qmscreener.com/openapi.json (OpenAPI 3.1).
Public endpoints
| Endpoint | Returns |
|---|---|
GET https://qmscreener.com/api/v1/health | {"ok": true} whenever the service is up. |
GET https://qmscreener.com/api/v1/preview | The leading few passing tickers per screen, plus the total that passed. |
GET https://qmscreener.com/api/v1/sector-strength | 21 sector ETFs' trailing returns against SPY. |
Authenticated endpoints
| Endpoint | Returns |
|---|---|
GET https://qmscreener.com/api/v1/screens | Every screen's identifier, methodology, sort, and filter controls. |
GET https://qmscreener.com/<screen>_results.json | One screen's full result set. |
GET https://qmscreener.com/api/v1/history?ticker=NVDA | Ascending daily OHLCV bars for one symbol. |
GET https://qmscreener.com/api/v1/watchlist | The account's saved tickers. |
POST https://qmscreener.com/api/v1/watchlist | Add or remove one ticker. |
Authenticate with an OAuth 2.1 bearer token — see https://qmscreener.com/auth.md.
Versioning and deprecation
The current major version is v1. Pin it. Every endpoint above is canonical at /api/v1/...; the unversioned /api/... form is a permanent alias for the same handler, kept because the dashboard's own JavaScript has always used it. Both spellings answer with an API-Version header, so a caller can always tell what served it.
A breaking change means a new prefix — /api/v2/... — not a changed one. Adding a field, an endpoint, or an optional parameter is not breaking and ships without a version bump, so do not treat an unfamiliar response field as an error. When v1 is eventually retired, its responses will carry RFC 8594 Deprecation and Sunset headers for at least 180 days before the endpoint stops answering, and the sunset date will appear here and in https://qmscreener.com/openapi.json. There is no such date today.
Errors
Every failure is JSON, never an HTML page:
{
"error": "subscription_required",
"code": "subscription_required",
"message": "This endpoint needs an active subscription.",
"hint": "Start a 7-day free trial at https://qmscreener.com/subscribe.",
"docs": "https://qmscreener.com/docs#errors"
}
code is the stable identifier to branch on; message and hint are for humans and for an agent explaining itself.
Rate limits
Responses carry the RFC 9331 RateLimit header, and a 429 carries Retry-After in seconds. Self-throttle on those rather than on a fixed sleep.
MCP
https://qmscreener.com/mcp speaks MCP over Streamable HTTP. The server card at https://qmscreener.com/.well-known/mcp/server-card.json lists the tools. Public tools work without a credential; the full-result tools take the same bearer token as the REST API.
Agent skills
https://qmscreener.com/.well-known/agent-skills/index.json indexes task recipes: todays-momentum-setups, screen-methodologies, ticker-price-history, momentum-watchlist.
Data and limits
End-of-day US equities, refreshed once per trading day after the close. No intraday, no fundamentals, no news. Every filter comparison is strictly greater-than, and every row carries the values that decided it, so any result can be audited without re-running the screen. Not financial advice.