Skip to main content

xsbl Docs

Guides, API reference, and integration setup for xsbl accessibility scanning.

Getting started

xsbl scans websites for WCAG 2.2 accessibility violations using axe-core in a real browser. Here are the main ways to use it:

1. Dashboard — add sites, run scans, view issues, and generate reports at xsbl.io/dashboard.

2. Scheduled scans — set daily or weekly scans per site and get alerted when new issues appear after a deploy.

3. GitHub integration — connect your repo, select issues, and xsbl creates a pull request with AI-generated code fixes.

4. API & CI/CD — trigger scans from your deployment pipeline using API keys.

All plans include the dashboard and manual scanning. Scheduled scans require Starter or above. GitHub PRs, API keys, and CI/CD require Pro or Agency.

Verify your site to unlock scheduled scans and compliance reports. Go to your site → the verification banner at the top. Choose DNS (add a TXT record), Meta tag (add a meta tag to your HTML), or File upload (host a verification file). Click "Verify" once done.

Scheduled scans

Automate scanning on a daily or weekly schedule. Available on Starter, Pro, and Agency plans.

Go to any site → Settings tab → Scan Schedule. Choose daily or weekly and select the hour (UTC) you want scans to run.

Scheduled scans count toward your monthly scan limit. Free plans are limited to manual scans only.

After each scheduled scan, xsbl automatically sends alerts (Slack and email) if configured, and auto-resolves issues that no longer appear in the results.

The site overview shows the time of the last scheduled scan and when the next one is due. Your time zone is displayed alongside the UTC hour for reference.

GitHub integration

Connect a GitHub repo to enable one-click PR creation for accessibility fixes.

Step 1: Go to your site → Settings → GitHub Integration.

Step 2: Enter your repo (e.g. acme/website) and a Personal Access Token with repo scope.

Step 3: Click Test to verify, then Save.

Create a token at github.com/settings/tokens — select the "repo" scope.

Single fix: Open any issue → click "Create fix PR" → xsbl reads your source code, generates a fix with AI, and opens a PR.

Bulk fix: On the Issues tab, check multiple issues (or use quick-select buttons like "All critical"), then click "Create fix PR" in the floating bar. One PR with all fixes.

How file discovery works: xsbl fetches your repo's file tree, scores files by relevance (matching page URLs to file names, component names, CSS selectors), fetches the top source files, sends them to our AI along with the issues, and commits the fixed files to a new branch.

CI/CD (GitHub Actions)

Run accessibility scans automatically after every deploy.

Step 1: Create an API key in Settings → API Keys (Pro or Agency required).

Step 2: Add repository secrets in GitHub:

XSBL_API_KEY — your API key
XSBL_SITE_ID — your site UUID (from the URL in the dashboard)

Step 3: Add this workflow file to your repo:

.github/workflows/xsbl-a11y.yml
name: Accessibility Scan
on:
  push:
    branches: [main]
  deployment_status:
    types: [completed]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger xsbl scan
        run: |
          RESPONSE=$(curl -s \
            -X POST "https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/scan-site" \
            -H "Authorization: Bearer ${{ secrets.XSBL_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{"site_id": "${{ secrets.XSBL_SITE_ID }}"}')
          
          SCORE=$(echo "$RESPONSE" | jq -r '.score')
          ISSUES=$(echo "$RESPONSE" | jq -r '.issues_found')
          
          echo "### Accessibility: $SCORE/100" >> $GITHUB_STEP_SUMMARY
          echo "$ISSUES issues found" >> $GITHUB_STEP_SUMMARY
          
          # Fail build if score is below threshold:
          # if (( $(echo "$SCORE < 70" | bc -l) )); then exit 1; fi

The scan results appear in the GitHub Step Summary on every run. Uncomment the last line to fail builds when the score drops below your threshold.

Slack & email alerts

Get notified after every scan completes.

Slack: Go to Settings → Alert Integrations → paste your Slack webhook URL → click Test. You'll get a rich message with score, issues, and a dashboard link.

Email: Add email addresses in Settings → Alert Integrations, or leave blank to use team members' addresses based on their notification preferences.

Team management

Invite team members from Settings → Team. Enter their email and choose a role:

Owner — full access including billing and account deletion. One per workspace.

Admin — can manage sites, settings, and team members. Cannot change billing or delete the account.

Member — can run scans, view issues, and create fix PRs. Cannot change settings or manage the team.

If the invitee already has an xsbl account, they're added immediately. Otherwise they receive an email invite and are added automatically when they sign up with that email address.

Accessibility simulator

The simulator shows how your site appears under different vision conditions. Available on Pro and Agency plans.

Go to any site → Simulator tab → select a condition. The simulator takes a real screenshot of your site and applies scientifically accurate filters for:

Protanopia (red-blind), Deuteranopia (green-blind), Tritanopia (blue-blind), Achromatopsia (total color blindness), Low vision, Cataracts, Glaucoma, and Macular degeneration.

Use these screenshots in client presentations and reports to demonstrate why accessibility matters.

Public status page

Enable a public accessibility status page for your organization. Go to Settings → General → toggle "Public status page."

Your status page lives at xsbl.io/status/your-org-slug and shows all verified sites with their current scores. It updates automatically after each scan.

Link it from your site's footer to demonstrate your commitment to accessibility. Only verified sites appear on the status page.

Client dashboards (Agency)

Give clients read-only access to their sites without sharing your full dashboard. Agency plan only.

Invite a client: Go to Settings → Integrations → Client Access → enter their email and select which sites they can see. They receive an invite link with a unique access token.

Clients see their assigned sites, scores, issues, and reports — but cannot trigger scans, change settings, or see other clients' data.

Clients don't need an xsbl account. They access their dashboard via a unique token URL. You can revoke access at any time.

White-label reports (Agency)

Replace xsbl branding with your company name on all client-facing reports. Agency plan only.

Go to Settings → Integrations → Scheduled Reports. Enable white-label, enter your company name, add recipient emails, and set the delivery schedule (weekly or monthly).

Reports include the overall score, per-page breakdowns, top issues with severity and WCAG criteria, and remediation guidance — all under your brand.

Custom scan profiles (Agency)

Customize what gets scanned per site. Agency plan only.

Go to any site → Settings → Scan Profile. You can:

Exclude rules — skip specific axe-core rules that aren't relevant (e.g. rules for content you don't control).

