public_api · v1
REST API for scan / sites / keywords / citations
All endpoints accept Authorization: Bearer <api-key> or X-API-Key: <api-key>. Generate keys in Dashboard → Settings → API Keys.
Authentication
# Either header works. Authorization: Bearer aeopro_xxxxxxxxxxxxxxxxxxxxxxxxxxxx X-API-Key: aeopro_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Rate limits (per API key)
| Plan | Limit |
|---|---|
| Free | 10 / hour |
| Starter | 100 / hour |
| Pro | 1,000 / hour |
| Agency | Unlimited (fair-use throttle) |
Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
Standard JSON envelope
// success
{ "ok": true, "data": { ... }, "meta": { ... } }
// paginated list
{ "ok": true, "data": [...], "meta": { "page", "limit", "total", "hasMore" } }
// error
{ "ok": false, "error": { "code": "rate_limited", "message": "...", "hint": "..." } }Live try-it
Run the anonymous quick-scan endpoint inline. Same engine and rate limit as /tools/free-aeo-checker (10 scans/hour per IP, no key required).
try it · live
anonymous · 10 scans/hourEndpoints
- POST
/api/v1/scanRun a SEO/AEO/GEO scan. mode=quick returns in ~10s; mode=full returns in ~25s.
body fields
- url (string) · required — Absolute URL to scan
- mode ("quick" | "full") — default: full
curl
curl -X POST https://www.aeo-pro.app/api/v1/scan \ -H "Authorization: Bearer aeopro_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{"url":"https://example.com","mode":"quick"}'response sample
{ "success": true, "data": { "url": "https://example.com", "scores": { "seo": 78, "aeo": 65, "geo": 71, "overall": 71 }, "checks": [ /* ... */ ], "scannedAt": "2026-05-15T01:23:45Z" } } - POST
/api/v1/aeo-2/evaluateScore caller-provided citation, evidence, and revenue observations with the deterministic AEO 2.0 evaluator. Does not independently verify provenance.
body fields
- citations (array) — Optional citation observations; max 100
- evidence (array) — Optional public evidence URLs and source metadata; max 100
- revenue (object) — Optional commercial inputs; ratios must be decimals from 0 to 1
curl
curl -X POST https://www.aeo-pro.app/api/v1/aeo-2/evaluate \ -H "Authorization: Bearer aeopro_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "citations": [{ "brandName": "AEO Pro", "targetUrl": "https://www.aeo-pro.app/", "responseText": "AEO Pro is cited as an AEO platform.", "citedSources": [{ "url": "https://www.aeo-pro.app/", "sourceType": "primary" }], "position": 1 }], "evidence": [{ "sourceType": "primary", "url": "https://www.aeo-pro.app/methodology", "snippet": "Methodology and scoring model documentation.", "supportsClaim": true }], "revenue": { "monthlyAiImpressions": 12000, "conversionRate": 0.035, "revenuePerConversion": 1800, "grossMargin": 0.82, "attributionCoverage": 0.45 } }'response sample
{ "ok": true, "data": { "citations": [{ "label": "verified_url", "score": 100, "isCited": true }], "evidence": [{ "band": "good", "score": 70 }], "revenue": { "score": 64, "components": { "visibility": 100, "rank": 100, "evidence": 70 } }, "recommendations": [ /* prioritized actions */ ] }, "meta": { "version": "2.0", "provenance": "Evaluation is deterministic scoring over provided observations; it does not independently verify citation provenance." } } - GET
/api/v1/scan/:idLook up a previously persisted scan by UUID.
curl
curl https://www.aeo-pro.app/api/v1/scan/00000000-0000-0000-0000-000000000000 \ -H "Authorization: Bearer aeopro_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
response sample
{ "ok": true, "data": { "id": "...", "url": "https://example.com", "status": "completed", "scores": { "seo": 92, "aeo": 88, "geo": 90, "overall": 90 }, "issues": { "critical": 0, "warning": 2, "info": 5 }, "duration_ms": 14210, "created_at": "2026-05-15T00:14:00Z" } } - GET
/api/v1/sitesList sites owned by the API key holder.
query params
- page (int) — default 1
- limit (int) — default 20, max 100
- q (string) — ILIKE filter on domain / name / url
curl
curl "https://www.aeo-pro.app/api/v1/sites?limit=10" \ -H "Authorization: Bearer aeopro_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
response sample
{ "ok": true, "data": [ { "id": "...", "url": "https://example.com", "domain": "example.com", "name": "Example", "is_verified": true, "latest_scores": { "seo": 92, "aeo": 88, "geo": 90 }, "last_scan_at": "..." } ], "meta": { "page": 1, "limit": 10, "total": 47, "hasMore": true } } - GET
/api/v1/keywordsList tracked keywords. Filter by site_id.
query params
- page (int) — default 1
- limit (int) — default 20, max 100
- site_id (uuid) — filter by site
curl
curl "https://www.aeo-pro.app/api/v1/keywords?limit=20" \ -H "Authorization: Bearer aeopro_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
response sample
{ "ok": true, "data": [ { "id": "...", "keyword": "AEO 工具", "position": 4, "volume": 1200, "difficulty": 38, "trend": "up" } ], "meta": { "page": 1, "limit": 20, "total": 64, "hasMore": true } } - GET
/api/v1/citationsList AI engine citation tracks.
query params
- site_id (uuid) — filter by site
- engine ("chatgpt" | "claude" | "perplexity" | "gemini" | "all") — default all
- date_range ("7d" | "30d" | "90d") — default 30d
- page (int) — default 1
- limit (int) — default 20, max 100
curl
curl "https://www.aeo-pro.app/api/v1/citations?engine=chatgpt&date_range=30d" \ -H "Authorization: Bearer aeopro_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
response sample
{ "ok": true, "data": [ { "id": "...", "platform": "chatgpt", "query_text": "best AEO tool", "cited": true, "citation_url": "https://...", "checked_at": "..." } ], "meta": { "page": 1, "limit": 20, "total": 88, "hasMore": true } }
Error codes
| Code | HTTP | Meaning |
|---|---|---|
| unauthenticated | 401 | Missing or invalid API key |
| rate_limited | 429 | Per-key hourly limit reached |
| invalid_request | 400 | Body or query failed Zod validation |
| not_found | 404 | Resource missing or not owned by key |
| forbidden | 403 | Authenticated but lacks permission |
| upstream_failure | 502 | External dependency (scanner, scrape) failed |
| internal_error | 500 | Unhandled server-side exception |
also available
MCP server
Same auth, JSON-RPC 2.0 over SSE. 4 tools: scan / score / fix / generate. See /docs/mcp.