AEO Check API

One-line verdict: The exact engine behind our free AEO Readiness Check, offered as a JSON API — send a domain, get back the full audit: a 0–100 readiness score, the four section scores, all 24 checks with the evidence found for each, and a fix list ranked by points recoverable. No lighter “API version” of the audit — same crawl, same rubric, same honesty label.

Who it’s for

Agencies, freelancers, and web builders who check sites in batches — a client roster, a prospect list, a portfolio after a redesign. If you only need one site, the free checker runs this same audit in your browser, with the full visual report. The API is for when you’re doing it fifty times a month and want the result inside your own spreadsheet, CRM, or reporting pipeline.

The endpoint

Base URL: https://altapointdevelopment.com/wp-json/aeocheck/v1

Method & path What it does
POST /check or GET /check?url=… Runs the audit for one domain (or returns its 24-hour cached result) and returns the full result as JSON.
GET /usage Returns your key’s quota, calls used this month, and totals — so your pipeline can check itself before we have to tell it no.

Authentication. Every request carries your key in the X-API-Key header (Authorization: Bearer … works too). Keys look like aeo_live_… and are stored on our side only as hashes — if you lose one, we revoke it and mint a new one; nobody, including us, can recover the original. A missing, wrong, or revoked key returns 401.

Machine-readable contract: the OpenAPI 3.1 spec (JSON) describes both endpoints, the full result schema, and every error code — point your client generator or your AI tooling at it directly.

Example request

curl -X POST "https://altapointdevelopment.com/wp-json/aeocheck/v1/check" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "benjaminfranklinplumbing.com"}'

The url field takes a bare domain or a full homepage URL — paths are ignored, because the homepage is the crawl’s front door, exactly like the web checker.

Example response

A real response from this API, produced on November 1, 2026 for a national plumbing franchise’s site — trimmed here to 3 of the 24 checks and 2 of the fixes; everything shown is verbatim. One note: the usage block always reflects your key — this call ran on a small test key, which is why its monthly quota shows 3. An early-access key shows 100.

{
  "ok": true,
  "domain": "www.benjaminfranklinplumbing.com",
  "url_checked": "https://www.benjaminfranklinplumbing.com/",
  "final_url": "https://www.benjaminfranklinplumbing.com/",
  "score": 84,
  "max_score": 100,
  "rubric": "AEO Score v2",
  "label": "Readiness score from on-site signals \u2014 not a measurement of live ChatGPT / Perplexity / Google AI answers.",
  "cached": false,
  "checked_at": "Nov 1, 2026, 11:04 PM",
  "served_at": "2026-11-01T23:04:39+00:00",
  "report_url": "https://altapointdevelopment.com/aeo-check/r/1ab4cd7f29552e63d32d/",
  "scope": {
    "pages_checked": 10,
    "pages": [
      {
        "label": "Homepage",
        "url": "https://www.benjaminfranklinplumbing.com/"
      },
      {
        "label": "FAQ",
        "url": "https://www.benjaminfranklinplumbing.com/faq/"
      },
      {
        "label": "FAQ",
        "url": "https://www.benjaminfranklinplumbing.com/andover/about-us/faq/"
      }
    ],
    "crawl": {
      "candidates": 4173,
      "attempted": 10,
      "missed": [],
      "files": {
        "robots_status": 200,
        "sitemap_at": "/sitemap.xml",
        "sitemap_pages": 5625,
        "llms_status": 200
      }
    }
  },
  "sections": {
    "schema": {
      "label": "Machine identity & schema",
      "points": 21,
      "max": 28
    },
    "machine": {
      "label": "Crawler & machine files",
      "points": 20,
      "max": 20
    },
    "content": {
      "label": "Extractable content",
      "points": 30,
      "max": 30
    },
    "local": {
      "label": "Local proof & contact",
      "points": 13,
      "max": 22
    }
  },
  "checks": [
    {
      "section": "schema",
      "id": "jsonld_present",
      "label": "JSON-LD structured data present",
      "max": 4,
      "points": 4,
      "status": "pass",
      "evidence": "26 JSON-LD blocks found across the checked pages; readable structured data parsed on 10 of the 10 pages.",
      "fix": ""
    },
    {
      "section": "schema",
      "id": "entity_type",
      "label": "Business type named specifically",
      "max": 6,
      "points": 6,
      "status": "pass",
      "evidence": "Schema names the business as Plumber \u2014 a specific business type, not a generic entity.",
      "fix": ""
    },
    {
      "section": "schema",
      "id": "field_completeness",
      "label": "Schema field completeness",
      "max": 8,
      "points": 7,
      "status": "partial",
      "evidence": "The business schema carries 7 of 8 key fields (name, phone, street address, URL, profile links (sameAs), opening hours, geo coordinates) \u2014 missing: service area.",
      "fix": "Add the missing fields to the business schema: service area."
    }
    // … 21 more checks (24 total)
  ],
  "fixes": [
    {
      "check": "Service schema",
      "points": 3,
      "found": "No Service schema found \u2014 services are described only in page text.",
      "action": "Add Service schema for each core service, tied to the business and its service area.",
      "difficulty": "Quick fix"
    },
    {
      "check": "Review / rating schema",
      "points": 3,
      "found": "No AggregateRating or Review schema found on any checked page.",
      "action": "Once real reviews are published on the site, mark them up with Review / AggregateRating schema that matches them exactly.",
      "difficulty": "Quick fix"
    }
    // … remaining fixes, ranked by points recoverable
  ],
  "usage": {
    "requests_this_month": 1,
    "monthly_quota": 3,
    "remaining": 2
  }
}

