Audit any site, from your own code.
The same technology, version-currency and Lighthouse quality audit that powers this site - read any audit's scored report with your API key, and run fresh audits from an MCP-enabled agent.
What your API key does
Your ats_ key is a bearer token for STARTING audits, READING scored reports and driving the MCP tools. Kick off a fresh audit from your CI, poll it to completion and read the scored report back into your dashboards and scripts - same audit engine, same Awesomeness Score you see here, every response wrapped in the same { success, data, meta } envelope.
- 01Create an API key in the workbench.
- 02Start & poll an audit. POST a URL, then poll the status until it's done.
- 03Read the report. GET the scored report, key as the bearer.
Your ats_ key authenticates directly - there is no token exchange step. Manage API keys →
Start an audit
Run the whole audit from CI with your ats_ key: POST the exact URL you want audited - path, query and all, they are preserved - then poll that audit's own URL until it is completed. Two endpoints, one bearer key, no token exchange. The report arrives on the poll itself, so there is no third call. Prefer an agent? The MCP analyze tool below does the same start.
1 · Start the audit
# 1) start an audit - your ats_ key, org-scoped to the key POST https://awesometechstack.com/api/v2/audits Authorization: Bearer ats_live_... Content-Type: application/json { "url": "https://example.com/pricing" } # 202 Accepted - the audit, addressed by its id from here on # (200 instead, with Idempotency-Replayed: true, when you replay a key) { "success": true, "data": { "id": "593406ea-fec7-41b8-8c6f-f09e09a50b18", "status": "queued", "stage": "queued", "progress": 0 } }
2 · Poll the audit until it completes
# 2) poll the SAME url until status is "completed" (usually a few minutes) GET https://awesometechstack.com/api/v2/audits/593406ea-fec7-41b8-8c6f-f09e09a50b18 Authorization: Bearer ats_live_... # 200 OK - keep polling while status is queued or running; # stop on completed (report attached) or failed (failure.reason) { "success": true, "data": { "status": "running", "stage": "scoring", "progress": 72, "report": null, "failure": null } }
Read a report
The poll IS the read: once status is completed, that same GET carries the frozen report - the overall score, the sub-scores (including the A-F-graded AI-Readiness as a number), honest counts and every detected technology with its version status and detection confidence. Reports are addressed by audit id - the id the start call handed you - never by domain, so a re-audit is a new report rather than an overwrite. Send your key as the bearer; the read is scoped to the key's organization.
# read a scored report with your ats_ API key (org-scoped to the key) GET https://awesometechstack.com/api/v2/audits/593406ea-fec7-41b8-8c6f-f09e09a50b18 Authorization: Bearer ats_live_... # 200 OK - the completed audit and its frozen report { "success": true, "data": { "id": "593406ea-fec7-41b8-8c6f-f09e09a50b18", "status": "completed", "score": 85, "report": { "target": { "url": "https://example.com/pricing" }, "score": 85, "band": "medium", "scores": { "technology": 78, "upToDateness": 70, "quality": 93, "aiReadiness": 30 }, "counts": { "technologies": 14, "outdated": 2, "vulnerabilities": 0 }, "technologies": [ { "title": "Next.js", "version": "15.3.1", "versionStatus": "present" } ], "auditedAt": "2026-07-30T20:31:37Z" } } }
MCP for agents
The audit is exposed as an MCP server so coding agents can score a stack on their own - the agent-facing way to start an audit (the REST flow above is the CI-facing one). It speaks JSON-RPC 2.0 over HTTP at POST /api/v2/mcp, authenticated with an API key as a bearer token - no token exchange. Call tools/list to discover the tools and their argument schemas, or tools/call to run one.
curl
# run a fresh audit with the MCP analyze tool (your API key, no token exchange) POST https://awesometechstack.com/api/v2/mcp Authorization: Bearer ats_live_... Content-Type: application/json { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "analyze", "arguments": { "url": "https://example.com" } } }
Node
// any MCP client works; here is a raw fetch call from Node const res = await fetch('https://awesometechstack.com/api/v2/mcp', { method: 'POST', headers: { Authorization: `Bearer ${process.env.ATS_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'analyze', arguments: { url: 'https://example.com' } }, }), }) const { result } = await res.json()
- analyze - audit a URL and return the Awesomeness Score with the detected stack.
- diff - compare two audits and return what changed between them.
- list-vulnerabilities - the known vulnerabilities and end-of-life technologies on a site.
- ai-readiness - the A-F AI-Readiness grade and its published checks.
Bearer keys work on paid plans (Starter and up). Manage API keys →
Audit any path, not just the root
An audit target is a full URL. Post https://example.com/pricing and the audit runs against that page: report.target.url echoes it back, and the technologies, scores and findings in the report are that page's. One audit covers one URL, so a second page is a second audit - and each one keeps its own history and its own share link.
A note on auth
Audits you start in the app run against your signed-in session (a __session cookie). Programmatic access - starting an audit, reading a report and the MCP endpoint - uses an API key instead: send it directly as the bearer on every call. Audits, report reads and MCP all work from any CI runner with your key. Errors are RFC-9457 problem+json with a machine reason code.
Coming from the old API
The previous customer API - /products/website-analyzer/auth/token and /products/website-analyzer/api/v1/analysis/* - was retired with the platform rewrite and now answers 404. Three things change, and the new shape is smaller than the old one:
- No token exchange. The old flow traded an
apiKeyfor a 24-hour JWT. Now the key itself is the bearer on every call - nothing to refresh, nothing to cache. Your old key will not work: the new API accepts onlyats_keys, and keys from the old system were never carried over. Issue a new key under API keys. - One url for status and result.
analysis/status/<id>andanalysis/result/<id>became a singleGET /api/v2/audits/<id>: poll it, and the report is attached the momentstatusturnscompleted. - Envelope and errors. Success bodies are
{ success, data, meta }- the old flat body is now underdata. Failures are RFC-9457problem+jsonwith a machinereason, instead of a bare status code.
# BEFORE (v1, retired - both of these now answer 404) POST /products/website-analyzer/auth/token { "apiKey": "<your old key>" } # -> { "accessToken": "<jwt, 24h>" } POST /products/website-analyzer/api/v1/analysis/start Authorization: Bearer <jwt> { "url": "https://example.com" } # -> { "id": "<taskId>" } GET /products/website-analyzer/api/v1/analysis/status/<id> GET /products/website-analyzer/api/v1/analysis/result/<id> # AFTER (v2) - no token exchange at all: the key IS the bearer POST https://awesometechstack.com/api/v2/audits Authorization: Bearer ats_live_... { "url": "https://example.com" } # -> 202 { success, data: { id, status } } GET https://awesometechstack.com/api/v2/audits/<id> # status AND result, one url
The old running / statusCode / statusResult triple has one successor: status, which is queued, running, completed or failed. A failed audit carries failure.reason instead of a numeric code.
Included from Starter up
There is no separate API plan. The REST API and the MCP server are part of every paid plan from Starter upward - your plan's monthly audits power API and MCP runs just like the ones you start by hand, and beyond the cap both draw from the same audit budget. Nothing is ever billed automatically.