Developer API

ScanAble API Documentation

Integrate WCAG 2.2 accessibility scanning into your applications. Scan any URL and get a structured JSON response with compliance score, violations, severity breakdown, and fix suggestions.

API key auth
5-15s per scan
100 free scans/month
REST + JSON

Quick start

1

Get an API key

curl
curl -X POST https://scanable.dev/api/v1/keys \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com"}'
2

Scan a URL

curl
curl -X POST https://scanable.dev/api/v1/scan \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'
3

Get structured results

json
// Free plan response (100 scans/mo)
{
  "url": "https://example.com",
  "scannedAt": "2026-04-12T10:30:00Z",
  "score": 72,
  "level": "AA",
  "plan": "free",
  "summary": {
    "totalViolations": 23,
    "critical": 2, "serious": 5, "moderate": 12, "minor": 4,
    "passCount": 87
  },
  "violations": [
    {
      "id": "color-contrast",
      "impact": "serious",
      "description": "Elements must have sufficient color contrast",
      "wcagCriteria": ["wcag143"],
      "count": 5,
      "detailsAvailable": true,
      "upgradeUrl": "https://scanable.dev/pricing"
    }
  ],
  "passes": 87,
  "scanDurationMs": 8234,
  "note": "Upgrade to a paid plan to get fix instructions and affected HTML elements."
}

Paid plans also include fix instructions and affected elements:

json
// Paid plan response (Starter+) — includes fix instructions
{
  "url": "https://example.com",
  "score": 72,
  "plan": "starter",
  "violations": [
    {
      "id": "color-contrast",
      "impact": "serious",
      "description": "Elements must have sufficient color contrast",
      "count": 5,
      "nodes": [
        {
          "html": "<p class=\"text-gray-400\">...",
          "target": ["#hero > p:nth-child(2)"],
          "failureSummary": "Fix: Element has contrast ratio of 3.2:1 (need 4.5:1)"
        }
      ]
    }
  ]
}

Code examples

Node.js / TypeScript

javascript
const response = await fetch("https://scanable.dev/api/v1/scan", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_your_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ url: "https://example.com" }),
});
const data = await response.json();
console.log(data.score); // 72

Python

python
import requests

response = requests.post(
    "https://scanable.dev/api/v1/scan",
    headers={"Authorization": "Bearer sk_live_your_key_here"},
    json={"url": "https://example.com"},
)
data = response.json()
print(f"Score: {data['score']}/100")

Endpoints

POST/api/v1/keys

Generate a new API key

{ "email": "you@example.com", "name": "My App" }
POST/api/v1/scanAuth required

Scan a URL for WCAG violations

{ "url": "https://example.com", "level": "AA" }
GET/api/v1/usageAuth required

Get current period usage stats

GET/api/v1/keysAuth required

List your active API keys

DELETE/api/v1/keysAuth required

Revoke an API key

{ "keyId": "clx..." }

Authentication

All API requests (except key generation) require a Bearer token in the Authorization header:

http
Authorization: Bearer sk_live_abc123def456...

Keys start with sk_live_. Store them securely — they are shown only once at creation.

Rate limits

Rate limits are enforced per API key on a monthly basis. The following headers are included in every response:

X-RateLimit-LimitMonthly scan quota
X-RateLimit-RemainingScans remaining this month
X-RateLimit-ResetUnix timestamp when the quota resets

When quota is exceeded, you'll receive a 429 Too Many Requests response.

API pricing

PlanPriceScansResponse data
Free$0100/moViolation summary (no fix instructions)
Starter$19/mo1,000/moFull data + fix instructions
Growth$49/mo5,000/moFull data + fix instructions
Scale$149/mo25,000/moFull data + fix instructions

Error codes

401UNAUTHORIZEDMissing or invalid API key
400INVALID_INPUTMalformed request body or invalid URL
429QUOTA_EXCEEDEDMonthly scan limit reached
502SCAN_FAILEDTarget URL unreachable or blocked scanning
400KEY_LIMITMaximum 5 active keys per email

Start scanning for free

Get 100 free scans per month. No credit card required.

curl -X POST https://scanable.dev/api/v1/keys -H "Content-Type: application/json" -d '{"email":"you@example.com"}'