AEO-Pro Public API
Run AEO-Pro's 53-point scan engine from your own code. Analyse SEO, AEO (AI Engine Optimisation) and GEO signals for any URL.
https://aeo-pro-beta.vercel.app/api/v1Overview
The AEO-Pro API is a JSON REST API. All endpoints accept and return JSON. HTTPS only in production.
Authentication
Pass your API key in the X-API-Key header:
curl -X POST https://aeo-pro-beta.vercel.app/api/v1/scan \
-H "X-API-Key: aeopro_your_key_here" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'No key? Anonymous requests are allowed with a lower rate limit (10 req/hr per IP). Create a free API key at /dashboard/settings.
Rate Limits
| Plan | Requests / hour |
|---|---|
| Anonymous (no key) | 10 |
| Free | 10 |
| Starter | 100 |
| Pro | 500 |
| Agency | Unlimited |
Rate limit info is returned in every response header: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
Endpoints
/api/v1/scanRun a full (or quick) 53-point scan on a URL.
Request body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | ✓ | — | Target URL (with or without https://) |
mode | "full" | "quick" | "full" | Full=53 checks; quick=core checks only |
Response
{
"success": true,
"data": {
"url": "https://example.com",
"grade": "B+",
"scores": {
"seo": 78,
"aeo": 65,
"geo": 71,
"total": 72
},
"checks": [
{
"id": "meta_title",
"category": "seo",
"status": "pass",
"score": 10,
"maxScore": 10,
"title": "Meta Title",
"description": "Title tag present and within length limits"
}
],
"scannedAt": "2026-04-08T10:00:00.000Z",
"duration": 4521
}
}/api/v1/keys — list your API keys (JWT required)/api/v1/keys — create a new API key (JWT required)/api/v1/keys/:id — delete an API key (JWT required)Manage keys via Dashboard → Settings → API Keys, or with a JWT in Authorization: Bearer <jwt>.
Response Format
All successful responses wrap data in {"success": true, "data": {...}}. Errors use {"error": "...", "code": "..."}.
Grade Scale
| Grade | Total Score |
|---|---|
| A+ | 95 – 100 |
| A | 85 – 94 |
| B+ | 75 – 84 |
| B | 65 – 74 |
| C | 55 – 64 |
| D | 40 – 54 |
| F | 0 – 39 |
Code Examples
curl
# Anonymous scan (10/hr limit)
curl -s -X POST https://aeo-pro-beta.vercel.app/api/v1/scan \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","mode":"quick"}' | jq .
# Authenticated scan
curl -s -X POST https://aeo-pro-beta.vercel.app/api/v1/scan \
-H "Content-Type: application/json" \
-H "X-API-Key: aeopro_your_key_here" \
-d '{"url":"https://example.com"}' | jq .data.gradePython
import requests
API_KEY = "aeopro_your_key_here"
BASE = "https://aeo-pro-beta.vercel.app/api/v1"
resp = requests.post(
f"{BASE}/scan",
json={"url": "https://example.com"},
headers={"X-API-Key": API_KEY},
timeout=35,
)
resp.raise_for_status()
data = resp.json()["data"]
print(f"Grade: {data['grade']} (SEO:{data['scores']['seo']} AEO:{data['scores']['aeo']} GEO:{data['scores']['geo']})")
# Check which items failed
failed = [c for c in data["checks"] if c["status"] == "fail"]
for c in failed:
print(f" ✗ {c['id']}: {c['description']}")Node.js
const BASE = "https://aeo-pro-beta.vercel.app/api/v1";
const KEY = "aeopro_your_key_here";
async function scanUrl(url) {
const res = await fetch(`${BASE}/scan`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": KEY,
},
body: JSON.stringify({ url }),
});
if (!res.ok) {
const err = await res.json();
throw new Error(`API error ${res.status}: ${err.error}`);
}
const { data } = await res.json();
console.log(`${data.url} → ${data.grade}`);
console.log(data.scores);
return data;
}
scanUrl("https://example.com");MCP Server (AI IDE Integration)
AEO-Pro ships an MCP (Model Context Protocol) server so Claude Code, Cursor, Windsurf, and other AI IDEs can call the scan engine directly from chat.
MCP endpoint: https://aeo-pro-beta.vercel.app/mcp/sse
Claude Code (~/.claude.json)
{
"mcpServers": {
"aeo-pro": {
"type": "http",
"url": "https://aeo-pro-beta.vercel.app/mcp/sse",
"headers": { "X-API-Key": "aeopro_your_key_here" }
}
}
}Cursor / Windsurf (.cursor/mcp.json)
{
"mcpServers": {
"aeo-pro": {
"url": "https://aeo-pro-beta.vercel.app/mcp/sse?key=aeopro_your_key_here"
}
}
}Available MCP Tools
| Tool | Input | Output |
|---|---|---|
aeo_scan | url, mode? | 53-point scan + grade |
aeo_score | url | Quick score summary |
aeo_fix | url, issues? | llms.txt + JSON-LD + robots.txt |
aeo_generate | url, content_type, topic? | AI-generated FAQ/blog/product |
Test MCP via curl
# List tools
curl -s -X POST https://aeo-pro-beta.vercel.app/mcp/sse \
-H "Content-Type: application/json" \
-H "X-API-Key: aeopro_your_key_here" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}' | jq '.result.tools[].name'
# Quick score
curl -s -X POST https://aeo-pro-beta.vercel.app/mcp/sse \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"aeo_score","arguments":{"url":"https://example.com"}},"id":2}'Error Codes
| HTTP | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing or invalid request field |
| 400 | INVALID_JSON | Request body is not valid JSON |
| 401 | INVALID_API_KEY | X-API-Key header is invalid or revoked |
| 403 | PLAN_LIMIT | Plan quota exhausted |
| 429 | RATE_LIMITED | Too many requests; check Retry-After header |
| 500 | INTERNAL_ERROR | Unexpected server error |