API · v1 beta
DataForAEO API
One base URL, JSON in and out, real HTTP status codes, and a cost on every response so you can meter yourself.
Base URL: https://dataforaeo.dev/api/v1. The two crawler endpoints are free and need no key. The others need a key from the console (sign in with your AEO Toolkit account), sent as Authorization: Bearer dfa_live_…. During the beta, calls draw on your AEO Toolkit plan’s monthly checks.
Every response
{ "ok": true, "request_id": "…", "time_ms": 12, "cost": { "checks": 0 }, "result": { … } }
{ "ok": false, "request_id": "…", "time_ms": 3, "error": { "code": "unauthorized", "message": "…" } }GET · no key · Free
GET /api/v1/ai-crawlers
Every AI agent we classify: its User-Agent token, vendor, what it fetches for (a person asking, a search index, or training), and whether its IPs can be verified.
curl https://dataforaeo.dev/api/v1/ai-crawlers{ "ok": true, "request_id": "…", "time_ms": 1, "cost": { "checks": 0 },
"result": { "crawlers": [
{ "user_agent_token": "ChatGPT-User", "vendor": "openai",
"kind": "user", "ip_verifiable": true }, … ] } }POST · no key · Free
POST /api/v1/ai-crawlers/verify
Is this request really an AI bot? Send the User-Agent and IP from your logs. We match the bot and check the IP against the ranges its vendor publishes: verified, unverified (the example uses a documentation address, so it fails), or unknown when the vendor publishes no list. Nothing is stored.
| Parameter | Meaning |
|---|---|
user_agent | string, required. The full User-Agent header. |
ip | string, optional. IPv4 or IPv6. Without it, verification is "unknown". |
curl -X POST https://dataforaeo.dev/api/v1/ai-crawlers/verify \
-H 'Content-Type: application/json' \
-d '{"user_agent":"Mozilla/5.0; ChatGPT-User/1.0","ip":"203.0.113.7"}'{ "ok": true, "cost": { "checks": 0 }, "result": {
"ai_bot": true, "bot": "ChatGPT-User", "vendor": "openai",
"kind": "user", "verification": "unverified" } }GET · API key · Free
GET /api/v1/demand
Measured AI demand for one of your sites, from the collector: hits by kind for this window and the one before, per page and per bot, with the verified share.
| Parameter | Meaning |
|---|---|
domain | string, required. A project in your workspace with the collector installed. |
days | integer 1 to 30, default 7. The window length. |
curl 'https://dataforaeo.dev/api/v1/demand?domain=example.com&days=7' \
-H "Authorization: Bearer $DFA_KEY"{ "ok": true, "cost": { "checks": 0 }, "result": {
"domain": "example.com", "days": 7,
"current": { "user": 41, "search": 120, "training": 300 },
"previous": { "user": 30, "search": 98, "training": 310 },
"verifiedShare": 0.93, "pages": [ … ], "bots": [ … ] } }POST · API key · 1 check per prompt per engine answered
POST /api/v1/answers/live
Ask the AI engines your prompts now and see, per engine, whether your domain is cited or mentioned, its rank, and an excerpt. Results are also saved to your AEO Toolkit project.
| Parameter | Meaning |
|---|---|
domain | string, required. Created as a project if your plan has room. |
prompts | string array, required, 1 to 5 questions after duplicates are merged (case and spacing ignored). Merged prompts are listed in result.notes. |
curl -X POST https://dataforaeo.dev/api/v1/answers/live \
-H "Authorization: Bearer $DFA_KEY" -H 'Content-Type: application/json' \
-d '{"domain":"example.com","prompts":["best crm for small agencies"]}'{ "ok": true, "cost": { "checks": 3 }, "result": {
"domain": "example.com", "run_id": "…",
"results": [ { "prompt": "best crm for small agencies", "engine": "perplexity",
"model": "…", "cited": true, "mentioned": true, "rank": 2, "excerpt": "…" } ],
"quota": { "used": 13, "limit": 100, "remaining": 87 } } }GET · API key · Free
GET /api/v1/me
The key’s workspace, its plan, and the checks used this month.
curl https://dataforaeo.dev/api/v1/me -H "Authorization: Bearer $DFA_KEY"{ "ok": true, "cost": { "checks": 0 }, "result": {
"workspace_id": "…", "plan": "free", "checks": { "used": 13, "limit": 100 } } }Errors and limits
| HTTP | code | What to do |
|---|---|---|
| 400 | invalid_request, invalid_domain, invalid_prompts, invalid_days, invalid_ip | Fix the request; the message says what. |
| 401 | unauthorized | Missing, malformed, unknown or revoked key. |
| 402 | quota_exceeded, project_limit | The workspace is out of checks or projects for its plan. |
| 404 | not_found | No such project in the key’s workspace. |
| 429 | rate_limited | 120 calls a minute per key; 30 a minute per IP without one. |
| 500 | server_error | Our side. Retry with backoff; quote the request_id if it persists. |