The five endpoints
Free scan of a single page
POST https://inkluso.eu/api/scan/free
Free · 5 calls per hour per IP · homepage only
Checks the submitted address against WCAG 2.1 AA and maps the findings to the law selected by the lang field. The most severe violation comes back in full, with its legal reference; every other one appears in locked_violations as severity and instance count only.
- A call takes roughly 30 seconds: the server launches a real browser and renders the page. Set a client timeout of at least 60 seconds.
- The address must point at a public host. A missing scheme is completed to https://, and internal or loopback addresses are rejected with 422.
- The scan_status field is the scan's own diagnosis. "bot_challenge" means the target site's WAF blocked the scanner, that is not a good grade, it is no grade at all.
- Errors: 422 (invalid address, or nothing could be scanned), 429 (rate limit), 503 (scanner busy), 504 (scan exceeded the 300-second cap).
curl -sS -X POST https://inkluso.eu/api/scan/free \
-H 'Content-Type: application/json' \
--max-time 90 \
-d '{"url": "https://example.cz", "lang": "en"}'
Accessibility statement draft
POST https://inkluso.eu/api/statement/draft
Free · 20 calls per minute per IP · nothing is stored
Assembles a draft accessibility statement from the details you send. No scan runs, nothing is stored, no email is sent and no account is created. The response has two fields: statement (a structured object) and text (the same document as plain text for a CMS).
- conformance_status accepts only "partial", "none" or "not_assessed". "full" is deliberately not allowed: full conformance cannot be self-declared, only measured.
- known_issues takes at most 20 items of at most 300 characters each; longer input is trimmed, not rejected.
- The statement is the organisation's own declaration. Inkluso verifies none of the details, and the text says so explicitly.
- Errors: 422 (invalid address, empty organisation name, disallowed conformance_status, malformed email), 429 (rate limit).
curl -sS -X POST https://inkluso.eu/api/statement/draft \
-H 'Content-Type: application/json' \
-d '{"organisation": "Vzor s.r.o.",
"url": "https://example.cz",
"lang": "en",
"conformance_status": "partial",
"known_issues": ["Two PDFs published before 2024 are not tagged."]}'
Order status
GET https://inkluso.eu/api/orders/{ref}
Free · 30 calls per hour per IP · every response carries X-Robots-Tag: noindex
Resolves an order reference to its fulfilment state, and once that finishes, to the report's address. The reference is minted when the order is created and is not the report token, that does not exist until fulfilment completes.
- 404 {"detail": "Order not found"}: no such reference; stop asking.
- 202 {"status": "pending"}: the order exists, fulfilment is still running.
- 200 {"status": "fulfilled", "report_url": "/api/reports/{token}"}: done.
- Fulfilment runs a scan of the whole site and renders a PDF, so count in minutes. At 30 calls per hour the practical ceiling is one poll every two minutes; one poll every five minutes is a safe pattern.
curl -sS -i https://inkluso.eu/api/orders/9f2c1d7a8b6e4f0c
HTTP/2 202
x-robots-tag: noindex
{"status": "pending"}
Buy an audit, or start monitoring
POST https://inkluso.eu/api/billing/checkout
Paid · 10 calls per minute per IP
Creates a Stripe Checkout session and returns its URL. Payment itself happens on Stripe, not here: no card details are ever sent to this endpoint. tier selects the product: scan_report is the one-time audit (from EUR 149 or the currency equivalent); monitor / monitor_annual is the recurring monitoring subscription; agency is contact-led (its price here is a floor anchor, not the marketed rate, use the sales-led flow instead); shoptet_audit is the one-time Shoptet e-shop audit (EUR 99 / 2 490 Kč / 449 zł; settlement currency follows lang).
- consent must be true. This is a legal requirement, not a formality: the purchased tier is digital content/service delivered immediately, so the buyer must expressly waive the 14-day EU right of withdrawal. false or omitted returns 422 and no order is created. Do not send true on a human's behalf without their actual agreement.
- The settlement currency follows lang: cs settles in CZK, pl in PLN, every other language (de, en) in EUR. This is not a converted figure, each currency has its own price list. The single source of truth is price_for_tier() in backend.billing.stripe.
- An optional Idempotency-Key header: generate a fresh, unique value yourself for EVERY purchase intent (e.g. a UUID v4). The key is bound to your exact request (email, url, tier, lang): a repeat with the SAME request within 24 hours replays the SAME order_ref, checkout_url, amount and currency; the same key with DIFFERENT details returns 422. A key reused mid-flight returns 503, retry shortly. Never copy a key from documentation or from another request.
- Errors: 422 (consent not true, invalid URL, or a missing/malformed field), 429 (rate limit), 503 (Idempotency-Key already in progress, or the payment provider is temporarily misconfigured), 500 (payment system unavailable).
curl -sS -X POST https://inkluso.eu/api/billing/checkout \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: ' \
-d '{"email": "buyer@example.cz", "tier": "scan_report",
"url": "https://example.cz", "lang": "en", "consent": true}'
Then poll GET /api/orders/{order_ref} above until it resolves to "fulfilled".