Endpoints
Production base URL: https://api.machineread.ai
POST /v1/audit
POST /v1/audit/summary
Both endpoints accept the same AuditRequest and run the same bounded Essentials pipeline. /v1/audit returns the full AuditResult. /v1/audit/summary returns a compact deterministic AuditSummary for agents. The deprecated POST /audit compatibility alias is available at runtime but is absent from OpenAPI.
All audit routes share one per-client-IP REST rate-limit bucket. They accept anonymous application/json requests. The transport rejects request bodies larger than 65,536 bytes before JSON parsing.
Request body
{
"url": "https://example.com/",
"preset": "blog"
}
| Field | Type | Required | Meaning |
|---|---|---|---|
url | string | yes | Public HTTP(S) URL. A missing scheme defaults to HTTPS. Private, loopback, link-local, and reserved targets are rejected. |
preset | string or null | no | Recommended scope selector: blog, corporate, services, ecommerce, news, saas, or custom. |
custom_overrides | object or null | no | Boolean family overrides applied on top of a selected preset. Rejected when preset is null. |
include_protocols | boolean | no, deprecated | Legacy protocol/API scope toggle. Ignored when a preset is selected. |
include_account_auth | boolean | no, deprecated | Legacy account/auth scope toggle. Ignored when a preset is selected. |
include_ecommerce | boolean | no, deprecated | Legacy commerce scope toggle. Ignored when a preset is selected. |
Supported custom_overrides keys are protocols, account_auth, ecommerce, feed_discovery, article_schema, localbusiness_schema, news_article_schema, claimreview_schema, product_offer_schema, commerce_fields, api_catalog, mcp, a2a, agent_skills, webmcp, oauth_oidc, ard_catalog, and auth_md. Unknown, incoherent, or preset-inapplicable combinations return 422.
Presets
blog: feed discovery and Article/BlogPosting schema.corporate: universal and contextual core only.services: LocalBusiness schema.news: feeds, Article/BlogPosting, NewsArticle, and ClaimReview schema.saas: API catalog, MCP, A2A, Agent Skills, WebMCP, ARD, OAuth/OIDC, andauth.md.ecommerce: the SaaS protocol/auth families plus feeds, Product/Offer schema, and commerce fields.custom: starts from the blog family defaults and accepts any supported override.
Every preset keeps the same 13 included rows and 56-point checked denominator. Presets change applicable sub-signals, strict agent-readiness probes, scope metadata, and benchmark cohort selection.
Full response: AuditResult
POST /v1/audit returns these top-level fields:
| Field | Meaning |
|---|---|
api_version | Public contract version, currently 1.0. |
url | Normalized audited URL. |
scope | Resolved AuditScope. |
overall_score | Points earned on the 100-point full rubric. Locked rows remain zero until verified. |
pillar_scores | Raw earned points for off_site, scrapability, and seo. |
pillar_max | Full-rubric caps: 30, 40, and 30. |
agent_readiness | Separate strict agent-native percentage plus earned/max probes and benchmark. |
benchmark | Singular Essentials peer comparison. score and median_score are percentages; checked_score and checked_max are raw points. |
checks | 13 included rows and 9 locked rows in the same checks array. |
Do not read benchmark.score as raw points. For example, 42 earned of 56 checked points produces benchmark.score: 75. overall_score: 42 remains 42 raw points on the full 100-point rubric.
AuditScope keys
The full response scope contains:
include_protocols,include_account_auth, andinclude_ecommerce: resolved coarse dimensions.label: human-readable resolved scope.included_optional_surfacesandexcluded_optional_surfaces: coarse display buckets.preset_applied: selected preset, or null for the legacy path.overrides_applied: the accepted custom override map.included_familiesandexcluded_families: exact resolved family keys.machine_surfaces_scope:common-contextualorfull.
CheckResult fields
| Field | Meaning |
|---|---|
pillar | off_site, scrapability, or seo. |
check_name | Stable machine identifier. |
label | Human-readable row title. |
state | pass, partial, fail, warn, or locked. |
evidence_level | verified, inferred, unknown, or not_applicable. |
available_in | Essentials, Starter, or Pro. |
score | Raw points earned for this row. |
max_score | Raw points available for this row. |
finding | Deterministic explanation of observed evidence. |
fix | Deterministic remediation hint. |
effort | low, medium, or high. |
A locked row has state: "locked", score: 0, evidence_level: "not_applicable", and a Starter or Pro available_in value. A warn row is inconclusive, not negative verified evidence.
{
"overall_score": 42,
"benchmark": {
"score": 75,
"checked_score": 42,
"checked_max": 56,
"median_score": 75,
"percentile": 100
},
"checks": [
{
"pillar": "scrapability",
"check_name": "robots_txt",
"label": "AI Bot Policy Signals",
"state": "partial",
"evidence_level": "verified",
"available_in": "Essentials",
"score": 4,
"max_score": 6,
"finding": "robots.txt mentions GPTBot but does not mention ClaudeBot.",
"fix": "Add an explicit ClaudeBot directive (Allow or Disallow) to robots.txt.",
"effort": "low"
}
]
}
Compact response: AuditSummary
POST /v1/audit/summary preserves score denominators, compact scope, benchmark percentiles and medians, row counts, up to five attention rows, and fixed limitation codes. It omits full finding/fix prose, peer entries, raw fetch context, and generated prose.
The top-level keys are api_version, summary_version, url, scope, scores, benchmarks, checks, attention, and limitations. Note that full AuditResult uses singular benchmark; the compact projection groups two comparisons under plural benchmarks.
{
"api_version": "1.0",
"summary_version": "1.0",
"url": "https://example.com/",
"scope": {
"preset": "blog",
"protocols": false,
"account_auth": false,
"ecommerce": false,
"overrides": {}
},
"scores": {
"overall": { "earned": 42, "max": 100 },
"pillars": {
"off_site": { "earned": 10, "max": 30 },
"scrapability": { "earned": 20, "max": 40 },
"seo": { "earned": 12, "max": 30 }
},
"essentials": { "percent": 75, "earned": 42, "max": 56 },
"agent_readiness": { "percent": 88, "earned": 7, "max": 8 }
},
"benchmarks": {
"essentials": { "percentile": 100, "median_percent": 75, "peer_count": 1, "snapshot": "2026-08-26" },
"agent_readiness": { "percentile": 100, "median_percent": 88, "peer_count": 1, "snapshot": "2026-08-26" }
},
"checks": {
"included": 13,
"locked": 9,
"pass": 2,
"partial": 11,
"fail": 0,
"warn": 0,
"attention_total": 5
},
"attention": [],
"limitations": ["relative_scores", "no_live_ranking", "no_provider_ip_auth", "no_paid_crawlers"]
}
Progressive HTML form adapter
The public page also supports a non-JavaScript browser submission. Its standard
form posts application/x-www-form-urlencoded data to same-origin /audit on
the www host. A bounded Pages Function validates the form and issues a 307 to
https://api.machineread.ai/v1/audit/form, preserving the browser POST and the
real client-IP rate-limit identity.
/v1/audit/form accepts only the browser form encoding and returns escaped,
semantic HTML with Cache-Control: no-store and restrictive security headers.
It is a progressive-enhancement adapter, not a JSON API. It is intentionally
include_in_schema=False and must not appear in the JSON OpenAPI contract.
JSON agents and SDKs must continue to use /v1/audit or
/v1/audit/summary.
Error responses
Both public audit endpoints document the same error set in OpenAPI.
| Status | Model | Meaning |
|---|---|---|
400 | ErrorMessage | The URL resolves to a blocked private, loopback, link-local, or reserved target. |
413 | ErrorMessage | The request body exceeds 65,536 bytes. |
422 | ValidationErrorMessage | URL syntax, body, preset, or override validation failed. |
429 | RateLimitErrorMessage | The shared REST audit limit was exceeded. The body includes retry_after. |
500 | ErrorMessage | Audit context setup failed. No partial result is returned. |
503 | ErrorMessage | The bounded outbound-request budget was exhausted, process capacity was unavailable, or the end-to-end audit wall deadline elapsed. No partial result is returned or cached. |
Rate limits and retry guidance
The default REST audit limit is 3 requests per minute per client IP. Successful 200 and rejected 429 responses include:
X-RateLimit-Limit: configured request limit.X-RateLimit-Remaining: requests left in the current window.X-RateLimit-Reset: absolute Unix epoch reset time.Retry-After: whole seconds until reset.
A 429 body also includes integer retry_after, which mirrors the delta-seconds Retry-After header. Wait at least that long before retrying. Do not treat X-RateLimit-Reset as a duration.
OpenAPI
The current schema is at https://api.machineread.ai/openapi.json. It is the source for exact models, enums, response statuses, examples, and headers. Interactive Swagger UI is at https://api.machineread.ai/docs.