Start here

Run your first URL preflight

This quickstart creates a URL scan, waits for a terminal state, and evaluates the accessibility result separately from the release check.

Before you start

In the AccessPreflight console, create a project and a project API key with these scopes:

  • scans:write
  • scans:read
  • reports:read
  • profiles:read

Use a test-environment key while integrating. The complete secret is shown once.

export ACCESSPREFLIGHT_API_KEY='ap_test_REPLACE_ME'

Never commit the key or expose it in browser code.

Every API key is bound to one project when it is created. Requests made with that key inherit the project automatically, so API-key integrations must not send project_id. Supplying the matching ID remains accepted for older clients; a different project returns 404.

The reference documents only the accessibility integration endpoints available to project API keys. Account setup, organizations, projects, API-key issuance, and billing are managed in the console and are intentionally omitted.

1. Select a compatible profile

Profiles are immutable and asset-specific. List the currently available versions instead of copying a version from an old example.

curl --fail-with-body \
  --request GET \
  --url 'https://api.accesspreflight.com/v1/profiles' \
  --header "Authorization: Bearer ${ACCESSPREFLIGHT_API_KEY}"

For a website, select an active profile whose asset_types includes url. Pin a concrete version for reproducible CI. latest is convenient for exploration but can resolve differently after a registry update.

2. Create the scan

Every create request needs an idempotency key. Generate a new one for a new logical operation and reuse it only when retrying the exact same request.

IDEMPOTENCY_KEY="$(uuidgen)"

curl --fail-with-body \
  --request POST \
  --url 'https://api.accesspreflight.com/v1/scans' \
  --header "Authorization: Bearer ${ACCESSPREFLIGHT_API_KEY}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
  --data "{
    \"environment\": \"test\",
    \"asset\": {
      \"type\": \"url\",
      \"url\": \"https://example.com\",
      \"viewport\": \"desktop\",
      \"wait\": {
        \"strategy\": \"dom_ready\",
        \"timeout_ms\": 15000
      }
    },
    \"profiles\": [\"wcag-2.2-aa-web@1.2.0\"],
    \"options\": {
      \"include_repair_plan\": true,
      \"include_screenshots\": false
    }
  }"

The API returns 202 Accepted and a scan object. Save its id; accepting the request does not mean the scan is complete.

3. Poll with bounded backoff

Use the links.self value from the response. Poll every two seconds at first, then back off to a maximum interval such as ten seconds. Stop after your own bounded deadline.

curl --fail-with-body \
  --request GET \
  --url "https://api.accesspreflight.com/v1/scans/${SCAN_ID}" \
  --header "Authorization: Bearer ${ACCESSPREFLIGHT_API_KEY}"

Terminal success is status: completed. Terminal failures include rejected, fetch_failed, unsupported, timed_out, engine_failed, and cancelled. Do not poll a terminal scan forever.

For event-driven systems, use a signed webhook and keep occasional polling as reconciliation.

4. Make the right decision

After status is completed:

  1. Check result. incomplete is not a clean result.
  2. Check quality_gate.status only if you configured a gate.
  3. Read /findings for remediation records.
  4. Read /coverage for checks that did not run and manual work still required.
curl --fail-with-body \
  --url "https://api.accesspreflight.com/v1/scans/${SCAN_ID}/findings?limit=100" \
  --header "Authorization: Bearer ${ACCESSPREFLIGHT_API_KEY}"

curl --fail-with-body \
  --url "https://api.accesspreflight.com/v1/scans/${SCAN_ID}/coverage" \
  --header "Authorization: Bearer ${ACCESSPREFLIGHT_API_KEY}"

5. Download an Excel report

The XLSX export is designed for triage and handoff to product, engineering, content, and accessibility reviewers.

curl --fail-with-body \
  --url "https://api.accesspreflight.com/v1/scans/${SCAN_ID}/reports/xlsx" \
  --header "Authorization: Bearer ${ACCESSPREFLIGHT_API_KEY}" \
  --output "accesspreflight-${SCAN_ID}.xlsx"

Continue with quality gates before making scan results block a production deployment.

Search documentation