{"openapi":"3.1.0","info":{"title":"CheckAnySite API","version":"1","summary":"What is this website? Evidence about any site: AI builders, popularity, technology, trust signals.","description":"Ask what we found about any public website, each finding with its evidence and source. Free during launch: every account gets 300 credits a month, and more on request; each key may make 60 requests every 60 seconds, and every answer says how many are left (`X-RateLimit-*`).\n\nTwo APIs, one key: GET reads our stored results and never scans (the Lookup API); POST scans (the Scan API), and takes an `Idempotency-Key` so a retry never scans or charges twice.\n\nDocs: https://docs.checkanysite.com/. Errors: https://docs.checkanysite.com/errors.\n\nWithin v1 fields and values may be added, never removed or renamed: ignore what you don’t know.","termsOfService":"https://checkanysite.com/terms","contact":{"email":"hello@checkanysite.com"}},"servers":[{"url":"https://api.checkanysite.com/v1"}],"security":[{"bearerKey":[]},{"headerKey":[]}],"paths":{"/sites/{domain}":{"get":{"operationId":"getSite","summary":"Retrieve a site’s stored result","description":"Returns our latest stored result for a site, with the checks you ask for (every check if you leave out `checks`); the other fields are null. This is the Lookup API: it never starts a scan. Check `scannedAt`, use `maxAgeDays` to require a more recent result, and scan the site with POST /scans when you need a new one. Every response has an `ETag`: send it back in `If-None-Match`, and while the result is unchanged you get a free 304 with no body.\n\nCredits: Each check you ask for costs its stored price, up to 3 for every check, when a result is found. A no_result error or a 304 costs nothing.","parameters":[{"name":"domain","in":"path","required":true,"description":"The site’s domain, such as `example.com`.","schema":{"type":"string"},"example":"example.com"},{"name":"checks","in":"query","required":false,"description":"The checks to answer, separated by commas. Leave it out to ask for every check.","schema":{"type":"array","items":{"type":"string","enum":["ai","readiness","popularity","tech","dns","trust","summary","history"]}},"style":"form","explode":false,"example":["ai","dns"]},{"name":"maxAgeDays","in":"query","required":false,"description":"Return a result only if it is at most this many days old (1 to 3650); otherwise the API returns `no_result`.","schema":{"type":"integer"},"example":30},{"name":"If-None-Match","in":"header","required":false,"description":"The `ETag` of a response you already have. While the result is unchanged, the API returns a 304 with no body, for free.","schema":{"type":"string"},"example":"\"8c4e1f0a9b7d6e5c4b3a29180f7e6d5c\""}],"responses":{"200":{"description":"The stored result, with its `ETag`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteResult"}}}},"304":{"description":"The result hasn’t changed since the `ETag` you sent. No body, and no credits.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"},"ETag":{"$ref":"#/components/headers/ETag"}}},"400":{"description":"`invalid_domain`: The address isn’t a public domain name we can check, such as an IP address, a private name or a typo. `invalid_parameter`: A parameter is missing, unknown or has a value the API doesn’t accept. `param` names it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`missing_api_key`: The request has no API key. `invalid_api_key`: The API key doesn’t exist, or it was copied incorrectly. `revoked_api_key`: The API key was revoked and no longer works. `expired_api_key`: The API key has expired: it reached the expiry date set when it was created, or the end of its grace period after a rotation.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`no_result`: We have no stored result for this site with these checks, or none as recent as you asked for.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: This key has made more requests than its rate limit allows. `quota_exceeded`: The account has used all its credits for this month. `key_limit_reached`: This key has used the monthly credit limit set for it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`: Something went wrong on our side. This request cost nothing.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites/batch":{"post":{"operationId":"batchSites","summary":"Retrieve stored results for many sites","description":"Looks up as many as 50 sites at once, and returns each site’s stored result as GET /sites/{domain} does, in the order you sent them. A site sent twice gets one item. A site without a stored result, or an input that isn’t a domain, gets an `error` in its place, and the other sites are still returned. It never starts a scan.\n\nCredits: Each result found costs its checks’ stored price, up to 3 each; sites without a result cost nothing. The batch is charged as a whole: if your credits don’t cover every result found, the request is refused and nothing is charged.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique value for this request, such as a UUID. A retry with the same key within 24 hours returns the first response (`Idempotent-Replayed: true`), and never starts a second scan or charges twice. The same key with a different request returns `idempotency_key_reused`.","schema":{"type":"string"},"example":"7f3a2c1e-1b2c-4d5e-8f90-123456789abc"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteBatchRequest"},"example":{"domains":["stripe.com","lovable.dev"],"checks":["ai","tech"]}}}},"responses":{"200":{"description":"A result or an error for each site.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteBatch"}}}},"400":{"description":"`invalid_json`: The request body isn’t a valid JSON object. `invalid_parameter`: A parameter is missing, unknown or has a value the API doesn’t accept. `param` names it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`missing_api_key`: The request has no API key. `invalid_api_key`: The API key doesn’t exist, or it was copied incorrectly. `revoked_api_key`: The API key was revoked and no longer works. `expired_api_key`: The API key has expired: it reached the expiry date set when it was created, or the end of its grace period after a rotation.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`idempotency_key_in_use`: A request with this `Idempotency-Key` is still being processed.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"`request_too_large`: The request body is larger than the API accepts.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"`unsupported_media_type`: The request body has a content type other than JSON.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`idempotency_key_reused`: This `Idempotency-Key` was sent with a different request in the last 24 hours. Each key belongs to one request.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: This key has made more requests than its rate limit allows. `quota_exceeded`: The account has used all its credits for this month. `key_limit_reached`: This key has used the monthly credit limit set for it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`: Something went wrong on our side. This request cost nothing.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scans":{"post":{"operationId":"startScan","summary":"Scan a site","description":"Starts a scan of a site with the checks you ask for. If a result from the last day already has those checks, the API returns it with 200. If a scan of the site is already running, it returns that scan with 202; otherwise it starts a new scan and returns 202. Read the scan at `links.self` until `complete` is true: the first results arrive within seconds, and slower sources follow. A scan runs only what its checks need, so fewer checks are faster and cost less. A read-only key gets a recent result or a running scan, but never starts a new one (`read_only_key`). To check a fix, ask for the `readiness` check with `again: true`: once its last result is a few minutes old, the check runs again.\n\nCredits: Each check costs its scan price, up to 15 for every check, when a new scan starts; its stored price, up to 3, when a recent result or a running scan answers.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique value for this request, such as a UUID. A retry with the same key within 24 hours returns the first response (`Idempotent-Replayed: true`), and never starts a second scan or charges twice. The same key with a different request returns `idempotency_key_reused`.","schema":{"type":"string"},"example":"7f3a2c1e-1b2c-4d5e-8f90-123456789abc"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanRequest"},"example":{"domain":"example.com","checks":["ai","dns"]}}}},"responses":{"200":{"description":"A recent result had the checks; the scan is complete.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}}},"202":{"description":"A scan is running. Read it at `links.self`, which the `Location` header also gives.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}}},"400":{"description":"`invalid_json`: The request body isn’t a valid JSON object. `invalid_parameter`: A parameter is missing, unknown or has a value the API doesn’t accept. `param` names it. `invalid_domain`: The address isn’t a public domain name we can check, such as an IP address, a private name or a typo.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`missing_api_key`: The request has no API key. `invalid_api_key`: The API key doesn’t exist, or it was copied incorrectly. `revoked_api_key`: The API key was revoked and no longer works. `expired_api_key`: The API key has expired: it reached the expiry date set when it was created, or the end of its grace period after a rotation.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`read_only_key`: This key is read-only. It can read stored results but can’t start a scan.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`idempotency_key_in_use`: A request with this `Idempotency-Key` is still being processed.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"`request_too_large`: The request body is larger than the API accepts.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"`unsupported_media_type`: The request body has a content type other than JSON.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`idempotency_key_reused`: This `Idempotency-Key` was sent with a different request in the last 24 hours. Each key belongs to one request. `site_refused`: We don’t check this kind of site, such as adult websites.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: This key has made more requests than its rate limit allows. `quota_exceeded`: The account has used all its credits for this month. `key_limit_reached`: This key has used the monthly credit limit set for it. `scan_limit_reached`: The account has started its 25 new scans for today (UTC).","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`: Something went wrong on our side. This request cost nothing.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`capacity`: The API can’t start new scans right now. Stored results still work.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scans/batch":{"post":{"operationId":"batchScans","summary":"Scan many sites","description":"Scans as many as 10 sites at once. Each site is handled as POST /scans would handle it (a recent result, a running scan or a new scan), in the order you sent them. A site refused by your credits, the daily limits or our rules gets an `error` in its place, and the other sites go ahead. Read each scan at its `links.self`.\n\nCredits: Each site is charged as POST /scans charges it: its checks’ scan price for a new scan, or their stored price for a recent result or a running scan. Each scan’s credits are counted before the next site.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique value for this request, such as a UUID. A retry with the same key within 24 hours returns the first response (`Idempotent-Replayed: true`), and never starts a second scan or charges twice. The same key with a different request returns `idempotency_key_reused`.","schema":{"type":"string"},"example":"7f3a2c1e-1b2c-4d5e-8f90-123456789abc"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanBatchRequest"},"example":{"domains":["example.com","example.org"],"checks":["ai"]}}}},"responses":{"200":{"description":"Every scan is complete, from recent results.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanBatch"}}}},"202":{"description":"Some scans are running. Read each at its `links.self`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanBatch"}}}},"400":{"description":"`invalid_json`: The request body isn’t a valid JSON object. `invalid_parameter`: A parameter is missing, unknown or has a value the API doesn’t accept. `param` names it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`missing_api_key`: The request has no API key. `invalid_api_key`: The API key doesn’t exist, or it was copied incorrectly. `revoked_api_key`: The API key was revoked and no longer works. `expired_api_key`: The API key has expired: it reached the expiry date set when it was created, or the end of its grace period after a rotation.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`idempotency_key_in_use`: A request with this `Idempotency-Key` is still being processed.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"`request_too_large`: The request body is larger than the API accepts.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"`unsupported_media_type`: The request body has a content type other than JSON.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`idempotency_key_reused`: This `Idempotency-Key` was sent with a different request in the last 24 hours. Each key belongs to one request.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: This key has made more requests than its rate limit allows.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`: Something went wrong on our side. This request cost nothing.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scans/{id}":{"get":{"operationId":"getScan","summary":"Retrieve a scan","description":"Returns a scan’s status and, once it has completed, its result with the checks that were asked for. Read the scan at its `links.self`, which includes those checks. `complete` becomes true when the scan has failed, or has completed with every slow source in. Until then, the `Retry-After` header says when to read it again.\n\nCredits: Free.","parameters":[{"name":"id","in":"path","required":true,"description":"The scan’s `id`, returned by POST /scans.","schema":{"type":"string"},"example":"0b5a7a6e-1f7e-4d7c-9a4e-2f0d8b1c6a11"},{"name":"checks","in":"query","required":false,"description":"The checks the scan was asked for; `links.self` includes them.","schema":{"type":"array","items":{"type":"string","enum":["ai","readiness","popularity","tech","dns","trust","summary","history"]}},"style":"form","explode":false,"example":["ai","dns"]}],"responses":{"200":{"description":"The scan as it is now.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}}},"400":{"description":"`invalid_parameter`: A parameter is missing, unknown or has a value the API doesn’t accept. `param` names it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`missing_api_key`: The request has no API key. `invalid_api_key`: The API key doesn’t exist, or it was copied incorrectly. `revoked_api_key`: The API key was revoked and no longer works. `expired_api_key`: The API key has expired: it reached the expiry date set when it was created, or the end of its grace period after a rotation.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`scan_not_found`: There is no scan with this ID.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"`scan_expired`: This scan is older than the results we keep, so its result is no longer available. We keep each site’s latest result.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: This key has made more requests than its rate limit allows.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`: Something went wrong on our side. This request cost nothing.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/usage":{"get":{"operationId":"getUsage","summary":"Retrieve your usage","description":"Returns the credits your account has used and has left this month (UTC), the key’s own limit if it has one, and the price of each check.\n\nCredits: Free.","parameters":[],"responses":{"200":{"description":"This month’s credits.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"X-Credits-Cost":{"$ref":"#/components/headers/CreditsCost"},"X-Credits-Remaining":{"$ref":"#/components/headers/CreditsRemaining"},"X-Credits-Reset":{"$ref":"#/components/headers/CreditsReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"`missing_api_key`: The request has no API key. `invalid_api_key`: The API key doesn’t exist, or it was copied incorrectly. `revoked_api_key`: The API key was revoked and no longer works. `expired_api_key`: The API key has expired: it reached the expiry date set when it was created, or the end of its grace period after a rotation.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: This key has made more requests than its rate limit allows.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`internal_error`: Something went wrong on our side. This request cost nothing.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerKey":{"type":"http","scheme":"bearer","description":"Your API key (cas_live_…) from https://checkanysite.com/account/keys."},"headerKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"The same key, in its own header."}},"headers":{"RequestId":{"description":"This request’s id; give it when you write to us.","schema":{"type":"string"}},"CreditsCost":{"description":"Credits this call cost (only on calls that cost credits).","schema":{"type":"integer"}},"CreditsRemaining":{"description":"Credits the account has left this month after this call.","schema":{"type":"integer"}},"CreditsReset":{"description":"When the month’s credits reset (UTC).","schema":{"type":"string","format":"date-time"}},"RateLimitLimit":{"description":"Requests the key may make per window (60 seconds).","schema":{"type":"integer"}},"RateLimitRemaining":{"description":"Requests the key has left in the current window, this one counted.","schema":{"type":"integer"}},"RateLimitReset":{"description":"When the current window ends, in Unix seconds.","schema":{"type":"integer"}},"RetryAfter":{"description":"Seconds to wait before asking again.","schema":{"type":"integer"}},"ETag":{"description":"This answer’s tag: send it in `If-None-Match` to get a free 304 while it is unchanged.","schema":{"type":"string"}},"IdempotentReplayed":{"description":"`true` when this is the first answer to an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"schemas":{"Evidence":{"description":"Where a finding was seen, with the exact text: the reason it is reported.","type":"object","properties":{"where":{"type":"string","description":"Where we saw it: \"index.html, line 14\", \"response header\", \"address\"."},"snippet":{"type":"string","description":"The element, header or excerpt as it appears."},"match":{"type":"string","description":"The part of the snippet that matched."},"masked":{"type":"boolean","description":"True when email addresses and phone numbers in the snippet are masked."}},"required":["where","snippet","match","masked"]},"AiTraces":{"description":"Traces of the AI website builders and patterns we found. Evidence, never a verdict about who made the site.","type":"object","properties":{"level":{"type":"string","enum":["high","medium","none"],"description":"`high`: an AI builder’s own trace; `medium`: a combination of its weaker traces only; `none`: no traces found."},"builders":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Our id for the builder (\"lovable\")."},"name":{"type":"string","description":"The builder’s name (\"Lovable\")."},"kind":{"type":"string","enum":["ai","general"],"description":"`ai` for AI builders, `general` for other site builders."},"url":{"type":"string","format":"uri","description":"The builder’s own site."},"strength":{"type":"string","enum":["signature","combination"],"description":"`signature`: one trace of its own; `combination`: weaker traces that count only together."},"combination":{"description":"For a combination, what its traces mean together.","type":["string","null"]},"evidence":{"type":"array","items":{"$ref":"#/components/schemas/Evidence"},"description":"Where each trace was seen, with the exact line."}},"required":["id","name","kind","url","strength","combination","evidence"]},"description":"Each builder whose traces we found; empty when none."},"patterns":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Our id for the pattern."},"name":{"type":"string","description":"The pattern’s name."},"note":{"type":"string","description":"Why it is weak evidence on its own."},"evidence":{"type":"array","items":{"$ref":"#/components/schemas/Evidence"},"description":"Where it was seen."}},"required":["id","name","note","evidence"]},"description":"Design patterns common on AI-built pages; they never set the level on their own."}},"required":["level","builders","patterns"]},"AiReadiness":{"description":"How easily AI tools can find, read and use the site: a score out of 100 from checks, each with its evidence, and what to fix first. What the site lets AI crawlers do is listed apart and never scored: keeping AI out is the site’s choice.","type":"object","properties":{"answer":{"type":"string","description":"The answer in a sentence (\"Ready for AI: it scores 82 of 100.\")."},"note":{"type":"string","description":"What it lets AI crawlers do, in a sentence: the site’s choice, never scored."},"score":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Out of 100; null when too little could be checked to say."},"version":{"type":"string","description":"The readiness formula’s version (/changelog)."},"checkedAt":{"type":"string","format":"date-time","description":"When AI access was checked: the scan’s own date, or for a result made before we checked AI access, the newer check that answers in its place."},"level":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"The level’s id (\"readable\")."},"name":{"type":"string","description":"Its name (\"Readable\")."},"meaning":{"type":"string","description":"What reaching it means, in a sentence."}},"required":["id","name","meaning"]},{"type":"null"}],"description":"The highest level it reaches; null when it reaches none."},"levels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"`findable`, `readable`, `ai-friendly` or `agent-ready`; new levels may appear."},"name":{"type":"string","description":"The level’s name."},"reached":{"type":"boolean","description":"True when the site reaches it."}},"required":["id","name","reached"]},"description":"Every level, lowest first; one counts once its checks and every level before it are met."},"next":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"The level’s id."},"name":{"type":"string","description":"Its name."},"needs":{"type":"array","items":{"type":"string"},"description":"The keys of the checks it still needs, as `checks` lists them."}},"required":["id","name","needs"]},{"type":"null"}],"description":"The first level not reached and what it needs; null once every level is."},"comparison":{"description":"Where the score stands among the most visited sites we read, in a sentence; null without a score.","type":["string","null"]},"partial":{"type":"boolean","description":"True when some checks couldn’t be made or are still checking; the rest is scaled to 100."},"checks":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"A stable key: `text`, `listing`, `facts`, `structured`, `sitemap`, `robots`, `agents` (every file for AI agents at once: one found is enough), `llms`, `links` or `markdown`; new keys may appear."},"group":{"type":"string","enum":["find","read","agents"],"description":"`find` (can AI find its pages?), `read` (can AI read it?) or `agents` (can agents use it?)."},"label":{"type":"string","description":"The check’s name (\"Structured data\")."},"state":{"type":"string","enum":["found","partial","none","info","unknown"],"description":"`found`, `partial`, `none`, `info` or `unknown` (we couldn’t check it)."},"value":{"type":"string","description":"What we found, in words."},"evidence":{"type":"array","items":{"$ref":"#/components/schemas/Evidence"},"description":"Where it was seen, with the exact line."},"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The points it earns."},"max":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The most it can earn."},"met":{"type":"boolean","description":"True when it earns its full points."},"unchecked":{"type":"boolean","description":"True when we couldn’t check it, or it is still checking: it is left out of the score."},"optional":{"type":"boolean","description":"True for what few sites have yet; it is worth few points."},"fix":{"anyOf":[{"type":"object","properties":{"gain":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The points fixing it would add to the score."},"why":{"type":"string","description":"Why it matters."},"todo":{"type":"string","description":"What to do, in a line."},"prompt":{"type":"string","description":"A prompt for an AI coding assistant to fix it, with the site’s address and what we found."}},"required":["gain","why","todo","prompt"]},{"type":"null"}],"description":"What to do about it; null when it is met or couldn’t be checked."}},"required":["key","group","label","state","value","evidence","points","max","met","unchecked","optional","fix"]},"description":"Each check that counts, as the score reads it."},"fixPrompt":{"description":"The fixes that aren’t optional, most points first, as one prompt for an AI coding assistant that ends with where to check again; the optional ones once only they are left. Null when there is nothing to fix.","type":["string","null"]},"crawlers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The crawler, as its maker writes it (\"GPTBot\")."},"company":{"description":"The AI company it belongs to, for those we follow.","type":["string","null"]},"role":{"type":"string","enum":["training","answers"],"description":"What it fetches pages for: `training` models, or `answers` (AI assistants and AI search)."},"access":{"type":"string","enum":["out","some","in"],"description":"`out` of the whole site, kept from `some` paths, or let `in`."},"line":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The robots.txt line of the group that decides it; null when no group names it."}},"required":["name","company","role","access","line"]},"description":"Every AI crawler we know, as the site’s robots.txt treats it; never scored."}},"required":["answer","note","score","version","checkedAt","level","levels","next","comparison","partial","checks","fixPrompt","crawlers"]},"Popularity":{"description":"How popular the site is, from public ranked lists: a band and each list’s rank, never a visit count.","type":"object","properties":{"band":{"type":"string","description":"The best band any list gives the site (\"Top 100K\"), or \"Outside top 1M\"."},"bestRank":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The best rank behind the band; null when no list ranks the site."},"ranks":{"type":"array","items":{"type":"object","properties":{"list":{"type":"string","description":"The list’s name (\"Chrome UX Report\")."},"rank":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The rank, or null when the list doesn’t rank the site."},"isBucket":{"type":"boolean","description":"True when the rank is the edge of a bucket, not an exact position."},"rankedAs":{"description":"The parent name the list ranks, when not the site itself.","type":["string","null"]},"asOf":{"type":"string","description":"When the list was produced, as it states it."},"measures":{"type":"string","description":"What the list counts."},"url":{"type":"string","format":"uri","description":"Where the list is published."},"license":{"anyOf":[{"type":"object","properties":{"name":{"type":"string","description":"The license’s name (\"CC BY 3.0\")."},"url":{"type":"string","format":"uri","description":"The license’s text."}},"required":["name","url"]},{"type":"null"}],"description":"The list’s license, when its terms ask for attribution: keep it when you republish."}},"required":["list","rank","isBucket","rankedAs","asOf","measures","url","license"]},"description":"Each list we read, with the site’s rank on it."}},"required":["band","bestRank","ranks"]},"Technology":{"description":"The technologies the site shows, each with its evidence, and the network announcing its address.","type":"object","properties":{"technologies":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Our id for the technology."},"name":{"type":"string","description":"Its name (\"Next.js\")."},"category":{"type":"string","description":"Such as \"framework\", \"cms\", \"analytics\", \"hosting\"."},"evidence":{"type":"array","items":{"$ref":"#/components/schemas/Evidence"},"description":"Where it was seen, with the exact line."}},"required":["id","name","category","evidence"]},"description":"Each technology the site shows, with its evidence."},"network":{"anyOf":[{"type":"object","properties":{"asn":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The autonomous system number, such as 13335."},"name":{"type":"string","description":"The organisation announcing the address (\"Cloudflare, Inc.\")."},"prefix":{"description":"The routed block holding the address (\"104.16.16.0/20\").","type":["string","null"]},"source":{"type":"string","description":"Who answered."},"checkedAt":{"type":"string","format":"date-time","description":"When we asked."}},"required":["asn","name","prefix","source","checkedAt"]},{"type":"null"}],"description":"A network, never a place: many networks answer from everywhere."}},"required":["technologies","network"]},"DnsRecords":{"description":"The domain’s DNS records as the scan read them, over DNS over HTTPS, and the network announcing its address.","type":"object","properties":{"read":{"type":"boolean","description":"False when the lookup failed: then there are no records to give."},"records":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The name asked about: the domain, its www host, or a policy entry such as `_dmarc`."},"type":{"type":"string","enum":["A","AAAA","CNAME","MX","TXT","NS","CAA","SVCB","HTTPS"],"description":"The record type. SVCB and HTTPS come only from `_agents`, where a site names its AI agents."},"value":{"type":"string","description":"The record’s value, as the resolver gave it."}},"required":["name","type","value"]},"description":"Each record we read."},"dnssec":{"description":"Whether the resolver validated the answer with DNSSEC; null when that didn’t answer.","type":["boolean","null"]},"incomplete":{"type":"array","items":{"type":"string"},"description":"The questions (\"example.com TXT\") that didn’t answer whole: a record missing from one of them may still exist."},"source":{"description":"The resolver that answered.","type":["string","null"]},"checkedAt":{"anyOf":[{"type":"string","format":"date-time","description":"An instant in UTC, ISO 8601."},{"type":"null"}],"description":"When we asked."},"network":{"anyOf":[{"type":"object","properties":{"asn":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The autonomous system number, such as 13335."},"name":{"type":"string","description":"The organisation announcing the address (\"Cloudflare, Inc.\")."},"prefix":{"description":"The routed block holding the address (\"104.16.16.0/20\").","type":["string","null"]},"source":{"type":"string","description":"Who answered."},"checkedAt":{"type":"string","format":"date-time","description":"When we asked."}},"required":["asn","name","prefix","source","checkedAt"]},{"type":"null"}],"description":"The network announcing the site’s address, never a place."}},"required":["read","records","dnssec","incomplete","source","checkedAt","network"]},"TrustSignals":{"description":"Signals about how established and reachable the site is. Signals, never a verdict.","type":"object","properties":{"checks":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"A stable key such as `privacyPolicy` or `domainAge`; new keys may appear."},"label":{"type":"string","description":"The signal’s name (\"Privacy policy\")."},"state":{"type":"string","enum":["found","partial","none","info","unknown"],"description":"`found`, `partial`, `none` (not found; absence is never an accusation), `info` (a fact) or `unknown` (couldn’t check)."},"value":{"type":"string","description":"What we found, in words."},"kind":{"type":"string","enum":["measured","sourced","interpreted"],"description":"`measured` by us, `sourced` from a named source, or `interpreted` from what we read."},"source":{"type":"string","description":"Where it came from: our scan or a named source."},"evidence":{"type":"array","items":{"$ref":"#/components/schemas/Evidence"},"description":"Where it was seen, when the page or a record shows it."},"pending":{"type":"boolean","description":"True while a slow source is still being read."}},"required":["key","label","state","value","kind","source","evidence","pending"]},"description":"Each signal we looked for, found or not."}},"required":["checks"]},"Score":{"description":"A score out of 100 for how established the site looks, from its parts; it says nothing about intent.","type":"object","properties":{"total":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Out of 100; null when too little could be read to score fairly."},"band":{"type":"string","description":"The band the total falls in."},"withheld":{"type":"boolean","description":"True when too little could be read; `total` is null then."},"version":{"type":"string","description":"The score formula’s version (/changelog)."},"parts":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"The part, such as `transparency`, `trackRecord`, `popularity`, `security` or `consistency`."},"label":{"type":"string","description":"The part’s name."},"points":{"type":"number","description":"The points it earned."},"max":{"type":"number","description":"The most it could earn from what we could check."},"reasons":{"type":"array","items":{"type":"string"},"description":"Why points were given or withheld, one short phrase each."},"checked":{"type":"boolean","description":"False when none of its inputs could be checked."}},"required":["key","label","points","max","reasons","checked"]},"description":"The parts the total is made of, each with its points."},"missing":{"type":"array","items":{"type":"string"},"description":"Inputs we couldn’t check; the rest is scaled to 100."}},"required":["total","band","withheld","version","parts","missing"]},"SiteSummary":{"description":"What the site is: its own words, its kind, an automatic summary, who is behind it and its profiles.","type":"object","properties":{"title":{"description":"The page’s own title.","type":["string","null"]},"description":{"description":"The page’s own description.","type":["string","null"]},"siteName":{"description":"The name the site gives itself.","type":["string","null"]},"language":{"description":"The page’s language code (\"en\").","type":["string","null"]},"kind":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Our id for the kind (\"shop\")."},"label":{"type":"string","description":"Its name."},"confidence":{"type":"string","enum":["high","medium"],"description":"How sure the reading is."}},"required":["id","label","confidence"]},{"type":"null"}],"description":"The kind of site we read it as (a shop, a blog, an app…); null when unclear."},"summary":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Two or three sentences: what the site is and offers, as the page presents it."},"category":{"type":"string","description":"What kind of site the model read it as."},"offerings":{"type":"array","items":{"type":"string"},"description":"What it offers, in short phrases."},"audience":{"description":"Who it is for, when the page says.","type":["string","null"]},"model":{"type":"string","description":"The model that wrote it."},"writtenAt":{"type":"string","format":"date-time","description":"When it was written."}},"required":["text","category","offerings","audience","model","writtenAt"]},{"type":"null"}],"description":"An automatic summary whose quotes we checked against the page; null when there is none."},"identity":{"anyOf":[{"type":"object","properties":{"names":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The name as the source gives it."},"source":{"type":"string","description":"Where it comes from: `structured data`, `copyright line`, `Wikidata` or `certificate`."}},"required":["name","source"]},"description":"Each name a source gives for who is behind the site."},"agreeing":{"type":"array","items":{"type":"string"},"description":"The sources whose names agree, when at least two do."}},"required":["names","agreeing"]},{"type":"null"}],"description":"Who is behind the site, by independent sources."},"wikidata":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The item’s id (\"Q52\")."},"label":{"type":"string","description":"Its label."},"description":{"description":"Its short description.","type":["string","null"]},"types":{"type":"array","items":{"type":"string"},"description":"What it is an instance of, in English (\"search engine\")."},"inceptionYear":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The year it was founded or launched."},"url":{"type":"string","format":"uri","description":"Its page on Wikidata."}},"required":["id","label","description","types","inceptionYear","url"]},"description":"The Wikidata items that name the domain as their official website."},"social":{"type":"array","items":{"type":"object","properties":{"network":{"type":"string","description":"The network (\"github\", \"linkedin\")."},"handle":{"type":"string","description":"The account as its address names it (\"acme\", \"company/acme\")."},"url":{"type":"string","description":"The profile’s address."}},"required":["network","handle","url"]},"description":"The profiles the home page links."},"aiPolicy":{"anyOf":[{"type":"object","properties":{"trainingBlocked":{"type":"array","items":{"type":"string"},"description":"AI training crawlers robots.txt keeps out of the whole site."},"trainingPartly":{"type":"array","items":{"type":"string"},"description":"Training crawlers it gives rules for some paths only."},"assistantsBlocked":{"type":"array","items":{"type":"string"},"description":"AI assistants (fetching pages for a person) it keeps out of the whole site."},"everyoneBlocked":{"type":"boolean","description":"True when every crawler is kept out, AI ones included."},"contentSignal":{"description":"Its Content Signals line, as written (\"search=yes, ai-train=no\").","type":["string","null"]},"noai":{"type":"boolean","description":"True when a `noai` robots tag or header is set."}},"required":["trainingBlocked","trainingPartly","assistantsBlocked","everyoneBlocked","contentSignal","noai"]},{"type":"null"}],"description":"What the site says about AI crawlers using its content."},"llmsTxt":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","description":"Where it is."},"title":{"type":"string","description":"Its title."},"summary":{"description":"The summary it writes for AI assistants.","type":["string","null"]}},"required":["url","title","summary"]},{"type":"null"}],"description":"The site’s llms.txt (llmstxt.org), when it has one."},"iconUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Our copy of the site’s icon."}},"required":["title","description","siteName","language","kind","summary","identity","wikidata","social","aiPolicy","llmsTxt","iconUrl"]},"DomainHistory":{"description":"The domain’s history from public records: its registration, its first certificate and the web archive.","type":"object","properties":{"registration":{"anyOf":[{"type":"object","properties":{"registeredAt":{"anyOf":[{"type":"string","format":"date-time","description":"An instant in UTC, ISO 8601."},{"type":"null"}],"description":"When the domain was registered; null when the registry doesn’t say."},"lastChangedAt":{"anyOf":[{"type":"string","format":"date-time","description":"An instant in UTC, ISO 8601."},{"type":"null"}],"description":"When the record last changed."},"registrar":{"description":"The registrar, as the registry names it.","type":["string","null"]},"recordFor":{"description":"The registered name, when the record is for a parent name.","type":["string","null"]},"source":{"type":"string","description":"The registry server that answered (RDAP or WHOIS)."},"checkedAt":{"type":"string","format":"date-time","description":"When we asked."}},"required":["registeredAt","lastChangedAt","registrar","recordFor","source","checkedAt"]},{"type":"null"}],"description":"The domain registry’s record; null when it couldn’t be read."},"firstCertificate":{"anyOf":[{"type":"object","properties":{"firstSeen":{"anyOf":[{"type":"string","format":"date-time","description":"An instant in UTC, ISO 8601."},{"type":"null"}],"description":"The earliest certificate’s start date; null when there were too many to read."},"count":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"How many certificates the logs list, when read in full."},"source":{"type":"string","description":"The log search that answered."},"checkedAt":{"type":"string","format":"date-time","description":"When we asked."}},"required":["firstSeen","count","source","checkedAt"]},{"type":"null"}],"description":"Certificate Transparency: when a certificate for the domain was first issued."},"archive":{"anyOf":[{"type":"object","properties":{"firstCapture":{"anyOf":[{"type":"string","format":"date-time","description":"An instant in UTC, ISO 8601."},{"type":"null"}],"description":"The web archive’s first capture of the site."},"firstCaptureUrl":{"description":"A link to that capture, to look at.","type":["string","null"]},"captureYears":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"The years with at least one capture, oldest first."},"source":{"type":"string","description":"The archive that answered."},"checkedAt":{"type":"string","format":"date-time","description":"When we asked."}},"required":["firstCapture","firstCaptureUrl","captureYears","source","checkedAt"]},{"type":"null"}],"description":"The Internet Archive’s record of the site."}},"required":["registration","firstCertificate","archive"]},"SiteResult":{"description":"One scan’s result for a site, holding the checks asked. A field is null when its check wasn’t asked, or the scan didn’t run it.","type":"object","properties":{"domain":{"type":"string","description":"The site’s domain, as we read it (\"example.com\")."},"checks":{"type":"array","items":{"type":"string","enum":["ai","readiness","popularity","tech","dns","trust","summary","history"]},"description":"The checks this result holds: those asked that the scan answered."},"scanId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The scan that made this result."},"scannedAt":{"type":"string","format":"date-time","description":"When the scan read the site."},"complete":{"type":"boolean","description":"False while slow sources (`pending`) are still being read."},"pending":{"type":"array","items":{"type":"string"},"description":"The slow sources still being read, if any."},"limited":{"anyOf":[{"type":"object","properties":{"reason":{"type":"string","enum":["blocked","robots","private"],"description":"`blocked` (bot protection turned us away), `robots` (robots.txt keeps us out) or `private` (the site asks visitors to sign in)."},"message":{"type":"string","description":"What that means, in plain words."}},"required":["reason","message"]},{"type":"null"}],"description":"Set when the page itself couldn’t be read; the result then comes from outside records."},"finalUrl":{"type":"string","description":"The address the scan ended at, after redirects."},"resultUrl":{"type":"string","format":"uri","description":"The result on our site, with every section and its evidence."},"versions":{"type":"object","properties":{"signatures":{"type":"string","description":"The signature list’s version."},"score":{"type":"string","description":"The score formula’s version."}},"required":["signatures","score"],"description":"The signature list and score formula the result was made with (/changelog)."},"ai":{"anyOf":[{"$ref":"#/components/schemas/AiTraces"},{"type":"null"}],"description":"AI website builder traces (check `ai`)."},"readiness":{"anyOf":[{"$ref":"#/components/schemas/AiReadiness"},{"type":"null"}],"description":"How ready it is for AI tools, out of 100 (check `readiness`). A result made before we checked AI access takes it from a newer check when there is one (its `checkedAt` says when), and is null otherwise."},"popularity":{"anyOf":[{"$ref":"#/components/schemas/Popularity"},{"type":"null"}],"description":"Popularity from public ranked lists (check `popularity`)."},"tech":{"anyOf":[{"$ref":"#/components/schemas/Technology"},{"type":"null"}],"description":"The technology it runs on (check `tech`)."},"dns":{"anyOf":[{"$ref":"#/components/schemas/DnsRecords"},{"type":"null"}],"description":"Its DNS records (check `dns`)."},"trust":{"anyOf":[{"$ref":"#/components/schemas/TrustSignals"},{"type":"null"}],"description":"Trust signals (check `trust`)."},"score":{"anyOf":[{"$ref":"#/components/schemas/Score"},{"type":"null"}],"description":"How established it looks, out of 100 (check `trust`, with the signals)."},"summary":{"anyOf":[{"$ref":"#/components/schemas/SiteSummary"},{"type":"null"}],"description":"What it is and who is behind it (check `summary`)."},"history":{"anyOf":[{"$ref":"#/components/schemas/DomainHistory"},{"type":"null"}],"description":"Its domain’s history (check `history`)."},"notes":{"type":"array","items":{"type":"string"},"description":"Limits of this scan, in plain words."}},"required":["domain","checks","scanId","scannedAt","complete","pending","limited","finalUrl","resultUrl","versions","ai","readiness","popularity","tech","dns","trust","score","summary","history","notes"]},"Scan":{"description":"A scan: queued, running, completed or failed. Poll it until `complete` is true.","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The scan’s id."},"domain":{"type":"string","description":"The domain scanned."},"checks":{"type":"array","items":{"type":"string","enum":["ai","readiness","popularity","tech","dns","trust","summary","history"]},"description":"The checks its result holds: those asked that the scan answers."},"status":{"type":"string","enum":["queued","running","completed","failed"],"description":"Where it is: `queued`, `running`, `completed` or `failed`."},"createdAt":{"type":"string","format":"date-time","description":"When it was asked for."},"finishedAt":{"anyOf":[{"type":"string","format":"date-time","description":"An instant in UTC, ISO 8601."},{"type":"null"}],"description":"When it finished; null while it runs."},"complete":{"type":"boolean","description":"True once the scan failed, or completed with every slow source in."},"failure":{"anyOf":[{"type":"object","properties":{"code":{"type":"string","description":"Why, as a stable code."},"message":{"type":"string","description":"Why, in plain words."}},"required":["code","message"]},{"type":"null"}],"description":"Why the scan couldn’t finish; null unless `status` is `failed`."},"result":{"anyOf":[{"$ref":"#/components/schemas/SiteResult"},{"type":"null"}],"description":"The result once `status` is `completed`."},"links":{"type":"object","properties":{"self":{"type":"string","format":"uri","description":"This scan, to poll: the address names the checks asked, so polling answers the same."},"result":{"type":"string","format":"uri","description":"Its result page on our site."}},"required":["self","result"],"description":"Where to poll the scan, and where its result is shown."}},"required":["id","domain","checks","status","createdAt","finishedAt","complete","failure","result","links"]},"Usage":{"description":"The calling key’s account: its credits this month, and the key’s own.","type":"object","properties":{"period":{"type":"object","properties":{"start":{"type":"string","format":"date-time","description":"When the month began."},"end":{"type":"string","format":"date-time","description":"When it ends and the credits start again."}},"required":["start","end"],"description":"The calendar month (UTC) the credits count in."},"allowance":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The account’s credits this month."},"used":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The credits the account used this month, all keys together."},"remaining":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The account’s credits left this month."},"key":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The key’s id."},"name":{"type":"string","description":"The name you gave it."},"monthlyCreditLimit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Its own monthly limit; null when it has none."},"used":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The credits it used this month."},"remaining":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"What its own limit leaves; null without one."}},"required":["id","name","monthlyCreditLimit","used","remaining"],"description":"The key that made this call."},"prices":{"type":"object","properties":{"checks":{"type":"object","propertyNames":{"type":"string","enum":["ai","readiness","popularity","tech","dns","trust","summary","history"]},"additionalProperties":{"type":"object","properties":{"stored":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"From a stored result, or a scan already running."},"scan":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"With a new scan."}},"required":["stored","scan"]},"required":["ai","readiness","popularity","tech","dns","trust","summary","history"],"description":"What each check costs."},"allChecks":{"type":"object","properties":{"stored":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Every check from a stored result."},"scan":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Every check with a new scan."}},"required":["stored","scan"],"description":"The most a call costs: every check at once, asked when `checks` is left out."}},"required":["checks","allChecks"],"description":"What a call costs, in credits: each check it asks, never more than every check at once."},"rateLimit":{"type":"object","properties":{"requests":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Calls a key may make in a period."},"periodSeconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The period, in seconds."}},"required":["requests","periodSeconds"],"description":"How fast a key may call."}},"required":["period","allowance","used","remaining","key","prices","rateLimit"]},"Error":{"description":"Every error has this shape; `code` is stable and documented.","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_api_key","invalid_api_key","revoked_api_key","expired_api_key","invalid_json","invalid_parameter","invalid_domain","unsupported_media_type","request_too_large","not_found","method_not_allowed","no_result","scan_not_found","scan_expired","read_only_key","browser_request","site_refused","idempotency_key_reused","idempotency_key_in_use","rate_limited","quota_exceeded","key_limit_reached","scan_limit_reached","capacity","internal_error"],"description":"The error’s stable code; each is on the errors page."},"message":{"type":"string","description":"What happened and what to do, in a sentence."},"param":{"description":"The parameter at fault, for `invalid_parameter`.","type":"string"},"docs":{"type":"string","format":"uri","description":"The code’s entry on the errors page."},"requestId":{"type":"string","description":"The request’s id, also in `x-request-id`; quote it when you write to us."}},"required":["code","message","docs","requestId"]}},"required":["error"]},"ScanRequest":{"description":"What to scan, and which checks to answer.","type":"object","properties":{"domain":{"type":"string","minLength":1,"maxLength":300,"description":"A domain, or a URL whose host is used.","example":"example.com"},"checks":{"description":"The checks to answer; left out, every check. A scan runs only what they need, and the call costs what they cost.","example":["ai","dns"],"minItems":1,"type":"array","items":{"type":"string","enum":["ai","readiness","popularity","tech","dns","trust","summary","history"]}},"again":{"default":false,"description":"With the `readiness` check: ask it again once its answer is 3 minutes old, to check a fix. Without it, and for other checks, a result from the last 24 hours answers.","type":"boolean"}},"required":["domain"]},"BatchError":{"description":"A domain of a batch that got no answer, in its place in the list; the others are answered.","type":"object","properties":{"input":{"type":"string","description":"The domain as it was sent."},"domain":{"description":"The domain as we read it; null when it isn’t one (`invalid_domain`).","type":["string","null"]},"error":{"type":"object","properties":{"code":{"type":"string","description":"Why, as a stable code: `no_result`, `invalid_domain`, …"},"message":{"type":"string","description":"Why, in plain words."}},"required":["code","message"],"description":"Why this domain got no answer."}},"required":["input","domain","error"]},"SiteBatchRequest":{"description":"Domains to read from our stored results at once, and which checks to answer.","type":"object","properties":{"domains":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":300},"description":"1 to 50 domains, or URLs whose host is used. A domain sent twice is answered once, in its first place.","example":["stripe.com","lovable.dev"]},"checks":{"description":"The checks to answer for each domain; left out, every check.","example":["ai","tech"],"minItems":1,"type":"array","items":{"type":"string","enum":["ai","readiness","popularity","tech","dns","trust","summary","history"]}},"maxAgeDays":{"description":"Answer only with results at most this many days old; older ones are `no_result`.","type":"integer","minimum":1,"maximum":3650}},"required":["domains"]},"SiteBatch":{"description":"The stored result of each domain asked, or why there is none, in the order they were sent.","type":"object","properties":{"data":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"input":{"type":"string","description":"The domain as it was sent."},"domain":{"type":"string","description":"The domain as we read it."},"result":{"$ref":"#/components/schemas/SiteResult"}},"required":["input","domain","result"]},{"$ref":"#/components/schemas/BatchError"}]},"description":"One item per domain: its `result`, or an `error`."}},"required":["data"]},"ScanBatchRequest":{"description":"Domains to scan at once, and which checks to answer.","type":"object","properties":{"domains":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":300},"description":"1 to 10 domains, or URLs whose host is used. A domain sent twice is answered once, in its first place.","example":["example.com","example.org"]},"checks":{"description":"The checks to answer for each domain; left out, every check.","example":["ai","tech"],"minItems":1,"type":"array","items":{"type":"string","enum":["ai","readiness","popularity","tech","dns","trust","summary","history"]}},"again":{"default":false,"description":"With the `readiness` check: ask it again, as on POST /scans.","type":"boolean"}},"required":["domains"]},"ScanBatch":{"description":"A scan for each domain asked, or why there is none, in the order they were sent.","type":"object","properties":{"data":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/Scan"},{"$ref":"#/components/schemas/BatchError"}]},"description":"One item per domain: its scan (poll each `links.self`), or an `error`."}},"required":["data"]}}}}