---
url: https://ora.ai/docs/api/scores
title: "Scores & checks API - Docs"
description: "Read cached scores, embed badges, and browse the full check catalog with weights and applicability."
crawled_at: 2026-10-18T19:27:05Z
ask: https://ora-ai.ora.run/ask
docs: https://ora-ai.ora.run/.well-known/ora/docs
lang: en
---
# Scores & checks

Read cached scores, embed badges, and browse the full check catalog with weights and applicability.

## GET /api/score/{domain}

#### Get cached score for a domain

Returns the most recent cached scan result for the given domain. Read-only: never triggers a scan. On miss (404) or when the previous scan got stuck mid-flight (200 with `analysisStatus: "stuck"`), the response carries a structured `next_action` envelope pointing at `POST /api/scan` so agent callers have a machine-parseable next step. Successful responses are cached for 1 hour; stuck, 404, and ephemeral (disposable, `urlKind: "ephemeral"`) responses are uncached (`Cache-Control: no-store`) so a successful re-scan is observable immediately and a deleted disposable row is never served from cache. Rate limited to 10 requests per minute per IP - returns 429 if exceeded. A scan API key exempts the caller, since this is the poll target for keyed scanning.

##### PARAMETERS

domain · string · path · required

The domain to look up (e.g. stripe.com). URL-encoded full URLs are normalized to their hostname.

competitors · string · query

Pass 1 to include a `competitors` object in the response: the category top-5 leaders plus the neighbor window (2 above / self / 2 below) drawn from the leaderboard. Returned only for domains with a market category - unclassified domains (Community, or no leaderboard row) get `competitors: null`. Omitted by default so the plain response stays lean.

format · string · query

Pass `audit` to receive the versioned, allowlisted audit shape (AuditScanResult / AuditScoreResult) instead of the default body: every field is documented, carries a `contractVersion`, and internal fields are dropped. Omit it and the response is unchanged from previous releases. On GET /api/scan/stream, only the `scan_complete` event's `result` is projected - all other events are identical to the default stream.

include · string · query

Opt-in expansion list (comma-separated). `essentials` adds one response key, `essentials`: an alternate reading of the same scan carrying its own `score` (0-100 or null - required checks share 80 points, recommended 20, forward-looking signals upside-only), the required/recommended buckets, label copy, per-surface sub-scores, access signals, and a `checks` map keyed by check id. That map holds the essentials INTERPRETATION only (tier, bonus, fraction, occurrences, `essentialsGain`) - name, status, details, ora's recommendation, and `estScoreGain` for the same id stay in `layers[].checks[]`, so nothing serializes twice; join on the id. The pre-sorted `issues` list and `scoreEvidence` are arrays of ids resolving in that map. Omit the parameter and the response is byte-identical to previous releases. On GET /api/checks, `essentials` instead adds `essentialsTier`, `essentialsBonusOnly`, and `essentialsExcluded` to every catalog check (an excluded check never enters the essentials model; since 1.19.1 that is the two robots.txt policy checks). Experimental: the audit schemas declare `siteType` only as a loose object, so its inner fields may change without a version bump, and pinning the contract major does not freeze them. `siteType` adds one response key, `siteType`: the same scan scored against what the site is (`content`, `business`, `app`, or `store`). It carries `type`, `source` (`declared`, `self-declared`, `classified`, `default`, `blocked`, or `unavailable`), `confidence` (`high` or `low`), `basis`, `score` (0-100 or null), per-layer `layers` (`id`, `score`, `maxScore`), per-check `states` (`req`, `bonus`, `gated`, or `emerging`), and `gatedOut` (each excluded check id with the gate that excluded it). A site-type score uses a different rubric from the canonical `score` and can land above or below it: never compare the two, only another `siteType.score` of the same `type`. When no type resolves, the key is `{ type: null, source: "unavailable", confidence: "low", score: null, layers: [] }` with a `basis` saying why.

siteType · string · query

