GITHUB APP

Scan every pull request

Accessibility scanning on every pull request — automatic, zero config, works with any URL.

Overview

The ADAGuard GitHub App scans the preview of every pull request and posts the accessibility score and issues as a PR comment and a GitHub check. It finds the preview URL on its own, or you can point it at any URL with a .adaguard.yml config file in your repo.

No setup
Install once and every pull request is scanned.
Any URL
Scan the detected preview or a URL you choose.
A check on the PR
The score in the PR. On Business and up, you can make the check fail.

Installation

  1. Install the GitHub App
    Click "Install on GitHub" above. Select the repositories you want to scan. On Free the App scans 3 pull requests a month, public or private; after that it asks you to sign in or upgrade, and the 3 start again on the 1st. Paid plans scan every pull request.
  2. Open a pull request
    That's it. ADAGuard scans when the pull request is opened or updated, and again when its preview deployment reports success.
  3. View the results
    The score, the issues and fix links appear in one PR comment, updated on every push. A check named "ADAGuard Accessibility" shows the score.
  4. Optional: add .adaguard.yml
    Add .adaguard.yml to your repo root to set the URL to scan, the standard, or (Business and up) a minimum score.

How It Works

ADAGuard scans when a pull request is opened, updated or reopened, and again when GitHub reports that its preview deployment succeeded (deployment_status). The result is posted back as a PR comment and a check as soon as the scan finishes. The URL it scans is, in order: the URL you set (in Settings → Integrations or .adaguard.yml), the preview URL from the deployment event, or a preview URL found in the pull request description. It checks the pull request’s preview, not your live site: deployments your host marks as production, including GitHub Pages, are skipped. Nothing to set up.

Open or update a pull request
  → your platform deploys a preview
    → GitHub reports the deployment (deployment_status)
      → ADAGuard picks the URL
        → runs the accessibility scan (up to 1 minute)
          → posts the PR comment and the check

If no deployment event fires (e.g. your repo doesn’t use a preview platform), you can still set a custom URL in .adaguard.yml and the app will scan it on every PR.

Auto-detected Platforms

When no URL is set, the App finds the preview itself. These platforms report their preview to GitHub, so it is picked up automatically:

  • Vercel
  • Netlify
  • Railway
  • Render
  • Cloudflare Pages

