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

EndpointReturns
GET https://qmscreener.com/api/v1/health{"ok": true} whenever the service is up.
GET https://qmscreener.com/api/v1/previewThe leading few passing tickers per screen, plus the total that passed.
GET https://qmscreener.com/api/v1/sector-strength21 sector ETFs' trailing returns against SPY.

Authenticated endpoints

EndpointReturns
GET https://qmscreener.com/api/v1/screensEvery screen's identifier, methodology, sort, and filter controls.
GET https://qmscreener.com/<screen>_results.jsonOne screen's full result set.
GET https://qmscreener.com/api/v1/history?ticker=NVDAAscending daily OHLCV bars for one symbol.
GET https://qmscreener.com/api/v1/watchlistThe account's saved tickers.
POST https://qmscreener.com/api/v1/watchlistAdd 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.