Portfolio demo. Payments run in Stripe test mode: use card 4242 4242 4242 4242, any future date and any CVC. No real charges.

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

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

Scan a URL

curlcurl -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

javascriptconst 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

pythonimport 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:

httpAuthorization: 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

Free$0
100/mo

Violation summary (no fix instructions)

Starter$19/mo
1,000/mo$0.019/scan

Full data + fix instructions

Growth$49/mo
5,000/mo$0.0098/scan

Full data + fix instructions

Scale$149/mo
25,000/mo$0.006/scan

Full 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"}'