Claude — API and Custom Connector integration
Give Claude direct access to Accessio.AI accessibility data — via the Anthropic Messages API (server-to-server) or a Custom Connector inside claude.ai (OAuth 2.1).
Use Accessio.AI from Claude
Three integration paths, ordered from least to most setup:
- REST API — `X-API-Key` against `https://api.accessio.ai/v1\`. Server-side scripts, CI jobs, dashboards.
- Claude API with
mcp_servers— server-to-server. Claude calls Accessio.AI tools on behalf of your backend. - Custom Connector in claude.ai (OAuth 2.1) — end-user-facing. Each user authorizes Accessio.AI inside Claude with their own scopes; tokens scope to their organization.
All three speak the same MCP tool surface and audit log on the Accessio.AI side.
1. Create a service-account API key
In the dashboard, go to Settings → API keys, create a new key, and grant the scopes you need:
| Scope | What it allows |
|---|---|
scans:read | List scan sessions and their issues |
scans:write | Run new scans (spends AI credits) |
alt-text:read | List generated alt-text suggestions |
alt-text:approve | Approve / reject alt-text suggestions |
embed:read | Inspect embed scripts (token / tokenHash never returned) |
quota:read | Check current-month usage |
org:read | Read organization name and contact details |
Keys are hashed at rest; the plaintext is shown once. Store it in your secret manager as ACCESSIO_API_KEY.
2. Call the REST API directly
curl -H "X-API-Key: $ACCESSIO_API_KEY" \
"https://api.accessio.ai/v1/scans?limit=20"Response:
{
"success": true,
"data": [
{
"id": "…",
"embedScriptId": "…",
"pageUrl": "https://example.com/",
"totalIssues": 4,
"criticalCount": 1,
"seriousCount": 2,
"moderateCount": 1,
"minorCount": 0,
"scanDurationMs": 1234,
"createdAt": "2026-04-17T12:34:56.000Z"
}
],
"metadata": { "limit": 20, "nextCursor": null },
"disclaimer": "Automated WCAG scan. Not a legal compliance certification.",
"scanSchemaVersion": "1.0.0"
}Every response carries:
disclaimer— the scan is automated and not a legal compliance certification.scanSchemaVersion— semver of the scan output schema; agents that cache results must revalidate on change.X-Request-Idresponse header — pass it back on support requests to locate the exact call in our audit log.
Paginate with ?cursor=<last-id>&limit=<n>. Maximum limit is 100.
3. Let Claude call the API for you
The Anthropic Messages API can invoke accessio.ai tools via mcp_servers. Your API key goes in authorization_token; Claude treats it as a Bearer token on the MCP transport.
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: mcp-client-2025-11-20" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-4-7",
"max_tokens": 1024,
"mcp_servers": [{
"type": "url",
"url": "https://mcp.accessio.ai",
"name": "accessio",
"authorization_token": "'"$ACCESSIO_API_KEY"'"
}],
"messages": [{
"role": "user",
"content": "List our 10 most recent accessibility scans and summarize the critical issues."
}]
}'Tool surface (admin tier):
| Tool | Scope | Side effects |
|---|---|---|
list_scans | scans:read | Read-only |
get_scan | scans:read | Read-only |
list_alt_text | alt-text:read | Read-only |
get_quota | quota:read | Read-only |
list_embed_scripts | embed:read | Read-only |
run_scan | scans:write | Spends AI credits, fetches the merchant page over the public web |
approve_alt_text | alt-text:approve | Mutates the alt-text — visible to merchant shoppers on next page load |
reject_alt_text | alt-text:approve | Mutates the row to REJECTED status (no deletion) |
Each tool's complete metadata (annotations, scopes, JSON schema) is at https://mcp.accessio.ai/.well-known/mcp.json.
4. Add Accessio as a Custom Connector in claude.ai (OAuth 2.1)
End-user-facing flow. Each Claude user authorizes Accessio.AI inside their own claude.ai session; tokens are scoped to whichever organization they pick at consent time.
- In claude.ai → Settings → Connectors → Add custom connector, paste:
- Server URL:
https://mcp.accessio.ai/mcp - The connector auto-discovers the OAuth authorization server via
https://mcp.accessio.ai/.well-known/oauth-protected-resource.
- Server URL:
- Click Connect. Claude opens a popup to
https://auth.accessio.ai/oauth2/authwith PKCE. - Sign in to Accessio.AI (or create an account). Pick the organization to grant access for. Review the scope list. Click Allow access.
- Claude exchanges the auth code for an access token in the background. The connector is now wired.
The connector uses Dynamic Client Registration (RFC 7591), so no manual client setup is needed. The OAuth flow uses PKCE (RFC 7636) and resource indicators (RFC 8707) — tokens are bound to either https://mcp.accessio.ai or https://api.accessio.ai, never replayable across them.
5. Example prompts that work end-to-end
Once the connector is enabled (or mcp_servers is configured in your API call), these prompts exercise the tool surface. They're the same prompts Anthropic's review uses to validate the directory listing.
Example 1 — Triage the alt-text review queue
"Show me all alt-text suggestions still pending review on my Accessio.AI account, then approve any that look reasonable for product images and reject anything decorative."
Claude will: call list_alt_text with status=PENDING → loop the rows → call approve_alt_text or reject_alt_text per row, choosing a reason for rejections (typically DECORATIVE or BRAND_SPECIFIC).
Expected outcome: a summary of how many were approved/rejected and why.
Example 2 — Re-scan after a deploy
"My team just shipped a fix for the colour-contrast issues on our pricing page. Re-run the most recent scan for that page and tell me if the issues are resolved."
Claude will: call list_scans to find the pricing-page scan → call run_scan with that scan id and an idempotency key → wait briefly → call get_scan to read the new issue counts → compare and explain.
Expected outcome: a before/after on critical issue counts plus any remaining issues.
Example 3 — Plan-usage check before a bulk operation
"Before I have you process all the alt-text on my newest store, check how much quota I have left this month and warn me if it's tight."
Claude will: call get_quota → compare remaining to the size of the pending queue (from list_alt_text) → warn if the bulk job would exceed quota.
Expected outcome: a clear "you have N credits remaining, the queue is M rows, here's what I'd recommend" decision aid.
Example 4 — Multi-store inventory
"List every site on my Accessio.AI account that has the widget installed, and for each one show the most recent scan's critical issue count."
Claude will: call list_embed_scripts → for each row, call list_scans with that embedScriptId filter → return a table of site → most-recent-scan critical-issue count.
Expected outcome: a portfolio view of your sites' accessibility posture.
6. Security notes
⚠️ Never paste your API key into a chat prompt. Keys go in environment variables on your server, in CI secrets, or in a secret manager. A key dropped into a Claude/ChatGPT conversation may be logged, cached, or trained on — treat it as leaked the moment it reaches a prompt.
- Do not ship the key to a browser. The
mcp_servers.authorization_tokenis a server-to-server secret. Use a backend proxy if your frontend needs scan data. - Rotate on leak. Revoke in the dashboard; Accessio supports a 30-day dual-active window so rotation does not break live Claude sessions.
- Scope narrowly. Keys issued with only
scans:readcannot invoke writes, even if Claude is tricked by a prompt-injected product title. - Rate limited. Each key is capped at 60 requests/minute per route in v1 (Phase 2 raises this and adds per-tool weights). Watch for
429 Rate limit exceededand back off using theRetry-Afterheader. - IP privacy. We coarsen client IPs (IPv4 → /24, IPv6 → /48) before they land in the audit log.
- Audit log. Every tool call and REST call is recorded with
principalId,organizationId,action,requestId, and a SHA-256 hash of the arguments. Raw arguments are never stored; audit rows are retained for 90 days by default. - Deprecation. When a route is scheduled for retirement we set
Deprecation,Sunset, andLink: rel="successor-version"response headers per RFC 8594. Agents that cache responses must honor these.
7. Troubleshooting
Common errors and what to do about them. Every response carries an X-Request-Id header — include it in any support email so we can locate the exact call in our audit log.
Authentication
| Symptom | Cause | Fix |
|---|---|---|
401 Bearer realm="accessio.ai", error="invalid_token" on REST or MCP | Token expired (1h TTL) or signature failed | Re-run the OAuth flow. For long-lived sessions, request offline_access scope and use the refresh token. |
401 immediately after adding the connector in claude.ai | Token has empty aud and your client validates strictly | Known Hydra v26 issue. Resolved on the Accessio side; if you see this from a third-party MCP client, file an issue. |
403 insufficient_scope with a required: array | Caller granted some but not all required scopes | Re-issue the API key with the missing scope, or re-grant via OAuth and tick the missing scope on the consent screen. |
Browser redirects to /oauth/error?error=invalid_request&...redirect_uri does not match | The OAuth client registered a different callback URL than what claude.ai sends | Allowlist BOTH https://claude.ai/api/mcp/auth_callback AND https://claude.com/api/mcp/auth_callback on the OAuth client. Both are required. |
OAuthAccountNotLinked on dashboard sign-in | Email-based User exists but no Google/Microsoft OAuth account is linked yet | Sign in with the OAuth provider whose email matches the User; auto-link is enabled. |
Rate limits
| Symptom | Cause | Fix |
|---|---|---|
429 Rate limit exceeded with Retry-After header | Per-key 60 req/min ceiling | Back off using the Retry-After value. For higher throughput, contact support — production tier raises the cap. |
too_many_failed_auths 429 with Retry-After: 60 | More than 30 failed authentications from your /24 subnet in a minute | Brute-force protection. Pause a minute; if persistent, check that the API key isn't truncated or quoted. |
MCP tool errors
error.code in the JSON-RPC envelope | Meaning |
|---|---|
not_found | The id isn't owned by your organization (or doesn't exist). We don't distinguish between the two — preventing cross-tenant existence leaks. |
invalid_cursor | The cursor you passed isn't a row your org owns. Re-fetch the page without a cursor and use the nextCursor value from the response. |
already_decided | Tried to approve/reject an alt-text row whose status is no longer PENDING. Pick another row from list_alt_text filtered by status=PENDING. |
audit_write_failed | Transient DB error during audit write. Retry the call; the underlying mutation rolled back so it's safe to retry. |
upstream_error with upstreamStatus | accessio-service (the Java AI backend) rejected or timed out. The MCP call is safe to retry. |
Connector setup in claude.ai
| Symptom | Fix |
|---|---|
| Connector shows "not connected" after Allow access | Pop-up blocker swallowed the callback. Disable the blocker for claude.ai and re-add the connector. |
| OAuth popup loops on dashboard sign-in | Existing dashboard cookie expired. Open dashboard.accessio.ai in the same browser, sign in there, then retry the connector add. |
| Tool calls return empty data | The org you selected at consent has no scans / alt-text / embed scripts yet. Install the widget on a site, run a scan, then retry. |
Other
| Symptom | Fix |
|---|---|
Deprecation and Sunset response headers | The route is scheduled for retirement. Migrate to the path indicated by Link: rel="successor-version" before the Sunset date. |
429 on /oauth2/register | Anti-abuse rate limit on Dynamic Client Registration (5/min, burst 10). Legitimate clients register once and reuse credentials; if you hit this, you're re-registering more than necessary. |
Still stuck?
Email [email protected] with:
- The
X-Request-Idfrom the failing response - A timestamp (UTC) of when the error happened
- The HTTP method + URL, or the MCP
tools/callname + arguments (redact sensitive fields)
We'll locate the exact call in the audit log within minutes.
OpenAPI spec
- Machine-readable: api.accessio.ai/v1/openapi.json
- Interactive explorer: api.accessio.ai