# AISA Verify API — for publishers and edge gateways (CDN / ESA integrators) > You run a CDN edge, gateway, or publisher backend and want AISA to decide, per request, > whether a crawler may access a resource (free / paid / blocked) — and to handle the billing. > Paths relative to this host (test: https://esa.aisa.one, production: https://cdn.aisa.one). > Full docs+playground: /cdn/docs.html · 12-return-value test matrix: /cdn/cdntest.html · Gateway test skill: /cdn/skill.md > Crawler-side docs live separately: /agent/llms.txt and /agent/docs.html. ## The one call POST /api/v1/access/verify Authorization: Bearer ← server-to-server gateway auth (issued out-of-band by AISA) X-AISA-Crawler-Token: ← forward the crawler's token verbatim (if it sent one) X-ESA-Original-Crawler-Agent: ← always forward; gateways rewrite User-Agent Content-Type: application/json { "publisherDomain": "", "resourceUrl": "/path/of/requested/resource", "crawlerAutoPrice": true, "crawlerAgent": "" } Response — minimal integration reads ONE field: accessGranted: true → serve the content (fetch from origin / cache) accessGranted: false → do not serve; return statusCode + body to the crawler Rich fields: statusCode (200/400/401/402/403/500), error (machine-readable), price, currency, charged/chargeAmount, crawler{balance,shortfall}, rule{urlPattern,accessMode,price}, crawlerIdentification{recognized,identifier,verified,signed}, onboarding, guidance (bot self-service instructions). GET /api/v1/access/verify returns a machine-readable self-description of all parameters and codes. ## Two independent auth layers | Layer | Header | Failure | |---------|-------------------------------------|---------| | Gateway | Authorization: Bearer | 401 gateway_unauthorized | | Crawler | X-AISA-Crawler-Token (or body crawlerToken) | 402 invalid_token | Never put a crawler token in Authorization: Bearer — that slot belongs to the gateway layer. ## Decision semantics (first-match-wins publisher rules) - block → 403 access_blocked (regardless of token/balance). Render your own block page; AISA returns JSON only. - allow → 200 free (no token required). - pay → requires valid crawler token; with crawlerAutoPrice:true and sufficient balance → 200 + charge; no token → 402 invalid_token; low balance → 402 insufficient_balance (+crawler.shortfall); no price intent → 402 price_required (+price quote). - no rule matched → 200 default allow (not charged). - Billing is per-request. URL query strings are stripped before rule matching. ## All 12 return values (assert coverage: /cdn/cdntest.html) 200 allow-rule · 200 no-rule-default-allow · 200 paid-and-charged · 402 invalid_token · 402 insufficient_balance · 402 price_required · 402 price_mismatch · 402 price_too_high · 400 invalid_price_format · 403 access_blocked · 401 gateway_unauthorized · 500 internal_error ## On denial, pass the body through The 402/403 JSON contains `onboarding` and a `guidance` block that teach the crawler to register, fund a balance (possibly a signup trial credit), and retry with X-AISA-Crawler-Token. Deliver that JSON to the crawler unmodified — it is how new crawlers convert into paying ones. ## Publisher self-service - Register/login: /cdn/login.html · Rules UI: /cdn/content-controls.html - Auto-discover pricing from your site: POST /api/publisher/discover (reads your pricing.json or sitemap) - Bulk import rules: POST /api/publisher/rules/bulk-import