Read-time lens for `include=siteType`: scores the scan against this type instead of the resolved one, without rescanning or storing anything. An unrecognized value is ignored, not rejected.

##### RESPONSES

200 Cached scan result. With `?competitors=1`, also carries a `competitors` object (category leaders + neighbor window drawn from the leaderboard). When `analysisStatus` is `"stuck"`, the body also includes a `next_action` envelope. With `?format=audit` the body is `#/components/schemas/AuditScoreResult` and the recovery envelope is the camelCase `nextAction`. -> ScanResult

404 No cached score for this domain. Body includes `code: "DOMAIN_NOT_SCANNED"` and a `next_action` pointing at `POST /api/scan` (`nextAction`, camelCase, under `?format=audit`). -> NotScannedResponse

422 MCP authentication is required. No score or grade was produced. The failed attempt does not overwrite a previous measured scan. -> McpAuthRequiredResponse

429 Rate limit exceeded - max 10 requests per minute per IP. The response carries a Retry-After header with the seconds until the oldest request in the window ages out. -> ErrorResponse

500 Database unavailable

###### GET /api/badge/{domain}

#### Get SVG badge for a domain

Returns an SVG badge showing the domain's ora score and grade. Embed in READMEs or websites. Cached for 1 hour.

##### PARAMETERS

domain · string · path · required

The domain to get a badge for

##### RESPONSES

200 SVG badge image

404 No score found for this domain

###### GET /api/checks

#### Get the complete catalog of scanner checks

Returns every check the ora scanner can run - stable id, scored layer, max score, applicability, eligible scan kinds, tier, maturity, and fix guidance per check, plus the four scored layers with their weights. Check ids are stable: gate CI on an explicit id list, not on tiers (the required set can grow on a minor version). Ids are also what POST /api/scan/checks takes, and every check carries a `beta` boolean for building check pickers - a beta check runs but cannot affect any score. The document is static and byte-stable between check-set changes, so diffing it detects catalog updates. One optional parameter: `?include=essentials` adds `essentialsTier`, `essentialsBonusOnly`, and `essentialsExcluded` (the essentials-model classification; excluded checks are ignored by that model outright) to every check; without it the body is byte-identical to previous releases. Sends Access-Control-Allow-Origin: * and is CDN-cached for 1 hour. Rate limited to 60 requests per minute per IP - returns 429 with a Retry-After header if exceeded.

##### PARAMETERS

include · string · query

Opt-in expansion list (comma-separated). `essentials` adds one response key, `essentials`: an alternate reading of the same scan carrying its own `score` (0-100 or null - required checks share 80 points, recommended 20, forward-looking signals upside-only), the required/recommended buckets, label copy, per-surface sub-scores, access signals, and a `checks` map keyed by check id. That map holds the essentials INTERPRETATION only (tier, bonus, fraction, occurrences, `essentialsGain`) - name, status, details, ora's recommendation, and `estScoreGain` for the same id stay in `layers[].checks[]`, so nothing serializes twice; join on the id. The pre-sorted `issues` list and `scoreEvidence` are arrays of ids resolving in that map. Omit the parameter and the response is byte-identical to previous releases. On GET /api/checks, `essentials` instead adds `essentialsTier`, `essentialsBonusOnly`, and `essentialsExcluded` to every catalog check (an excluded check never enters the essentials model; since 1.19.1 that is the two robots.txt policy checks).

##### RESPONSES

200 The complete check catalog -> CheckCatalog

429 RATE_LIMIT_EXCEEDED - max 60 requests per minute per IP. -> ArdErrorResponse

# Footer

The standard for agent experience.

© 2026 [era labs](https://eralabs.ai/)

Product

- Scan a site

- [Journey](https://journey.ora.ai/)

- [WebMCP audit](https://webmcp.ora.ai/)

- [Directory](https://directory.ora.ai/)

Resources

- Methodology

- Research

- Blog

- API Docs

Company

- About

- Contact

- Privacy

- [@oradotai](https://x.com/oradotai)
