REST API · v1

API Documentation

AccessPulse exposes a single REST endpoint. Send a URL, get back a WCAG 2.2 AA accessibility report with a score, violations, and per-element details. No SDK required.

Base URLhttps://accesspulse.dev

Quick start

Run a scan with a single curl command — no API key required for free scans:

curl -s -X POST https://accesspulse.dev/api/scan \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}' | jq .

With an API key (paid plans — higher rate limits):

curl -s -X POST https://accesspulse.dev/api/scan \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"url": "https://example.com"}' | jq .

POST /api/scan

Scans a URL for WCAG 2.2 AA violations. Synchronous — response returns the complete report.

Request headers

HeaderRequiredValue
Content-TypeYesapplication/json
AuthorizationNoBearer YOUR_API_KEY

Request body

{
  "url": "https://example.com"   // required — must be http:// or https://
}
FieldTypeRequiredDescription
urlstringYesPublic URL to scan. Must be reachable from the internet. Private IPs and internal hostnames are blocked.

Response format

HTTP 200 OK on success. The scan runs synchronously — the connection stays open until the scan completes (typically 10–30 seconds).

200 OK
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "url": "https://example.com",
  "score": 78,
  "violations_count": 2,
  "passes_count": 14,
  "incomplete_count": 0,
  "violations": [
    {
      "id": "landmark-one-main",
      "impact": "moderate",
      "description": "Ensure the document has a main landmark",
      "help": "Document should have one main landmark",
      "helpUrl": "https://dequeuniversity.com/rules/axe/4.10/landmark-one-main",
      "tags": ["cat.semantics", "best-practice"],
      "nodes_count": 1,
      "nodes": [
        {
          "html": "<html lang=\"en\">",
          "target": ["html"],
          "failureSummary": "Fix all of the following:\n  Document does not have a main landmark"
        }
      ]
    }
  ]
}

Fields

FieldTypeDescription
idstringUUID for this scan. Use with GET /api/scan/{id} to retrieve later.
urlstringThe URL that was scanned (normalized).
scoreintegerAccessibility score 0–100. Computed as a weighted ratio of passes to total checks. Critical violations are weighted 10×, serious 5×, moderate 2×, minor 1×.
violations_countintegerTotal number of distinct WCAG rules that failed.
passes_countintegerTotal number of distinct WCAG rules that passed.
incomplete_countintegerRules that could not be fully determined automatically (require manual review).
violations[].idstringaxe-core rule identifier (e.g. color-contrast, image-alt).
violations[].impactstringSeverity: critical · serious · moderate · minor
violations[].nodes_countintegerNumber of DOM elements affected by this rule.
violations[].nodesarrayUp to 10 affected elements with HTML snippet, CSS selector, and remediation summary.

Error codes

All errors return a JSON body with a single error field.

StatusMeaningCommon cause
400Bad requestMissing or invalid url field. Private IPs, localhost, and non-HTTP URLs are rejected.
401UnauthorizedInvalid or missing API key when accessing authenticated endpoints.
403ForbiddenSubscription is inactive (payment failed). Update your payment method.
429Rate limit exceededAnonymous: 10 scans/hour per IP. Paid plans: per-subscription monthly quota.
500Internal errorUnexpected server error. Transient — retry after a short delay.
502Scan failedThe target URL was unreachable, returned an error, or the page failed to load. Check the URL is publicly accessible.

Rate limits

PlanScans / monthNotes
Free (no key)25Per IP address. Also limited to 10 scans/hour per IP.
Developer — $29/mo500Identified by API key.
Team — $149/mo2,000Identified by API key.
Agency — $399/mo10,000Identified by API key.

Quotas reset on the first of each month. Upgrade your plan →

GitHub Action

Block PRs that regress your accessibility score. Zero dependencies — uses only Node.js built-ins.

Install

.github/workflows/accessibility.yml
name: Accessibility

on:
  pull_request:
  push:
    branches: [main]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - name: WCAG 2.2 scan
        uses: accesspulse/scan@v1
        with:
          url: ${{ vars.SITE_URL }}         # e.g. https://your-preview-url.vercel.app
          threshold: 80                      # fail if score drops below 80
          api-key: ${{ secrets.ACCESSPULSE_API_KEY }}  # optional

Inputs

InputRequiredDefaultDescription
urlYesURL to scan.
thresholdNo80Minimum score (0–100). Step fails if score is below this.
api-keyNoAccessPulse API key for paid-tier limits. Omit for free scans.

Outputs

OutputDescription
scoreAccessibility score (0–100).
violationsNumber of WCAG violations found.
passed'true' if score ≥ threshold, 'false' otherwise.

Use outputs in a later step

- name: WCAG 2.2 scan
  id: a11y
  uses: accesspulse/scan@v1
  with:
    url: https://example.com
    threshold: 80

- name: Post score to PR
  run: echo "Score: ${{ steps.a11y.outputs.score }}/100"

Scan a Vercel preview URL

.github/workflows/accessibility.yml
name: Accessibility

on: [pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - name: Wait for Vercel preview
        uses: patrickedqvist/wait-for-vercel-preview@v1.3.1
        id: vercel
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          max_timeout: 120

      - name: WCAG 2.2 scan
        uses: accesspulse/scan@v1
        with:
          url: ${{ steps.vercel.outputs.url }}
          threshold: 80
          api-key: ${{ secrets.ACCESSPULSE_API_KEY }}

Built on axe-core (MPL-2.0) by Deque Systems. AccessPulse is not affiliated with Deque. Questions? Contact us →