Exclude selectors — skip specific page elements like third-party widgets, chat bubbles, or ad containers.

Toggle best practices — include or exclude best-practice checks that go beyond WCAG requirements.

Scan profiles persist across all scans (manual and scheduled) for that site.

Evidence export (Agency)

Export structured compliance evidence for SOC 2, ISO 27001, and HIPAA audits. Agency plan only.

Go to Dashboard → Evidence Export. Select a framework, date range, and which sections to include:

Vulnerability management — open/fixed issues, severity breakdown, remediation timelines.

Access control — team members, roles, access change history.

Change management — pull requests created, files changed, approval status.

Monitoring — scan history, scheduled scan configuration, scan completion rates.

Asset inventory — all monitored sites with scores, scan schedules, and GitHub connections.

Export as JSON for programmatic use or CSV for spreadsheet review. Evidence packages are timestamped and include full metadata.

API keys

API keys let you authenticate without a user session. Available on Pro and Agency.

Create keys in Settings → API Keys. Each key is shown once — copy it immediately.

bash
curl -X POST https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/scan-site \
  -H "Authorization: Bearer xsbl_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"site_id": "your-site-uuid"}'

Keys are prefixed with xsbl_, 45 characters. Max 5 active keys per org.

Quick scan (public)

Scan any URL without authentication.

bash
curl -X POST https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/quick-scan \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'
json
{
  "score": 72,
  "issues_found": 14,
  "impact": { "critical": 2, "serious": 5, "moderate": 4, "minor": 3 },
  "top_issues": [
    { "rule_id": "image-alt", "impact": "critical", "count": 5,
      "description": "Images must have alternate text" }
  ]
}

Scan site (authenticated)

Trigger a multi-page scan. Returns results synchronously.

bash
curl -X POST https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/scan-site \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"site_id": "uuid"}'

Pass specific URLs to scan only certain pages:

json
{ "site_id": "uuid", "urls": ["https://example.com/", "https://example.com/about"] }

Page limits: Free: 5, Starter: 10, Pro: 25, Agency: 50

Bulk fix PR (authenticated)

Create a single PR fixing multiple issues. Requires GitHub connected on the site.

bash
curl -X POST https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/bulk-fix-pr \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"site_id": "uuid", "issue_ids": ["id1", "id2", "id3"]}'
json
{
  "status": "created",
  "pr_number": 42,
  "pr_url": "https://github.com/acme/site/pull/42",
  "issues_fixed": 3,
  "files_changed": 2
}

Generate report (authenticated)

Generate an HTML compliance report (VPAT format). Print to PDF from the browser.

bash
curl -X POST https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/generate-report \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"site_id": "uuid", "format": "html"}'

Use format: "json" for raw data export.

Alt text generation (authenticated)

Send an image URL and get AI-generated alt text.

bash
curl -X POST https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/generate-alt-text \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"image_url": "https://example.com/hero.jpg", "page_url": "https://example.com"}'
json
{
  "alt_text": "Team collaborating around a laptop in a modern office",
  "is_decorative": false,
  "confidence": 0.92
}

Supports JPEG, PNG, GIF, WebP, and SVG. Max 5MB.

Usage (authenticated)

Check current billing period usage:

bash
curl https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/check-usage \
  -H "Authorization: Bearer YOUR_TOKEN"
json
{
  "plan": "pro",
  "scans_used": 42,
  "scans_limit": 100,
  "scans_remaining": 58,
  "can_scan": true
}

Badge (public)

Embed a dynamic accessibility score badge.

markdown
![accessibility](https://vvfrbhvrhhuooopnnnlw.supabase.co/functions/v1/badge?domain=example.com)
domain — required
style flat (default), plastic, minimal
label — left-side text (default: "accessibility")

Rate limits

Free — 3 scans/month, 1 site, 10 AI suggestions, 1 GitHub PR
Starter ($19/mo) — 10 scans/month, 1 site, 50 AI suggestions, 5 GitHub PRs
Pro ($69/mo) — 100 scans/month, unlimited sites, 200 AI suggestions, 25 GitHub PRs, API keys, CI/CD
Agency ($249/mo) — 999 scans/month, unlimited sites, unlimited AI suggestions, unlimited GitHub PRs, white-label reports, client dashboards

Scan limits reset on the 1st of each month. AI suggestion and GitHub PR limits also reset monthly.

Realtime events

Use Supabase Realtime to listen for scan completions:

javascript
supabase.channel("scans")
  .on("postgres_changes", {
    event: "*", schema: "public", table: "scans",
    filter: `site_id=eq.${siteId}`,
  }, (payload) => {
    if (payload.new.status === "complete") {
      console.log("Score:", payload.new.score);
    }
  }).subscribe();

Slack and email alerts fire automatically after every scan — configure in Settings.