AINativeainative.axAX AUDIT
DEVELOPERS

API Documentation

Run AX Audit agent-readiness scans from your own CI/CD pipeline, monitoring stack, or internal tooling. The API is public and requires no authentication.

BASE URL
https://api.ainative.studio
AUTHENTICATION

None. All endpoints under /api/v1/public/* are open.

CONTENT TYPE

application/json for request bodies and responses.

TIMEOUTS

Scans run synchronously while the page is rendered. Set your client timeout to at least 60s for a quick scan and 90s for a full report — a cold site or slow render can take that long.

RATE LIMITS

Rate limits apply to abusive traffic; no published per-key quota exists yet. If you're integrating a high-volume CI/CD or monitoring use case, contact us for details.

POST/api/v1/public/ax-audit

Quick scan

Runs a fast AX (Agent eXperience) audit on a URL — 7 agent-readiness checks — and returns a score out of 100 with a letter grade. No data is persisted; good for a CI/CD gate or lightweight health check.

REQUEST BODY
{
  "url": "https://example.com"
}
RESPONSE
{
  "url": "https://example.com",
  "score": 82,
  "max_score": 100,
  "grade": "B",
  "checks": [
    {
      "name": "llms.txt",
      "passed": true,
      "score": 10,
      "max_score": 10,
      "details": "Found at /llms.txt"
    }
  ],
  "scanned_at": "2026-10-23T18:04:11Z",
  "full_report_url": "/ax-audit/full"
}
POST/api/v1/public/ax-audit/full

Full report

Runs the full audit — core checks plus an agent-simulation task (e.g. 'find pricing') and an industry benchmark percentile — and persists the result. Returns a report_id you can use to retrieve the same report later without re-scanning.

REQUEST BODY
{
  "url": "https://example.com",
  "industry": "saas"
}
RESPONSE
{
  "report_id": "e4b1c2a0-...-9f3d",
  "url": "https://example.com",
  "score": 82,
  "max_score": 100,
  "grade": "B",
  "checks": [ /* same shape as quick scan */ ],
  "scanned_at": "2026-10-23T18:04:11Z",
  "simulation": {
    "task": "find_pricing",
    "success": true,
    "score": 90,
    "failure_point": null,
    "total_steps": 4,
    "total_time_ms": 3200,
    "transcript": "...",
    "steps": [
      {
        "step_number": 1,
        "action": "navigate",
        "target": "https://example.com/pricing",
        "result": "success",
        "duration_ms": 800
      }
    ]
  },
  "benchmark": {
    "industry": "saas",
    "percentile": 64,
    "industry_median": 71,
    "industry_p25": 58,
    "industry_p75": 85,
    "industry_top_10": 94
  }
}
GET/api/v1/public/ax-audit/reports/{report_id}

Retrieve a stored report

Fetches a previously generated full report by its report_id — the same shape returned by the full-report endpoint. Use this to poll for or re-display a report without re-running the scan.

RESPONSE
{
  "report_id": "e4b1c2a0-...-9f3d",
  "url": "https://example.com",
  "score": 82,
  "max_score": 100,
  "grade": "B",
  "checks": [ /* ... */ ],
  "scanned_at": "2026-10-23T18:04:11Z",
  "simulation": { /* ... */ },
  "benchmark": { /* ... */ }
}

// 404 if report_id does not exist
POST/api/v1/public/ax-audit/crawl

Multi-page crawl

Crawls a site starting from the given URL (up to max_pages, default 10, ceiling 500) and runs a lightweight AX check on each discovered page, returning an overall score and per-dimension averages across the whole site.

Note: As of this writing, crawl execution is synchronous — the POST request blocks until the crawl finishes, which can be slow for large sites and may hit gateway timeouts near the 500-page ceiling. An async, Celery-backed version of this endpoint is in review (returning the job id immediately and moving the crawl itself off the request thread) but has not shipped yet. The request/response shapes above reflect what is live today; if you build against this endpoint, poll GET /ax-audit/crawl/{crawl_id} defensively and expect the status field (pending/completed/failed) to gain more value under async execution without a breaking shape change.
REQUEST BODY
{
  "url": "https://example.com",
  "max_pages": 50
}
RESPONSE
// Current response — the crawl runs inline and the
// request does not return until it finishes:
{
  "crawl_id": "8a21f0...-77cd",
  "status": "completed",
  "url": "https://example.com",
  "max_pages": 50
}

// Fetch full results (including per-page data) via:
// GET /api/v1/public/ax-audit/crawl/{crawl_id}
{
  "crawl_id": "8a21f0...-77cd",
  "status": "completed",
  "url": "https://example.com",
  "pages_crawled": 47,
  "overall_score": 76,
  "dimension_averages": { "structured_data": 80, "llms_txt": 100 },
  "crawl_time_ms": 24300,
  "pages": [ /* per-page results */ ],
  "errors": []
}
GET/api/v1/public/ax-audit/benchmark/{industry}

Industry benchmark

Returns benchmark statistics (median, 25th/75th percentile, top 10%, sample size) for a given industry, for comparing a score against peers. See GET /ax-audit/benchmark for the list of supported industry slugs.

RESPONSE
{
  "industry": "saas",
  "median": 71,
  "p25": 58,
  "p75": 85,
  "top_10": 94,
  "sample_size": 412
}

Code examples

Quick scan and full report are the two endpoints most useful for getting started — a CI/CD gate typically only needs the quick scan.

Quick scan

CURL
curl -X POST https://api.ainative.studio/api/v1/public/ax-audit \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'
PYTHON (httpx)
import httpx

resp = httpx.post(
    "https://api.ainative.studio/api/v1/public/ax-audit",
    json={"url": "https://example.com"},
    timeout=60,
)
resp.raise_for_status()
result = resp.json()
print(result["score"], result["grade"])
JAVASCRIPT (fetch)
const res = await fetch("https://api.ainative.studio/api/v1/public/ax-audit", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://example.com" }),
});

if (!res.ok) throw new Error(`API error: ${res.status}`);
const result = await res.json();
console.log(result.score, result.grade);

Full report

CURL
curl -X POST https://api.ainative.studio/api/v1/public/ax-audit/full \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "industry": "saas"}'
PYTHON (httpx)
import httpx

resp = httpx.post(
    "https://api.ainative.studio/api/v1/public/ax-audit/full",
    json={"url": "https://example.com", "industry": "saas"},
    timeout=90,
)
resp.raise_for_status()
report = resp.json()
report_id = report["report_id"]

# Retrieve the same report later without re-scanning
later = httpx.get(f"https://api.ainative.studio/api/v1/public/ax-audit/reports/{report_id}")
later.raise_for_status()
JAVASCRIPT (fetch)
const res = await fetch("https://api.ainative.studio/api/v1/public/ax-audit/full", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://example.com", industry: "saas" }),
});

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

// Retrieve the same report later without re-scanning
const later = await fetch(
  `https://api.ainative.studio/api/v1/public/ax-audit/reports/${report.report_id}`
);

Error responses

Errors follow a canonical envelope. Common statuses: 422 for a missing or empty url, 404 for an unknown report or crawl ID, and 502 if the target URL could not be scanned (unreachable, blocked, or timed out).

{
  "detail": "URL must not be empty"
}