AZComply API Reference
The AZComply API gives you programmatic access to the world's only deterministic EU AI Act classification engine. Embed regulatory risk detection directly into your CI/CD pipelines, compliance workflows, or enterprise applications.
Two tiers: POST /v1/classify runs the pure Python engine in <100ms with no credits and no LLM. POST /v1/assess runs the full 9-agent LLM pipeline asynchronously for narrative analysis, action plans, and PDF-ready reports (1 credit per assessment).
/v1/classify
Sync · Free · <100ms · Engine only
/v1/assess
Async · 1 credit · ~60s · Full pipeline
API Keys
az_live_* / az_test_* · SHA-256 stored
Base URL
All requests must use HTTPS. HTTP connections will be refused.
Versioning
The API is versioned via URL path (/v1/). Breaking changes will be released under a new version prefix (e.g. /v2/) with a 12-month deprecation notice. The EU AI Act engine version is returned in every response as engine_version.
Authentication
The AZComply API uses API keys for authentication. Include your key in every request using the X-API-Key HTTP header.
Key Types
| Prefix | Type | Behaviour |
|---|---|---|
az_live_* | Live | Real classification, consumes credits on /v1/assess |
az_test_* | Sandbox | No LLM, no credits. /v1/assess returns deterministic mock result instantly |
Sandbox Mode
Use az_test_* keys in your development and CI/CD environment. Calls to POST /v1/assess return immediately with a deterministic result (no LLM, no background job, no credit cost). The sandbox: true flag is always set in sandbox responses.
Quick Start
Make your first API call in under 2 minutes.
1. Create a key
Go to Dashboard → API Keys and click Create key. The full key is shown once — store it in your secret manager (AWS Secrets Manager, GitHub Secrets, Vault, etc.).
2. Make your first call
Classify an AI system description. No credit consumed.
curl -X POST https://api.azcomply.eu/v1/classify \
-H "X-API-Key: az_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"description": "AI system that automatically ranks job applicants by scoring their CVs before human review",
"jurisdictions": ["FR"]
}'3. Interpret the response
{
"risk_code": "HIGH_RISK",
"ci_status": "block",
"gate_pass": false,
"verdict": {
"classification": "HIGH",
"obligations_count": 9,
"fine_exposure": "€15,000,000 or 3% of global annual turnover"
},
"compliance_deadline": "2027-12-02",
"engine_version": "current",
"classified_at": "2026-03-25T14:30:00Z"
}POST /v1/classify
/v1/classifyDeterministic classification · No credits · <100ms
Classifies an AI system against EU AI Act 2024/1689 using the deterministic Python engine. Zero LLM cost. Returns risk level, obligations count, FRIA requirement, fine exposure, and compliance deadline in under 100ms.
classify (included on all keys by default). This endpoint is free — the engine is pure Python and costs nothing to run.Request body
Two input modes — provide either description (free-text) or facts (structured).
Mode A — Free text
| Parameter | Type | Required | Description |
|---|---|---|---|
description | string | Required | Plain-text description of the AI system (10–14,000 chars)e.g. "CV ranking AI used in HR" |
system_name | string | Optional | Human-readable name for the systeme.g. "HireBot v2" |
jurisdictions | string[] | Optional | ISO-2 country codes. Loads national law context.e.g. ["FR", "BE"] |
Mode B — Structured facts
| Parameter | Type | Required | Description |
|---|---|---|---|
facts | object | Required | Pre-structured SystemFacts fields. Useful for CI/CD where you know the system properties.e.g. {"is_hr_tool": true, "operator_role": "DEPLOYER"} |
Response
curl -X POST https://api.azcomply.eu/v1/classify \
-H "X-API-Key: az_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"description": "AI system that automatically ranks job applicants by scoring their CVs before human review",
"jurisdictions": ["FR"]
}'{
"risk_code": "HIGH_RISK",
"ci_status": "block",
"gate_pass": false,
"verdict": {
"classification": "HIGH",
"obligations_count": 9,
"fine_exposure": "€15,000,000 or 3% of global annual turnover"
},
"compliance_deadline": "2027-12-02",
"engine_version": "current",
"classified_at": "2026-03-25T14:30:00Z"
}Response fields
| Parameter | Type | Required | Description |
|---|---|---|---|
risk_level | string | Required | PROHIBITED | HIGH_RISK | LIMITED_RISK | MINIMAL_RISK | GPAI | GPAI_SYSTEMIC | UNCODED |
operator_role | string | Required | PROVIDER | DEPLOYER | IMPORTER | DISTRIBUTOR |
annex_iii_category | string | null | Required | Matched Annex III category if HIGH_RISK, e.g. "Employment & HR — Annex III §4(a)" |
obligations_count | integer | Required | Number of EU AI Act obligations applicable to this system |
fria_required | boolean | Required | Whether a Fundamental Rights Impact Assessment is required (Art. 27) |
national_law_flags | string[] | Required | National law indicators detected, e.g. ["CAO_39_BE", "CNIL_FR"] |
compliance_deadline | string | null | Required | ISO 8601 date of applicable compliance deadline |
fine_exposure | object | Required | { max_tier: string, max_eur: integer } — maximum fine under EU AI Act |
gate_pass | boolean | Required | True only if no obligations detected (MINIMAL_RISK with no flags) |
engine_version | string | Required | Classification engine version from /v1/systems/engine-info |
sandbox | boolean | Required | True if request was made with an az_test_* key |
Structured mode (CI/CD)
Pass pre-extracted system properties as structured facts for deterministic results in automated pipelines:
curl -X POST https://api.azcomply.eu/v1/classify \
-H "X-API-Key: az_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"facts": {
"system_name": "CV Ranking Engine",
"system_description": "Scores and ranks job applicants",
"operator_role": "DEPLOYER",
"jurisdictions": ["FR"],
"is_hr_tool": true,
"employee_count": 250,
"uses_gpai_model": false
}
}'POST /v1/assess
/v1/assessFull 9-agent LLM pipeline · 1 credit · ~60s · Async 202
Runs the complete assessment pipeline: fact extraction, deterministic classification, 9 LLM personas (logic critic, FRIA advisor, action plan architect, report writer, etc.), and returns a full narrative with action plan. Returns 202 Accepted immediately with a job_id.
assess (not included by default — enable when creating your key). Cost: 1 credit, deducted only after the pipeline completes successfully.Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
description | string | Required | Plain-text description of the AI system (20–14,000 chars) |
language | string | Optional | Report language: en, fr, nl, de, it, es. Default: en |
jurisdictions | string[] | Optional | ISO-2 country codes for national law context |
webhook_url | string | Optional | HTTPS URL to receive classification.completed / classification.failed events |
webhook_secret | string | Optional | Secret for HMAC-SHA256 signature verification |
curl -X POST https://api.azcomply.eu/v1/assess \
-H "X-API-Key: az_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"description": "Document describing our AI-powered credit scoring system...",
"language": "en",
"jurisdictions": ["BE"],
"webhook_url": "https://hooks.yourcompany.com/azcomply",
"webhook_secret": "your-webhook-secret"
}'{
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "queued",
"poll_url": "/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6",
"estimated_seconds": 60
}Job polling
docs.assess.pollingDesc The Retry-After header tells you the recommended polling interval.
# Poll for completion (every 5 seconds)
curl https://api.azcomply.eu/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
-H "X-API-Key: az_live_YOUR_KEY"
# Fetch result once status == "completed"
curl https://api.azcomply.eu/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6/result \
-H "X-API-Key: az_live_YOUR_KEY"| Status | Meaning | Action |
|---|---|---|
queued | Job received, waiting for a worker | Wait, poll again |
processing | Pipeline running (LLM personas active) | Wait, poll again |
completed | All stages done, result available | Fetch /result |
failed | Pipeline error — error field contains details | Check error, retry |
Result
When status === completed, fetch the full result:
/v1/jobs/{job_id}/resultReturns full JSON report when job is completed
{
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"risk_level": "HIGH_RISK",
"operator_role": "DEPLOYER",
"obligations_count": 11,
"fria_required": true,
"national_law_flags": ["CAO_39_BE", "CAO_9_BE"],
"compliance_deadline": "2027-12-02",
"fine_exposure": { "max_tier": "TIER_2_HIGH_RISK", "max_eur": 15000000 },
"gate_pass": false,
"validation_score": 94,
"fallacy_flags": [],
"bias_flags": [],
"fria_analysis": "A Fundamental Rights Impact Assessment is required under Art. 27...",
"action_plan": "Phase 1 (0–3 months): Establish AI governance framework...",
"narrative": "This credit scoring system presents significant regulatory risk...",
"completed_at": "2026-03-25T14:31:03Z"
}POST /v1/workpapers
/v1/workpapersPaid markdown workpaper · 1 credit · Async 202 · API/MCP transport
Generates a paid-grade Markdown workpaper for headless API clients and MCP agents. It uses the same hosted QAE extraction, deterministic classification, credit reservation, job polling, and result retention flow as the paid API report path, but returns a machine-readable job result containing markdown instead of a PDF report artifact.
assess. Cost: 1 credit, finalized only after the workpaper completes successfully. Use Idempotency-Key on retries to avoid duplicate reservations.Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
description | string | Required | Plain-text description of the AI system (20-14,000 chars) |
system_name | string | Optional | Display name used in the generated workpaper |
jurisdictions | string[] | Optional | ISO-2 country codes for national law context |
brief_scope | auto | single | composite | portfolio | Optional | Use composite for independently operable component suites |
components | object[] | Optional | Component boundaries for composite-system workpapers |
include_coverage_overlay | boolean | Optional | Adds deterministic coverage matrix rows |
curl -X POST https://api.azcomply.eu/v1/workpapers \
-H "X-API-Key: az_live_YOUR_KEY" \
-H "Idempotency-Key: hospital-suite-2026-05-30" \
-H "Content-Type: application/json" \
-d '{
"system_name": "Hospital Operations Suite",
"description": "Integrated hospital AI suite with triage, scheduling, diagnostics, kiosk, and facilities components...",
"jurisdictions": ["BE"],
"brief_scope": "composite",
"components": [
{ "name": "Patient Triage", "description": "Assigns urgency scores and appointment priority" }
]
}'{
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "queued",
"poll_url": "/v1/jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6",
"estimated_seconds": 60
}Result
docs.workpapers.resultDesc
Webhooks
Configure a webhook URL on POST /v1/assess to receive real-time notifications when an assessment completes or fails. AZComply signs every delivery with HMAC-SHA256 — always verify the signature before processing.
Events
| Event | When | data fields |
|---|---|---|
classification.completed | Pipeline succeeded | job_id, risk_level, obligations_count, fria_required, compliance_deadline |
classification.failed | Pipeline failed (credit released) | job_id, error |
Headers on every delivery
Verify signature
Always verify the X-AZComply-Signature header before processing webhook payloads.
import hmac, hashlib, json
def verify_azcomply_signature(
body: bytes,
signature_header: str,
secret: str,
) -> bool:
"""
Verify X-AZComply-Signature header on incoming webhook.
signature_header looks like: sha256=<hex_digest>
"""
expected = "sha256=" + hmac.new(
key=secret.encode(),
msg=body,
digestmod=hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, signature_header)
# Flask example
from flask import Flask, request, abort
app = Flask(__name__)
WEBHOOK_SECRET = "your-webhook-secret"
@app.route("/webhook", methods=["POST"])
def handle_webhook():
sig = request.headers.get("X-AZComply-Signature", "")
if not verify_azcomply_signature(request.data, sig, WEBHOOK_SECRET):
abort(401)
payload = request.get_json()
event = payload["event"] # "classification.completed"
job_id = payload["data"]["job_id"]
risk_level = payload["data"]["risk_level"]
# ... handle event
return "", 200Retry logic
AZComply retries failed deliveries up to 3 times with exponential backoff: 2s → 4s → 8s. After 3 failed attempts the event is discarded — check your endpoint's availability. 4xx responses are not retried (treat as permanent failures on your end).
Key Management
Manage API keys via the REST API or the Dashboard. Key management endpoints use JWT bearer auth (your user session token) — not API key auth.
Create key
/v1/keysJWT auth · Creates key · Raw key returned ONCE
curl -X POST https://api.azcomply.eu/v1/keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "CI/CD Pipeline",
"scopes": ["classify", "assess"],
"sandbox": false
}'
# Response (key shown ONCE — store it now):
{
"key_id": "...",
"raw_key": "az_live_FULL_KEY_SHOWN_ONCE_STORE_NOW",
"key_prefix": "az_live_abcd...",
"name": "CI/CD Pipeline",
"scopes": ["classify", "assess"],
"sandbox": false,
"created_at": "2026-03-25T14:00:00Z",
"warning": "Store this key securely. It will not be shown again."
}List keys
/v1/keysJWT auth · Returns all keys for your account
curl https://api.azcomply.eu/v1/keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Revoke key
/v1/keys/{key_id}JWT auth · Immediate revocation · Idempotent
curl -X DELETE https://api.azcomply.eu/v1/keys/KEY_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Returns 204 No ContentErrors
| Code | Name | Meaning |
|---|---|---|
| 200 | OK | Request succeeded |
| 201 | Created | Resource created (POST /v1/keys) |
| 202 | Accepted | Job queued (POST /v1/assess) |
| 401 | Unauthorized | Missing, invalid, or revoked API key |
| 402 | Payment Required | Insufficient credits for /v1/assess |
| 403 | Forbidden | Key exists but lacks required scope |
| 404 | Not Found | Job ID not found or belongs to different key |
| 409 | Conflict | Job failed — error field contains details |
| 410 | Gone | Job expired (results retained 7 days) |
| 422 | Unprocessable | Validation error — missing required fields |
| 425 | Too Early | Job result not yet ready — retry after Retry-After seconds |
| 429 | Too Many Requests | Daily rate limit exceeded — see X-RateLimit-* headers |
| 500 | Server Error | Internal error — transient, retry with backoff |
Error format
All errors return a JSON body with a detail field:
// 401 Unauthorized
{
"detail": "Invalid or revoked API key."
}
// 402 Payment Required
{
"detail": "Insufficient credits. Purchase more at https://azcomply.eu/pricing"
}
// 422 Validation Error
{
"detail": "Provide either 'description' (free-text) or 'facts' (structured dict)."
}
// 429 Rate Limit
{
"detail": "Daily rate limit of 500 calls exceeded. Resets at midnight UTC.",
// Headers also set:
// Retry-After: 3600
// X-RateLimit-Limit: 500
// X-RateLimit-Remaining: 0
}Rate Limits
Rate limits are per API key, resetting daily at 00:00 UTC. The default limit is 500 calls/day. Monthly counters reset on the 1st of each month.
| Endpoint | Default daily limit | Notes |
|---|---|---|
POST /v1/classify | 500 / key / day | Free, engine-only. No credit cost. |
POST /v1/assess | 500 / key / day | Also credit-limited. Whichever is lower applies. |
GET /v1/jobs/* | 500 / key / day | Poll at ≤5 second intervals. |
Rate limit headers
Every response includes these headers:
Backoff strategy
If you receive a 429, wait the number of seconds in the Retry-After header before retrying.
import time, requests
def classify_with_backoff(description: str, api_key: str) -> dict:
for attempt in range(3):
r = requests.post(
"https://api.azcomply.eu/v1/classify",
headers={"X-API-Key": api_key},
json={"description": description},
)
if r.status_code == 429:
wait = int(r.headers.get("Retry-After", 60))
print(f"Rate limited. Retrying in {wait}s...")
time.sleep(wait)
continue
r.raise_for_status()
return r.json()
raise Exception("Rate limit exceeded after 3 attempts")Engine current · EU 2024/1689 · GDPR data residency: europe-west4
© 2026 AZComply — Detection tool, not legal advice.