What the fields mean

Field Meaning
score / max_score The readiness score out of 100, on the AEO Score v2 rubric — the same rubric the web checker publishes.
sections The four section scores: Machine identity & schema (28), Crawler & machine files (20), Extractable content (30), Local proof & contact (22).
checks All 24 checks, each with points, max, status (pass / partial / fail), the evidence the crawler actually found, and the fix when points were left on the table.
fixes Every check that lost points, re-ranked by points recoverable, with the found evidence, the action, and a rough difficulty (Quick fix / Half-day / Build).
scope How many pages were crawled (up to 10), which ones, and the crawl facts — including any pages that could not be read. An unreadable page is reported, never silently scored as a pass.
report_url The shareable visual report for this check — the same report page the web checker produces.
cached true when the result came from the 24-hour per-domain cache instead of a fresh crawl.
usage Your key’s calls this month, monthly quota, and remaining calls, after this request.

Errors

Errors return {"ok": false, "error": {"code": …, "message": …}} with one of these HTTP statuses:

Status Code What it means
400 aeocheck_invalid_url The url value doesn’t look like a website address.
401 aeocheck_missing_key · aeocheck_invalid_key · aeocheck_key_inactive No key sent, the key isn’t recognized, or the key has been revoked.
422 aeocheck_site_blocked The site blocks automated checks (bot protection). No score is issued — a partial crawl would be an unfair verdict, so we don’t fake one.
429 aeocheck_rate_limited Your key passed its per-minute burst limit (10 requests/minute by default). Back off for a minute; a Retry-After header is included.
429 aeocheck_quota_exceeded Your key used its monthly quota. Quotas reset on the 1st of the month.
502 aeocheck_site_unreachable The site itself could not be reached at all.

Rate limits, quotas, and the cache

Two limits, both per key: a burst limit (10 requests per minute by default — a fresh crawl takes 10–25 seconds anyway, so this only bites scripts firing cached lookups in a loop) and a monthly quota. During early access, a free key carries 100 requests a month. If you need more, request a key and tell us your volume — higher quotas are set per key.

How counting works, stated plainly: a request counts once toward your monthly quota when it is served — including results served from the cache and sites that turn out to be blocked or unreachable (the crawl still ran). Requests rejected for a bad key or for exceeding a limit never count.

The 24-hour cache is the same one the web checker uses: the first check of a domain crawls up to 10 pages; any check of that domain in the next 24 hours returns the stored result in about a second, with "cached": true in the response and cached also shown in the X-AEO-Cache header (hit / miss). Scores never go silently stale — the flag is always there, and checked_at tells you when the crawl actually happened.

Honest limits

This is a readiness score from on-site signals — schema, extractable Q&A, contact details, service pages, reviews, and machine files. It is not a measurement of live ChatGPT, Perplexity, or Google AI answers, and it never claims to be: the same label travels inside every API response (label). It measures whether a site publishes what answer engines rely on when they choose what to cite. Sites behind bot protection get a 422 and no score, because an incomplete crawl scored as fact would be worse than no number at all.

Request an API key

Keys are minted by hand during early access — free tier, 100 requests a month, no card and no self-serve signup form. Tell us your agency or studio name and roughly how many sites you check a month, and we’ll issue a key sized to it.

Request an API key

One site, one time? Skip the key — the free AEO Checker runs the identical audit in your browser.