These don’t report previews to GitHub. Paste the preview URL into the pull request description (for example Preview: https://your-app.fly.dev) and it is picked up on the next push:

  • Fly.io
  • Heroku review apps
  • AWS Amplify
  • Surge.sh
  • GitHub Pages

On any other host, set a custom URL and every pull request scans it.

Comment and Check

ADAGuard keeps one comment per pull request and updates it on every push. It always shows one thing: the result, or what to do when there is no result (sign in, upgrade, a missing preview, a preview behind a login).

  • The result: the score, what changed since the last scan (paid plans), and the issues — the top 5 on Free, all of them on paid plans — each with its element, WCAG criteria and a fix link. On Professional and up, step-by-step fixes are included. A score of 90 or more with no issues is a one-line comment.
  • The check is named ADAGuard Accessibility. It passes at 70 or above and is neutral below — it never fails unless you ask it to. On Business and up you can make it fail below a score, on any critical or serious issue, or both, in Settings → Integrations or .adaguard.yml. To stop a merge, also make it a required status check in your branch protection rules.
  • Ignored issues: issue kinds you ignore (Settings → Integrations or ignore_rules) are left out of the comment and the check; the comment says how many. The score is unchanged.
  • Before you sign in: the App scans 3 pull requests. On the next one, the comment asks you to sign in to ADAGuard, and scanning continues once you do.

Plan Limits

FeatureFreeStarterProfessional and up
Pull requests scanned3 a monthUnlimitedUnlimited
Private repositories125 (Business/Enterprise: unlimited)
Public repositoriesWithin the 3UnlimitedUnlimited
Issues shown per PRTop 5AllAll
Fix guide linksYesYesYes
Score change since last scanNoYesYes
Step-by-step fixes in the commentNoNoYes
Fail the check (below a score or on critical issues, when you turn it on)NoNoBusiness+
Pages per scan1–31–31–3
Scans per installation20 an hour, 100 a day200 an hour, 1,000 a day200 an hour, 1,000 a day

A private repository takes a slot the first time one of its pull requests is scanned. Over the hourly or daily cap, the check says “Scan skipped — rate limit reached” and the next push scans again once the cap resets. View full pricing →

.adaguard.yml

Drop this file in your repo root to customise behaviour. All fields are optional — the app works with zero configuration.

.ADAGUARD.YML
# .adaguard.yml

# Scan this URL on every pull request instead of the detected preview.
# url: https://staging.your-site.com

# What the check's score counts (default wcag21-aa). A law (ada, section508,
# en301549, aoda, aca) or a WCAG version and level (wcag22-aa, wcag21-aaa ...).
# standard: wcag22-aa

# Make the check fail (Business and Enterprise). Off unless you set it.
# fail_on_score_below: 70
# fail_on_critical: true

# Leave these kinds of issues out of the comment and the check:
# color-contrast, missing-alt-text, form-labels, heading-structure,
# link-text, aria, keyboard — or an exact issue type from a result.
# ignore_rules:
#   - color-contrast

# Pages to scan per pull request (default 1, maximum 3).
max_pages: 1

# Scan this path of the preview, e.g. when its home page needs a login.
# The first entry is scanned on every pull request.
# public_pages:
#   - /pricing

# When a pull request has several deployments, scan the one matching this glob.
# scan_deployment_pattern: "web-*.vercel.app"
FieldTypeDefaultDescription
urlstringautoURL to scan on every pull request instead of the detected preview. The URL set in Settings → Integrations wins over this.
standardstringwcag21-aaWhat the check's score counts: ada, section508, en301549, aoda, aca, or a WCAG version and level (wcag22-aa). Findings beyond it are listed, not scored.
fail_on_score_belowint 0–100noneFail the check when the score is below this. Business and Enterprise.
fail_on_criticalboolfalseFail the check on any critical or serious issue within the standard. Business and Enterprise.
ignore_rulesstring[][]Leave these out of the comment and the check: color-contrast, missing-alt-text, form-labels, heading-structure, link-text, aria, keyboard, or an exact issue type. The score is unchanged.
max_pagesint 1–31Pages to scan per pull request. Values above 3 are capped at 3.
public_pagesstring[][]Paths of the preview to scan. The first is scanned on every pull request; when the preview asks for a login, they are tried in order.
scan_deployment_patternglobnoneWhen a pull request has several deployments, prefer the URL matching this pattern.
vercel_bypass_tokenstringnoneVercel Deployment Protection bypass secret. Better set in Settings → Integrations, where it is stored encrypted.
preview_basic_userstringnoneUsername for a preview behind HTTP Basic auth (for example Netlify or Render).
preview_basic_passwordstringnonePassword for that preview. Better set in Settings → Integrations.
cf_access_client_idstringnoneCloudflare Access service token client ID.
cf_access_client_secretstringnoneCloudflare Access service token secret. Better set in Settings → Integrations.

Custom URL

By default the App scans the preview it detects. To scan a different URL — your staging environment, production site or any other — set it in Settings → Integrations (“Scan this address instead”) or with the url field:

.ADAGUARD.YML
# Always scan this URL on every PR, regardless of deployment events
url: https://staging.your-site.com

This is useful when your repo doesn’t use a preview platform, when you want to scan a shared staging environment, or when you want to test production instead of the PR preview.

Protected Previews

If your previews are protected, the App reaches a login page instead of your app, and the comment says so. Give ADAGuard a way in, in Settings → Integrations → your repository → Preview protection, where it is stored encrypted:

  • Vercel Deployment Protection: the bypass secret (Vercel → your project → Settings → Deployment Protection).
  • HTTP Basic auth (for example Netlify or Render password protection): the username and password.
  • Cloudflare Access: a service token’s client ID and secret.
Don’t put these in .adaguard.yml in a shared repository: the App reads the file as it is, so GitHub secrets can’t be used there. If your app itself needs a login, scan a public page instead with public_pages, or set a public staging URL.

README Badge

Show the latest pull-request score in your README. The badge and a public report page update after each scan:

MARKDOWN
[![Accessibility](https://api.adaguard.io/badge/gh/OWNER/REPO/badge.svg)](https://www.adaguard.io/report/gh/OWNER/REPO)

Replace OWNER/REPO with your repository. The score is against WCAG 2.1 AA, so it means the same thing on every repository.

Troubleshooting

My PR was never scanned — no comment, no Check Run

  • Confirm the App can see this repository: on GitHub, Settings → GitHub Apps (organisation) or Settings → Applications → Installed GitHub Apps (personal account) → ADAGuard → Repository access.
  • If the comment says “sign in to keep scanning” or “upgrade to keep scanning”, this month’s 3 free pull requests are used: they start again on the 1st, or a paid plan scans every pull request.
  • If the check says “Scan skipped — rate limit reached”, the installation hit its hourly or daily cap; the next push after it resets scans again.
  • Check your private repository count against your plan (Free 1, Starter 2, Professional 5). The App says so in the comment when a repository isn't covered.
  • If your platform doesn't report previews (see Auto-detected Platforms above), put the preview URL in the description or set a custom URL.
  • Closed or merged pull requests are never scanned.

The comment says “ADAGuard: no preview to scan”

  • Your platform didn't report a preview. Paste the preview URL into the pull request description (e.g. “Preview: https://your-app.fly.dev”) and push again. Only previews on the platforms listed above are recognised there.
  • Or set a permanent URL: Settings → Integrations → your repository → Scan this address instead, or url: in .adaguard.yml.
  • This hint is posted once per repository.

The comment says the preview is behind a login

  • The preview answered with a login page, so the check is neutral and no score is given. Add your preview protection credentials (see Protected Previews above).
  • If your app itself asks for a login, set public_pages to a page anyone can see, or point the scan at a public staging or production URL.

The wrong deployment was scanned (e.g. my API instead of the frontend)

  • When a PR triggers multiple deployments, ADAGuard picks the most likely frontend URL. The "Tested" row in the PR comment shows which one.
  • To pin it, set a fixed url (Settings → Integrations or .adaguard.yml). scan_deployment_pattern: "frontend-*.vercel.app" helps too, but a scan started by one deployment's own event scans that deployment.

The same PR has a stale comment after I pushed a fix

  • ADAGuard updates its comment in place on every push. If it looks stale, the scan may have timed out (1-minute limit) — check the check status, then push again to retry.

Still stuck? Email support@adaguard.io with your repo name and PR link.

FAQ

Do I need an ADAGuard account?

Not to start. Free means 3 pull requests scanned a month, counted per GitHub account and per ADAGuard account, public or private repositories alike; new pushes to a pull request already counted are free. When they are used, the App posts one comment (sign in, or upgrade once you have) and scanning starts again on the 1st of the next month. Paid plans scan every pull request.

Does it work without a .adaguard.yml file?

Yes. The App finds the preview of each pull request on its own, and the check never fails unless you ask it to. Add .adaguard.yml (or use Settings → Integrations) to set the URL to scan, the standard, issues to ignore, or — on Business and up — when the check should fail.

Will it scan every push or just pull requests?

Pull requests only. It scans when a pull request is opened, updated or reopened, and again when its preview deployment reports success. Pushes to your main branch and closed or merged pull requests are not scanned.

Does the GitHub App use the same scan quota as the API?

No. The App is limited by private repositories (Free 1, Starter 2, Professional 5, Business and Enterprise unlimited), by 3 pull requests a month on Free, and by a per-installation cap of 20 scans an hour and 100 a day on Free (200 and 1,000 on paid plans) — not by the monthly scan count the API and dashboard use.

Can I get GitHub App scan results through the API?

Not today. The PR comment and Check Run are the only outputs of a GitHub App scan — those results aren't stored in a place GET /v1/scan or GET /v1/scans can read. If you need scan results back in your own tooling, use the API directly (see the API docs) instead of, or alongside, the App.