Docs
Claude — API and Custom Connector integration

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:

  1. REST API — `X-API-Key` against `https://api.accessio.ai/v1\`. Server-side scripts, CI jobs, dashboards.
  2. Claude API with mcp_servers — server-to-server. Claude calls Accessio.AI tools on behalf of your backend.
  3. 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:

ScopeWhat it allows
scans:readList scan sessions and their issues
scans:writeRun new scans (spends AI credits)
alt-text:readList generated alt-text suggestions
alt-text:approveApprove / reject alt-text suggestions
embed:readInspect embed scripts (token / tokenHash never returned)
quota:readCheck current-month usage
org:readRead 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-Id response 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):

ToolScopeSide effects
list_scansscans:readRead-only
get_scanscans:readRead-only
list_alt_textalt-text:readRead-only
get_quotaquota:readRead-only
list_embed_scriptsembed:readRead-only
run_scanscans:writeSpends AI credits, fetches the merchant page over the public web
approve_alt_textalt-text:approveMutates the alt-text — visible to merchant shoppers on next page load
reject_alt_textalt-text:approveMutates 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.

  1. 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.
  2. Click Connect. Claude opens a popup to https://auth.accessio.ai/oauth2/auth with PKCE.
  3. Sign in to Accessio.AI (or create an account). Pick the organization to grant access for. Review the scope list. Click Allow access.
  4. 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_token is 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:read cannot 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 exceeded and back off using the Retry-After header.
  • 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, and Link: 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

SymptomCauseFix
401 Bearer realm="accessio.ai", error="invalid_token" on REST or MCPToken expired (1h TTL) or signature failedRe-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.aiToken has empty aud and your client validates strictlyKnown 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: arrayCaller granted some but not all required scopesRe-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 matchThe OAuth client registered a different callback URL than what claude.ai sendsAllowlist 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-inEmail-based User exists but no Google/Microsoft OAuth account is linked yetSign in with the OAuth provider whose email matches the User; auto-link is enabled.

Rate limits

SymptomCauseFix
429 Rate limit exceeded with Retry-After headerPer-key 60 req/min ceilingBack off using the Retry-After value. For higher throughput, contact support — production tier raises the cap.
too_many_failed_auths 429 with Retry-After: 60More than 30 failed authentications from your /24 subnet in a minuteBrute-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 envelopeMeaning
not_foundThe id isn't owned by your organization (or doesn't exist). We don't distinguish between the two — preventing cross-tenant existence leaks.
invalid_cursorThe 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_decidedTried 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_failedTransient DB error during audit write. Retry the call; the underlying mutation rolled back so it's safe to retry.
upstream_error with upstreamStatusaccessio-service (the Java AI backend) rejected or timed out. The MCP call is safe to retry.

Connector setup in claude.ai

SymptomFix
Connector shows "not connected" after Allow accessPop-up blocker swallowed the callback. Disable the blocker for claude.ai and re-add the connector.
OAuth popup loops on dashboard sign-inExisting dashboard cookie expired. Open dashboard.accessio.ai in the same browser, sign in there, then retry the connector add.
Tool calls return empty dataThe 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

SymptomFix
Deprecation and Sunset response headersThe route is scheduled for retirement. Migrate to the path indicated by Link: rel="successor-version" before the Sunset date.
429 on /oauth2/registerAnti-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:

  1. The X-Request-Id from the failing response
  2. A timestamp (UTC) of when the error happened
  3. The HTTP method + URL, or the MCP tools/call name + arguments (redact sensitive fields)

We'll locate the exact call in the audit log within minutes.

OpenAPI spec

Claude — API and Custom Connector integration | AccessioAI