Integrations

REST API Reference

The AEO Tool REST API lets you run analyses, retrieve scores, and integrate AEO data into your own tools and dashboards. All API requests require authentication and return JSON.

Enterprise only
API access is available on Enterprise ($499/mo) plans. API keys are managed at Settings → API Keys.

Authentication

All API requests must include a Bearer token in the Authorization header:

bash
curl -X POST https://api.aeotool.io/api/analysis/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/page", "keyword": "what is AEO"}'

API keys can be created and revoked at Settings → API Keys. Each key has a label and optional expiry date. We recommend creating a separate key per integration.

Base URL

https://api.aeotool.io

Endpoints

POST/api/analysis/

Run a new AEO analysis. Returns the full analysis result including scores, recommendations, fanout queries, and competitor comparisons. Takes 20–90 seconds depending on options.

Request body

json
{
  "url": "https://example.com/your-page",
  "keyword": "what is answer engine optimization",
  "industry": "SaaS",
  "competitor_urls": [
    "https://competitor.com/page",
    "https://another.com/article"
  ],
  "demo_mode": false
}

Fields

urlstringoptional*Full page URL to analyse. Must be publicly accessible.
keywordstringoptional*Target query. At least one of url or keyword is required.
industrystringoptionalIndustry category. Auto-detected if omitted.
competitor_urlsarrayoptionalUp to 10 competitor URLs to include in gap analysis.
demo_modebooleanoptionalIf true, returns cached demo data without consuming credits. Default: false.

Response (200 OK)

json
{
  "id": "ana_01j2k3l4m5n6o7p8",
  "status": "completed",
  "url": "https://example.com/your-page",
  "keyword": "what is answer engine optimization",
  "industry": "SaaS",
  "overall_score": 67,
  "scores": {
    "aeo_readiness": 52,
    "information_retrieval_cost": 71,
    "html5_semantics": 78,
    "accessibility": 55,
    "eeat": 44,
    "content_patterns": 68,
    "cro": 61
  },
  "recommendations": [
    {
      "id": "rec_01",
      "priority": "critical",
      "dimension": "aeo_readiness",
      "title": "No FAQ schema detected",
      "description": "Your page contains FAQ-style content but lacks FAQ schema markup...",
      "action": "Add @FAQPage JSON-LD schema to your page head...",
      "effort": "quick_win",
      "estimated_score_impact": 12
    }
  ],
  "fanout_queries": [
    {
      "query": "What is AEO vs SEO?",
      "coverage": "not_covered",
      "weight": 0.85
    }
  ],
  "competitor_scores": [
    {
      "url": "https://competitor.com/page",
      "overall_score": 81,
      "scores": { "aeo_readiness": 88, "eeat": 79 }
    }
  ],
  "analysed_at": "2025-04-21T09:30:00Z",
  "credits_used": 1
}
GET/api/analyses/

List all analyses for the authenticated account. Results are paginated (20 per page).

Query parameters

pagePage number (default: 1)
page_sizeResults per page (default: 20, max: 100)
orderingSort by: analysed_at, overall_score, -analysed_at (descending)
json
{
  "results": [
    {
      "id": "ana_01j2k3l4m5n6o7p8",
      "url": "https://example.com/page",
      "keyword": "what is AEO",
      "overall_score": 67,
      "analysed_at": "2025-04-21T09:30:00Z"
    }
  ],
  "count": 42,
  "next": "https://api.aeotool.io/api/analyses/?page=2",
  "previous": null
}
GET/api/analyses/{id}/

Retrieve a single analysis by ID. Returns the same format as the POST response above.

Rate limits

30
Requests per minute
5
Concurrent analyses
Unlimited
Max analyses/month

When you exceed the rate limit, the API returns 429 Too Many Requests with a Retry-After header indicating when you can retry.

Error codes

CodeMeaning
400Bad request — missing required fields or invalid field values
401Unauthorised — missing or invalid API key
402Payment required — account has no remaining credits or plan expired
403Forbidden — feature not available on your current plan
404Not found — analysis ID doesn't exist or doesn't belong to your account
422Unprocessable — URL could not be fetched (blocked, not found, timeout)
429Too many requests — rate limit exceeded
500Server error — please retry after a few seconds; contact support if persistent

Code examples

Python

python
import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://api.aeotool.io"

def run_analysis(url=None, keyword=None, industry=None):
    response = requests.post(
        f"{BASE_URL}/api/analysis/",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "url": url,
            "keyword": keyword,
            "industry": industry,
            "demo_mode": False
        }
    )
    response.raise_for_status()
    return response.json()

# Example usage
result = run_analysis(
    url="https://example.com/blog/what-is-aeo",
    keyword="what is answer engine optimization"
)
print(f"Overall score: {result['overall_score']}")
print(f"AEO Readiness: {result['scores']['aeo_readiness']}")
print(f"Critical issues: {sum(1 for r in result['recommendations'] if r['priority'] == 'critical')}")

JavaScript / Node.js

javascript
const AEO_API_KEY = process.env.AEO_API_KEY;
const BASE_URL = 'https://api.aeotool.io';

async function runAnalysis({ url, keyword, industry }) {
  const response = await fetch(`${BASE_URL}/api/analysis/`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${AEO_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ url, keyword, industry, demo_mode: false }),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`API error ${response.status}: ${error.detail}`);
  }

  return response.json();
}

// Example
const result = await runAnalysis({
  url: 'https://example.com/page',
  keyword: 'what is AEO',
});

console.log('Score:', result.overall_score);
console.log('Recommendations:', result.recommendations.length);