Skip to main content
AZComply API Reference
v1Last updated 2026-03-25

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

https://api.azcomply.eu/v1

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.

X-API-Key: az_live_YOUR_SECRET_KEY
⚠️
Keep your API key secret. Never expose it in client-side code, public repos, or logs. If compromised, revoke it immediately in the Dashboard → API Keys.

Key Types

PrefixTypeBehaviour
az_live_*LiveReal classification, consumes credits on /v1/assess
az_test_*SandboxNo 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

Response · JSON
{
  "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"
}
gate_pass: false means the system has unmet obligationsuse obligations_count and fine_exposure to prioritise remediation. Run POST /v1/assess for the full action plan narrative.

POST /v1/classify

POST
/v1/classify

Deterministic 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.

💡
Scope required: 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

ParameterTypeRequiredDescription
descriptionstringRequiredPlain-text description of the AI system (10–14,000 chars)e.g. "CV ranking AI used in HR"
system_namestringOptionalHuman-readable name for the systeme.g. "HireBot v2"
jurisdictionsstring[]OptionalISO-2 country codes. Loads national law context.e.g. ["FR", "BE"]

Mode B — Structured facts

ParameterTypeRequiredDescription
factsobjectRequiredPre-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"]
  }'
Response · JSON
{
  "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

ParameterTypeRequiredDescription
risk_levelstringRequiredPROHIBITED | HIGH_RISK | LIMITED_RISK | MINIMAL_RISK | GPAI | GPAI_SYSTEMIC | UNCODED
operator_rolestringRequiredPROVIDER | DEPLOYER | IMPORTER | DISTRIBUTOR
annex_iii_categorystring | nullRequiredMatched Annex III category if HIGH_RISK, e.g. "Employment & HR — Annex III §4(a)"
obligations_countintegerRequiredNumber of EU AI Act obligations applicable to this system
fria_requiredbooleanRequiredWhether a Fundamental Rights Impact Assessment is required (Art. 27)
national_law_flagsstring[]RequiredNational law indicators detected, e.g. ["CAO_39_BE", "CNIL_FR"]
compliance_deadlinestring | nullRequiredISO 8601 date of applicable compliance deadline
fine_exposureobjectRequired{ max_tier: string, max_eur: integer } — maximum fine under EU AI Act
gate_passbooleanRequiredTrue only if no obligations detected (MINIMAL_RISK with no flags)
engine_versionstringRequiredClassification engine version from /v1/systems/engine-info
sandboxbooleanRequiredTrue 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

POST
/v1/assess

Full 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.

💡
Scope required: assess (not included by default — enable when creating your key). Cost: 1 credit, deducted only after the pipeline completes successfully.

Request body

ParameterTypeRequiredDescription
descriptionstringRequiredPlain-text description of the AI system (20–14,000 chars)
languagestringOptionalReport language: en, fr, nl, de, it, es. Default: en
jurisdictionsstring[]OptionalISO-2 country codes for national law context
webhook_urlstringOptionalHTTPS URL to receive classification.completed / classification.failed events
webhook_secretstringOptionalSecret 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"
  }'
Response · JSON
{
  "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"
StatusMeaningAction
queuedJob received, waiting for a workerWait, poll again
processingPipeline running (LLM personas active)Wait, poll again
completedAll stages done, result availableFetch /result
failedPipeline error — error field contains detailsCheck error, retry

Result

When status === completed, fetch the full result:

GET
/v1/jobs/{job_id}/result

Returns full JSON report when job is completed

Response · JSON
{
  "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

POST
/v1/workpapers

Paid 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.

💡
Scope required: assess. Cost: 1 credit, finalized only after the workpaper completes successfully. Use Idempotency-Key on retries to avoid duplicate reservations.

Request body

ParameterTypeRequiredDescription
descriptionstringRequiredPlain-text description of the AI system (20-14,000 chars)
system_namestringOptionalDisplay name used in the generated workpaper
jurisdictionsstring[]OptionalISO-2 country codes for national law context
brief_scopeauto | single | composite | portfolioOptionalUse composite for independently operable component suites
componentsobject[]OptionalComponent boundaries for composite-system workpapers
include_coverage_overlaybooleanOptionalAdds 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" }
    ]
  }'
Response · JSON
{
  "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

EventWhendata fields
classification.completedPipeline succeededjob_id, risk_level, obligations_count, fria_required, compliance_deadline
classification.failedPipeline failed (credit released)job_id, error

Headers on every delivery

X-AZComply-Signature: sha256=<HMAC-SHA256(body, secret)>
X-AZComply-Event: classification.completed
X-AZComply-Timestamp: 1711365000
Content-Type: application/json

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 "", 200

Retry 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).

⚠️
Your endpoint must respond within 10 seconds. Return 200 immediately and process the payload asynchronously — never perform slow operations synchronously in the webhook handler.

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

POST
/v1/keys

JWT auth · Creates key · Raw key returned ONCE

⚠️
The raw key is returned only once in the create response and never stored. Store it in a secrets manager immediately — it cannot be retrieved again.
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

GET
/v1/keys

JWT auth · Returns all keys for your account

curl https://api.azcomply.eu/v1/keys \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Revoke key

DELETE
/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 Content

Errors

CodeNameMeaning
200OKRequest succeeded
201CreatedResource created (POST /v1/keys)
202AcceptedJob queued (POST /v1/assess)
401UnauthorizedMissing, invalid, or revoked API key
402Payment RequiredInsufficient credits for /v1/assess
403ForbiddenKey exists but lacks required scope
404Not FoundJob ID not found or belongs to different key
409ConflictJob failed — error field contains details
410GoneJob expired (results retained 7 days)
422UnprocessableValidation error — missing required fields
425Too EarlyJob result not yet ready — retry after Retry-After seconds
429Too Many RequestsDaily rate limit exceeded — see X-RateLimit-* headers
500Server ErrorInternal error — transient, retry with backoff

Error format

All errors return a JSON body with a detail field:

Response · JSON
// 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.

EndpointDefault daily limitNotes
POST /v1/classify500 / key / dayFree, engine-only. No credit cost.
POST /v1/assess500 / key / dayAlso credit-limited. Whichever is lower applies.
GET /v1/jobs/*500 / key / dayPoll at ≤5 second intervals.

Rate limit headers

Every response includes these headers:

X-RateLimit-Limit: 500
X-RateLimit-Remaining: 342
Retry-After: 3600 # only on 429

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.

API Reference - AZComply