Quickstart
From an account to your first scan: add your site, create a secret scan API key and send your first request to the Scan API. If you use an AI coding tool, you can stop after step 1 and set up the AccessWiser MCP Server, which needs no request code.
Getting started
The Scan API is included on the Basic, Pro and Business plans, and so is the AccessWiser MCP Server, which scans through it. A trial gets what its plan gets. On Free and Starter you scan from the dashboard, and a request to this API is refused with 403 plan_required. Between the plans that include it, what changes is how many scans a month you get. See scan classes, allowances and credits and pricing.
The account also needs the target site added before a scan against it will run. Adding a site in the dashboard is where you get your widget snippet, and it is what makes that host scannable; a URL on any other host is answered 403 site_not_added. So the order is: add the site, install the widget, then point the API at a page on it.
Not the same as the "Widget and analytics API" line on the pricing page. That is a Business-plan entitlement with a different credential and a different set of endpoints. The Scan API these docs describe is the separate "Developer API" line.
1. Create a secret scan API key
Keys are created in your signed-in AccessWiser dashboard, under Scanning, then Scan API. A key needs a label (1–60 characters, e.g. CI pipeline) and a lifetime — 7, 30, 60 or 90 days, or never expires. You can hold up to 10live keys at once and revoke any of them at any time. If you can't find the screen in your account, email us and we will sort you out.
New keys default to 7 days. This changed: the expiry used to be optional, and a key created without one never expired. A short life limits what a leaked key is worth, so the default is now the shortest option and a permanent key is something you choose on purpose.
If you are wiring this into CI, decide which you want before you build around it. A request made with an expired key is refused with 401 and error.reason of expired — the same shape as a revoked key, so a pipeline that already handles one handles the other. Nothing warns you in advance, and an expired key cannot be extended: create a new one, deploy the secret, then revoke the old one.
The secret looks like awsk_… and is shown exactly once. We store only a keyed hash of it, so a lost key is replaced, never recovered — not even by us. Treat it like a password: environment variable or secret store, never a commit.
Not the same as your widget key. The public aw_… key that goes in your page source is visible to every visitor and is rejected by this API before any lookup happens, with reason: "widget_key". If it were accepted, anyone viewing your page source could spend your scan credits.
2. Make your first request
Send an Idempotency-Key from CI (a git SHA works well). It is optional, but it is what stops a pipeline retry from paying for a second scan.
curl -X POST https://app.accesswiser.com/api/v1/scans \
-H "Authorization: Bearer awsk_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: build-${GITHUB_SHA}" \
-d '{
"url": "https://your-site.example.com/pricing",
"scanClass": "quick"
}'You get back:
HTTP/1.1 202 Accepted
Location: /api/v1/scans/6f1c0f6e-6c2c-4a3b-9f5a-2a1d3b4c5d6e
X-Scan-Class: quick
X-Scan-Allowance-Limit: 50
X-Scan-Allowance-Remaining: 47
X-Scan-Allowance-Reset: 2026-08-01T00:00:00.000Z
X-Scan-Credits-Remaining: 0
{
"scanId": "6f1c0f6e-6c2c-4a3b-9f5a-2a1d3b4c5d6e",
"status": "running",
"scanClass": "quick",
"url": "https://your-site.example.com/pricing",
"chargedTo": "allowance",
"allowanceRemaining": 47,
"credits": 0,
"statusUrl": "/api/v1/scans/6f1c0f6e-6c2c-4a3b-9f5a-2a1d3b4c5d6e",
"disclaimer": "Automated testing detects only a portion of ..."
}Then poll statusUrl until terminal is true.