Two regions. Your API key says which one to call.
EU, Frankfurt
https://eu.api.complyedge.io
Key starts with ce_eu_. Use it when your contracts or customers want data kept in the EU. Preselected at sign-up.
US, Oregon
https://api.complyedge.io
Key starts with ce_. Use it when your contracts or customers want data kept in the US.
You choose the region when you create your free API key: the sign-up form asks where your data is stored, EU or US. The SDK reads the key and calls the right host. With curl or your own client, call the host of your key's region; a key sent to the other region is rejected. The region is where your prompts and audit records are processed and stored. It does not change which laws are checked: the jurisdiction field on each check does. No general law requires either region. US law does not require US storage, and GDPR allows transfers outside the EU with safeguards such as standard contractual clauses (Chapter V). The examples below use the EU host; with a US key, use api.complyedge.io instead.
Every check names its jurisdiction; the loaded rule bundle today runs EU AI Act rules (Article 5 and related), prompt-injection rules and, for US end users, SOX §302, and the same call shape carries other jurisdictions as their rule sets ship.
Authenticated endpoints expect a Bearer token in the Authorization header (API key or, where noted, a dashboard JWT session):
Authorization: Bearer ce_live_your_api_key
No auth: GET /health, GET /v1/public/trust/{slug}, and GET /v1/public/badge/{slug}.svg.
Don't have a key yet? Sign in to the dashboard (free, email OTP).
/health
Readiness check. Returns 200 only when OPA and TrustLint can evaluate; anything else is 503. No auth required.
Response 200
{
"status": "healthy",
"version": "0.1.0",
"commit": "a1b2c3d",
"timestamp": "2026-06-20T00:00:00Z",
"services": {
"database": { "status": "healthy", "service": "audit_logger", "database": "dynamodb" },
"trustlint": { "engine": "trustlint", "healthy": true, "rules_loaded": 64 },
"opa": true,
"enhanced_compliance_engine": true,
"rule_manager": true
}
}
Response 503
{
"status": "unhealthy",
"version": "0.1.0",
"commit": "a1b2c3d",
"timestamp": "2026-06-20T00:00:00Z",
"services": { "database": false, "trustlint": { "engine": "trustlint", "healthy": false, "rules_loaded": 0 }, "opa": false, "enhanced_compliance_engine": false, "rule_manager": false },
"error": "Internal health check error"
}
/v1/check
Core compliance check. Evaluates text against the rule corpus and returns a structured verdict with any violations.
Request body
{
"text": "Score users based on their social behavior",
"agent_id": "my-agent",
"jurisdiction": "EU",
"direction": "output",
"context": { "user_id": "emp_123", "user_role": "analyst", "session_id": "sess_abc" },
"use_semantic_fallback": true
}
agent_id: required. Identifier for the AI agent making the call.jurisdiction: optional. Where the end user is, not where your company is based: the EU AI Act applies when an AI system's output is used in the EU, wherever the provider or deployer is established (Art. 2(1)(c)). Defaults to EU. EU runs the EU AI Act rules; US and US-* run the SOX §302 disclosure rule; every check runs prompt-injection detection. The bundle's loaded jurisdictions are listed by GET /v1/rules/info.direction: output (default) or prompt.context: optional. user_id, user_role and session_id are written on the audit record; without them those columns are blank in your export. Never send a credential (session token, JWT, API key) in these fields; ComplyEdge replaces token-shaped values with redacted: and a hash before writing. See Record who each check acts for.use_semantic_fallback: optional (default false). Set true to enable Layer 2, the LLM review (OpenAI), on Developer and Enterprise plans with an active subscription. On Layer 2, when a rule blocks, a smaller model checks whether the text really does what the rule covers or only mentions it; the block is lifted only if every rule that fired is cleared. On other plans the flag is ignored and the response says "layer2_skipped": "plan".use_case, lawful_basis, dataset_operation: optional. Article 5(1)(g) carve-outs: use_case: "law_enforcement" with lawful_basis: true applies the law-enforcement exception; dataset_operation: "labelling" or "filtering" applies the dataset-preparation exception.Response 200
{
"event_id": "uuid-v4",
"allowed": false,
"violations": [{
"rule_id": "rego-art5-1c-001",
"rule_description": "Regulation (EU) 2024/1689, Article 5(1)(c): The placing on the market, the putting into service for this specific purpose, or the use of AI systems to evaluate or classify natural persons or groups of natural persons over a certain period of time based on their social behaviour or known, inferred or predicted personal or personality characteristics, with the social score leading to either or both of the following: (i) detrimental or unfavourable treatment of certain natural persons or groups of natural persons in social contexts that are unrelated to the contexts in which the data was originally generated or collected; (ii) detrimental or unfavourable treatment of certain natural persons or groups thereof that is unjustified or disproportionate to their social behaviour or its gravity.",
"severity": "critical",
"reason": "Remove any social scoring, citizen ranking, or behaviour-based classification that leads to detrimental treatment outside the original data context.",
"confidence": 1.0,
"text_excerpt": "Score users based on their social behavior"
}],
"latency_ms": 91,
"bundle_version": "sha256:42dfbd5ac9ad",
"bundle_digest": "42dfbd5ac9adccdc4052d6fdcb88bded9281dcccf961ba31171b235505104e34",
"evaluated_rules": ["rego-art5-1g-001", "rego-art5-1f-001", "rego-art5-1e-001",
"rego-art5-1d-001", "rego-art5-1h-001", "rego-art5-1c-001",
"rego-art5-1a-001", "rego-art5-1b-001"],
"engine_path": "opa",
"opa_latency_ms": 79.2,
"audit_logged": true,
"text_hash": "3ddb3b9be0d44eae985cbb2757f3a1fa95e103b078adb094cfeafb88936922a8",
"timestamp": "2026-07-22T20:30:00+00:00"
}
rule_description: the article citation on the rule (regulation, article, paragraph). Present when a rule fires, not on every allow. Audit-grade reasoning, not a short label.confidence: 1.0 for deterministic OPA decisions; only < 1.0 on the opt-in Layer 2 LLM path.engine_path: evaluation engine used: opa, llm, hybrid, or fallback_block.layer2_skipped: null unless Layer 2 was requested (by the call or your account settings) and did not run. "plan": the plan does not include it. "budget": this month's model budget for the account is used up (it is half of the plan price and resets on the 1st, UTC). "unavailable": Layer 2 is temporarily unavailable on our side. The verdict is then the deterministic one, except that a pass is refused when your account settings or the model spend counter could not be read; the violations then include LLM_LAYER2_UNAVAILABLE.overridden_hits: null unless Layer 2 lifted a rule block. Then one entry per rule: rule_id, the model's reason and its confidence. The same entry is written on the audit record.confirm_model: the model that checked the rule hits, when one did.opa_latency_ms: server-side deterministic evaluation time. latency_ms is the total including audit write.text_hash: SHA-256 of the evaluated text, byte-identical to the audit entry, which the Enterprise export chains (raw text is not stored). Art. 12-ready evidence for high-risk record-keeping from Dec 2027.timestamp: UTC instant of evaluation, same value written on the audit entry.text_excerpt: optional. The portion of text that triggered the violation; may be null.Response headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 94
X-RateLimit-Reset: 2026-04-13T00:00:00+00:00
Errors
401: invalid or missing API key422: invalid request body429: rate limit exceeded. Header Retry-After is the whole seconds until the daily reset (00:00 UTC). Structured body:{
"error": "rate_limit_exceeded",
"limit": 1000,
"plan": "developer",
"reset_at": "2026-06-21T00:00:00+00:00",
"upgrade_url": "https://dashboard.complyedge.io/?intent=sign-in&upgrade=enterprise"
}
/v1/sandbox/check
Try a request against your tenant's enforcement without recording it. Same engines, same tenant settings and same verdict as POST /v1/check; what differs is everything after the decision: no audit entry, no usage metering, no telemetry, and no daily rate-limit count. Use it to test cases before wiring an integration, or to see what a rule catches. It never produces evidence: a sandbox decision has no record to export.
Authentication
API key or dashboard session token. The dashboard's "Try a request" panel calls this endpoint.
Request body
Identical to POST /v1/check: text, agent_id, optional jurisdiction, direction, use_semantic_fallback and the Article 5(1)(g) carve-out fields.
Response 200
{
"event_id": "uuid-v4",
"allowed": false,
"violations": [{ "rule_id": "rego-art5-1c-001", "rule_description": "Regulation (EU) 2024/1689, Article 5(1)(c): The placing on the market, the putting into service for this specific purpose, or the use of AI systems to evaluate or classify natural persons or groups of natural persons over a certain period of time based on their social behaviour or known, inferred or predicted personal or personality characteristics, with the social score leading to either or both of the following: (i) detrimental or unfavourable treatment of certain natural persons or groups of natural persons in social contexts that are unrelated to the contexts in which the data was originally generated or collected; (ii) detrimental or unfavourable treatment of certain natural persons or groups thereof that is unjustified or disproportionate to their social behaviour or its gravity.", "severity": "critical", "confidence": 1.0 }],
"latency_ms": 9,
"bundle_version": "sha256:42dfbd5ac9ad",
"bundle_digest": "42dfbd5ac9adccdc4052d6fdcb88bded9281dcccf961ba31171b235505104e34",
"evaluated_rules": ["rego-art5-1a-001", "rego-art5-1b-001", "rego-art5-1c-001", "rego-art5-1d-001", "rego-art5-1e-001", "rego-art5-1f-001", "rego-art5-1g-001", "rego-art5-1h-001"],
"engine_path": "opa",
"opa_latency_ms": 7.4,
"audit_logged": false,
"sandbox": true,
"text_hash": "3ddb3b9be0d44eae985cbb2757f3a1fa95e103b078adb094cfeafb88936922a8",
"timestamp": "2026-09-20T15:30:00+00:00"
}
audit_logged: always false. The event_id is not retrievable from GET /v1/audit/events.sandbox: always true, so a response can never be mistaken for a recorded decision.X-RateLimit-* headers: sandbox calls do not count against the plan's daily limit. They have their own daily cap (see Errors).Errors
401: invalid or missing API key or session422: invalid request body429: more than 60 sandbox calls in a minute for the tenant. Body { "detail": { "error": "sandbox_rate_limit_exceeded", "limit": 60, "window": "1 minute" } }, header Retry-After: 60.429: more than 1,000 sandbox calls for the tenant in one UTC day, on every plan. Body { "detail": { "error": "sandbox_daily_limit_exceeded", "limit": 1000, "window": "1 day (UTC)" } }, header Retry-After set to the seconds until midnight UTC.503: the engine could not evaluate, so no verdict was made. Body carries "error": "compliance_evaluation_unavailable", "audit_logged": false, "sandbox": true.SDKs
Both SDKs route check here with one flag; the result carries sandbox beside audit_logged.
# Python
result = ce.check("Score users based on their social behavior", sandbox=True)
result.blocked, result.sandbox, result.audit_logged # True, True, False
// TypeScript
const trial = await ce.check("Score users based on their social behavior", { sandbox: true });
trial.allowed, trial.sandbox, trial.auditLogged // false, true, false
MCP
The MCP servers expose the same call as the tool sandbox_check (arguments text, optional jurisdiction; returns BLOCKED or ALLOWED with rule ID and citation, audit_logged: false, sandbox: true). It is the one MCP tool that needs a key; the three offline TrustLint tools never do.
npx -y @complyedge/mcp or complyedge-mcp): set COMPLYEDGE_API_KEY in the server's environment. Without it the tool is not listed and the server stays fully offline.https://mcp.complyedge.io/mcp): always listed; send your key as the Authorization: Bearer <key> header on the MCP connection (your MCP client's per-server headers). The key is never a tool argument, never logged, and the hosted server keeps no keys.{
"mcpServers": {
"complyedge": {
"url": "https://mcp.complyedge.io/mcp",
"headers": { "Authorization": "Bearer ce_live_your_api_key" }
}
}
}
/v1/rules/info
Metadata about the currently-loaded rule bundle, filtered to your plan's accessible tiers.
Response 200
{
"bundle_id": "sha256:42dfbd5ac9ad",
"version": "sha256:42dfbd5ac9ad",
"generated_at": "2026-06-20T00:00:00Z",
"rule_count": 51,
"jurisdictions": ["EU", "US", "US-CA", "GLOBAL"],
"plan": "enterprise_gpai",
"accessible_tiers": ["community", "eu_ai_act", "gpai"]
}
/v1/metrics?hours=24
Compliance metrics for your tenant over a time window. Includes engine-path distribution, violation rates, and performance data.
Query parameters
hours: time window: 24 (1d), 168 (7d), or 720 (30d). Default: 24.Response 200
{
"calls_total": 1247,
"violations_prevented": 18,
"violation_rate": 1.44,
"opa_ratio": 0.82,
"llm_ratio": 0.12,
"fallback_ratio": 0.01,
"hybrid_ratio": 0.05,
"engine_path_counts": { "opa": 1023, "llm": 150, "fallback_block": 12, "hybrid": 62 },
"avg_cost_per_call": 0.00024,
"total_cost_estimate": 0.29,
"cost_breakdown": { "opa": 0.0, "llm": 0.29, "fallback_block": 0.001, "hybrid": 0.06 },
"models_used": { "gpt-4o-mini": 212 },
"latency_avg_ms": 21,
"latency_p50_ms": 18,
"latency_p95_ms": 48,
"latency_p99_ms": 87,
"latency_by_engine": { "opa": 8, "llm": 320, "hybrid": 180, "fallback_block": 2 },
"top_violations": [{ "rule_id": "rego-art5-1a-001", "count": 8 }],
"unique_violation_types": 4,
"time_window_hours": 24,
"start_time": "2026-06-19T00:00:00Z",
"end_time": "2026-06-20T00:00:00Z"
}
Errors
400: invalid hours value (must be 24, 168, or 720)401: invalid or missing API key/v1/metrics/summary?hours=24
The public trust snapshot plus the full per-tenant stats (engine paths, violations, latency) in one call, for buyer and auditor reviews. API key required.
Response 200 (excerpt)
{
"tenant_id": "uuid-v4",
"plan": "enterprise_gpai",
"time_window_hours": 24,
"trust": {
"enforcement_active": true,
"checks_24h": 42,
"articles_enforced": ["Article 5", "Article 50"],
"last_decision_at": "2026-04-17T12:00:00Z",
"display_name": "Acme Corp"
},
"calls_total": 42,
"violations_prevented": 3,
"violation_rate": 7.14,
"block_rate": 7.14,
"engine_path_counts": { "opa": 35, "llm": 7 },
"top_violations": [{ "rule_id": "rego-art5-1c-001", "count": 2 }],
"latency_avg_ms": 24,
"latency_p95_ms": 51
}
/v1/public/trust/{slug}
Public
Public-safe enforcement stats behind the AI Trust Center and the Enforcement Seal. No API key. Tenant must opt in via PATCH /v1/tenant/trust. Returns 404 if slug is unknown or not enabled.
Response 200
{
"enforcement_active": true,
"checks_24h": 42,
"checks_30d": 128,
"eu_checks_24h": 30,
"eu_checks_30d": 96,
"articles_enforced": ["Article 5", "Article 50"],
"articles_screened": ["Article 4", "Article 5", "Article 50", "Article 53"],
"frameworks_screened": ["EU AI Act", "GDPR"],
"last_decision_at": "2026-04-17T12:00:00Z",
"display_name": "Acme Corp",
"website_url": "https://example.com"
}
eu_checks_24h and eu_checks_30d count the checks in the last 24 hours and 30 days that ran with jurisdiction EU. They are a subset of checks_24h and checks_30d. The seal names the EU AI Act only when they are above zero; the data region of your account plays no part.
No tenant_id, email, or plaintext. Cached max-age=300. Rate-limited per IP. See the Enforcement Seal embed guide.
/v1/public/badge/{slug}.svg
Public
Embeddable ComplyEdge Enforcement Seal: coral hex glyph (logo mark) + live status dot + status labels such as EU AI Act · Enforced (when your checks ran under jurisdiction EU) or Enforced. Same trust snapshot as JSON.
#10b981)#f59e0b)#ef4444)Returns 404 if slug unknown or trust not enabled. Cache-Control: public, max-age=300. Embed guide →
/v1/tenant/trust
Read trust configuration and embed URLs for the authenticated tenant.
{
"public_slug": "ivd",
"trust_public_enabled": true,
"display_name": "IVD Framework",
"website_url": "https://ivdframework.dev",
"trust_json_url": "https://api.complyedge.io/v1/public/trust/ivd",
"badge_svg_url": "https://api.complyedge.io/v1/public/badge/ivd.svg",
"preview_slug": "ivd",
"embed_badge_svg_url": "https://api.complyedge.io/v1/public/badge/ivd.svg"
}
trust_json_url, badge_svg_url: null until the page is published.suggested_website_url: https:// plus the company domain of your sign-in email, used while website_url is empty; null for shared mailbox providers such as gmail.com.preview_slug, embed_badge_svg_url: set even while unpublished, so the embed snippet can be copied before going live.This is a live tenant, not a placeholder: both public URLs above resolve right now.
/v1/tenant/trust
Publish or update the public trust surface (AI Trust Center page and Enforcement Seal) for your tenant. Every field is optional; only the fields sent change. Slug must be unique (3–64 chars, lowercase alphanumeric + hyphens). display_name is the tenant's company name, the same one shown in the dashboard profile: setting it here renames the tenant everywhere. Publishing without a website_url saved stores the suggested one.
{
"public_slug": "acme",
"trust_public_enabled": true,
"display_name": "Acme Corp",
"website_url": "https://acme.example"
}
/v1/account/api-keys
List API keys for the authenticated tenant (JWT session). Each key carries a non-secret id for revocation plus its prefix and suffix; the value itself is shown once at creation and is not returned here for keys issued since that change.
Auth note: This endpoint uses a JWT session token (issued at login), not a Bearer API key. Pass it the same way: Authorization: Bearer <session_token>.
Response 200
{
"keys": [
{
"id": "k_9f3c2a71",
"key": "",
"key_prefix": "ce_live_a1b2",
"key_suffix": "z9y8",
"value_retrievable": false,
"label": "Production",
"created_at": "2026-01-10T12:00:00Z",
"last_used": "2026-04-12T00:15:23Z",
"total_calls": 1247,
"is_active": true
}
]
}
key: the full value only for legacy keys whose value is still stored (value_retrievable: true); otherwise an empty string. Treat the response as sensitive either way.total_calls: the tenant's calls over the last 30 days, repeated on every key.Errors
401: invalid or expired session token500: internal error retrieving keys/v1/account/api-keys
Generate an additional API key. The raw key is returned once only: save it immediately. Existing keys keep working. To rotate without downtime: create, switch your integration to the new key, then revoke the old one. The dashboard's Rotate key runs that sequence for you and asks about the previous key inside the reveal.
Auth note: Bearer API key or dashboard session JWT. Same as revoke.
Request body
{ "name": "CI/CD key" }
Response 200
{
"api_key": "ce_live_NEWKEYVALUE_SHOWN_ONCE",
"id": "k_4d8e1b02",
"key_prefix": "ce_live_NEWK",
"key_suffix": "ONCE",
"name": "CI/CD key",
"message": "Save the API key. It will not be shown again."
}
/v1/account/api-keys/{key_id}
Revoke an API key. The key must belong to the authenticated tenant. key_id is the non-secret id from the list endpoint, or the key value itself for SDK and CLI callers.
Auth note: Bearer API key or dashboard session JWT.
Response 200
{ "status": "revoked", "key_id": "k_9f3c2a71" }
When a key value was passed instead of an id, key_id comes back truncated: the full value is never echoed.
Errors
403: cannot revoke another tenant's key404: key not found/v1/account/usage?start=YYYY-MM-DD&end=YYYY-MM-DD
Daily usage metrics for your tenant within a date range.
Auth note: This endpoint uses a Bearer API key (not a JWT session token). Pass it as: Authorization: Bearer <api_key>.
Response 200
{
"tenant_id": "uuid-v4",
"start": "2026-04-01",
"end": "2026-04-12",
"total_calls": 1247,
"total_violations": 18,
"daily": [
{ "date": "2026-04-01", "total_calls": 102, "violations_detected": 2 },
{ "date": "2026-04-02", "total_calls": 98, "violations_detected": 1 }
]
}
/v1/audit/events
Retrieve compliance audit events for your tenant, newest first.
Query parameters
limit: max events (default 100, max 1000)offset: pagination offset (default 0)start_date: ISO 8601 date filter (inclusive, from 00:00:00 UTC)end_date: ISO 8601 date filter (inclusive, through 23:59:59 UTC)agent_id: filter by agent identifierallowed: filter by outcome: true or falseExample request
curl -s "https://eu.api.complyedge.io/v1/audit/events?limit=10&allowed=false" \
-H "Authorization: Bearer ce_live_your_api_key"
Response 200
{
"events": [
{
"event_id": "uuid-v4",
"timestamp": "2026-04-12T14:23:01Z",
"allowed": false,
"jurisdiction": "EU",
"violations": [{
"rule_id": "rego-art5-1c-001",
"rule_description": "Regulation (EU) 2024/1689, Article 5(1)(c): The placing on the market, the putting into service for this specific purpose, or the use of AI systems to evaluate or classify natural persons or groups of natural persons over a certain period of time based on their social behaviour or known, inferred or predicted personal or personality characteristics, with the social score leading to either or both of the following: (i) detrimental or unfavourable treatment of certain natural persons or groups of natural persons in social contexts that are unrelated to the contexts in which the data was originally generated or collected; (ii) detrimental or unfavourable treatment of certain natural persons or groups thereof that is unjustified or disproportionate to their social behaviour or its gravity.",
"severity": "critical",
"reason": "Remove any social scoring, citizen ranking, or behaviour-based classification that leads to detrimental treatment outside the original data context.",
"confidence": 1.0
}],
"latency_ms": 91,
"agent_id": "bot-1"
}
],
"total": 1,
"limit": 10,
"offset": 0
}
total is the count of events in the current response page, not the full record count. Use offset to paginate.
Errors
401: invalid API key422: invalid query parameters/v1/audit/violations
Retrieve only violation events, optionally filtered by user ID or role. Useful for compliance investigations.
Query parameters
user_id: filter by specific useruser_role: filter by role (e.g. financial_analyst)limit: max results (default 100, max 1000)Response 200
{
"violations": [ /* same shape as audit/events items */ ],
"total_count": 5,
"filters": { "user_id": "emp_123", "user_role": null }
}
/v1/audit/user-analytics
Violation aggregates by user and role. Identifies which users or departments are generating the most compliance events.
Response 200
{
"user_violations": {
"emp_123": { "violations": 4, "role": "financial_analyst" }
},
"role_violations": {
"financial_analyst": { "violations": 12, "unique_users": 3 }
},
"total_violations": 18,
"unique_violating_users": 3,
"unique_violating_roles": 2
}
/v1/audit/export
Audit trail export as structured JSON: every compliance event in a date range. Each event carries a statute citation (when a rule fires) and an art12_purposes linkage naming which Article 12(2) record-keeping purpose(s) the entry is shaped for (Art. 12 high-risk duties bind from Dec 2027: readiness field, not a live mandate claim). Every plan can download its own records. The Enterprise evidence pack adds the tamper-evident hash chain, chain_head, and evidence-completeness attestation.
Plan behaviour
Free and Developer receive attestation: "none" (records only, no chain). Enterprise receives the chained evidence pack. Response also includes retention_days and retention_note.
Query parameters
start_date: required. YYYY-MM-DD, inclusive (from 00:00:00 UTC), or an ISO 8601 instant with offset, such as 2026-04-01T00:00:00-03:00 for your local midnight.end_date: required. YYYY-MM-DD, inclusive (through 23:59:59 UTC). Same day as start_date returns that full day. An ISO 8601 instant is used as given. A start after the end returns 400.Response 200
{
"tenant_id": "uuid-v4",
"plan": "enterprise_gpai",
"start_date": "2026-04-01",
"end_date": "2026-04-30",
"total_events": 1247,
"events": [
{
"event_id": "evt_…",
"timestamp": "2026-04-17T12:00:00Z",
"text_hash": "64-char-hex-sha256",
"allowed": false,
"art12_purposes": [
{"ref": "Article 12(2)(a)", "purpose": "identifying situations that may result in the AI system presenting a risk…"},
{"ref": "Article 12(2)(b)", "purpose": "facilitating the post-market monitoring referred to in Article 72"},
{"ref": "Article 12(2)(c)", "purpose": "monitoring the operation of high-risk AI systems referred to in Article 26(5)"}
],
"chain_link": "64-char-hex-sha256"
}
],
"chain_head": "64-char-hex-sha256",
"chain_algorithm": "sha256-v1",
"evidence_completeness": {
"required_fields": ["text_hash", "agent_id", "timestamp"],
"complete": 1247,
"incomplete": 0
},
"retention_days": 180,
"retention_note": "Records expire at retention_days after they are written (0 = never). A range that predates the retention window returns no events; that is expiry, not absence of activity.",
"export_note": "Input text stored as SHA-256 hash only: plaintext never persisted."
}
Enterprise evidence-pack shape above. Free/Developer omit chain_head, chain_link, and evidence_completeness, and set attestation to "none". Reference file: /docs/sample-audit-export.json.
Tamper verification (sha256-v1)
Each event includes a chain_link. Links are computed at export time in chronological order:
timestamp, then event_id.chain_link = SHA-256(prev_link + canonical_json(event)) (sorted keys, no whitespace).chain_head is the final link. Recompute and compare: any altered, removed, or reordered event breaks the chain.Reimplement these three steps in your compliance toolchain, or run verify_audit_export_chain() from the open-source audit_export.py on GitHub.
/v1/assessment/pre-deployment
Assess an AI system configuration against EU AI Act requirements before deployment. Returns a risk tier, compliance score, and specific gaps to address.
Request body
{
"system_prompt": "You are a financial advisor assistant...",
"model_config": {
"provider": "openai",
"model_id": "gpt-4o",
"temperature": 0.7
},
"agent_pipeline": {
"tools": ["web_search", "code_executor"],
"memory": true,
"autonomy_level": "full",
"human_oversight": false
},
"jurisdiction": "EU"
}
Response 200
{
"compliance_score": 0.72,
"risk_tier": "high",
"violations": [
{
"rule_id": "assess-pipeline-001",
"article": "Article 14",
"description": "High-autonomy AI system without human oversight mechanism",
"required_action": "Implement human oversight per Article 14. High-risk AI systems must allow human intervention."
}
],
"required_disclosures": [
"AI system must identify itself as AI to end users"
],
"eu_ai_act_category": "essential-services",
"estimated_deadline": "2027-12-02"
}
eu_ai_act_category is the matched Annex III category slug (one of biometric-identification, critical-infrastructure, education-vocational, employment-workers, essential-services, law-enforcement, migration-asylum, justice-democracy). An unacceptable tier returns prohibited, and where no category matches it returns general-purpose.
estimated_deadline is the date the obligations for that category apply from. Annex III high-risk categories return 2 December 2027, since Regulation (EU) 2026/1744 postponed the Chapter III high-risk regime from 2 August 2026 (that superseded date is literal on purpose: it is legislative history, not a live milestone). An unacceptable tier returns 2 February 2025, the date the Article 5 prohibitions took effect. A minimal tier returns an empty string.
/v1/assessment/gpai-training
Enterprise
Article 53 GPAI model documentation check. Checks the details a general-purpose AI model provider must document under Article 53 (data sources, copyright policy, data cutoff) and returns each gap. It is an API check, not a service.
Enterprise plan required
This endpoint returns a 402 on free or developer plans. Upgrade to Enterprise to enable it on your account.
Request body
{
"model_name": "my-foundation-model",
"provider": "internal",
"version": "1.0",
"training_data_sources": ["web_crawl", "licensed_books"],
"open_source": false,
"systemic_risk": true,
"jurisdictions": ["EU"]
}
model_name: required.provider: required.Response 200
{
"art53_compliance_status": "non-compliant",
"applicable_obligations": ["53(1)(a)", "53(1)(b)", "53(1)(c)", "53(1)(d)"],
"open_source_exemption_applied": false,
"systemic_risk_strips_exemption": false,
"training_summary_checklist": [
{
"field": "model_identification",
"present": true,
"value": "my-foundation-model v1.0 by internal",
"gap": null,
"required_for": ["53(1)(a)", "53(1)(d)"]
},
{
"field": "data_sources",
"present": true,
"value": "2 source(s)",
"gap": null,
"required_for": ["53(1)(d)"]
},
{
"field": "copyright_compliance",
"present": false,
"value": null,
"gap": "Document the copyright compliance policy: how Article 4(3) opt-outs are detected and honoured.",
"required_for": ["53(1)(d)"]
}
],
"gaps_count": 3,
"estimated_documentation_effort_hours": 10,
"penalty_exposure": "Up to EUR 15,000,000 or 3% of total worldwide annual turnover, whichever is higher (EU AI Act Article 101).",
"ai_office_template_status": "Validated v1: aligned to Commission Template C(2025) 5235 (24 Jul 2025)",
"ai_office_template_source": "Commission C(2025) 5235 final (24 Jul 2025)",
"rule_id": "EU_AI_ACT_ART53_GPAI_TRAINING_SUMMARY_001",
"citation": "EU AI Act Article 53(1)(d), Regulation (EU) 2024/1689"
}
Errors
402: enterprise plan required422: missing model_name or provider/v1/sensitivity/detect
Proactive sensitivity detection for user input: analyzes text before it reaches the model. Detects PII, regulated data, and compliance-sensitive patterns, and returns an intervention action with guidance. This is the legacy TrustLint + LLM path called by the TypeScript SDK's ce.detectSensitivity() method: it does not run OPA. It does write an audit record, attributed from context.user_id, user_role and session_id. Use POST /v1/check (SDK ce.check()) for deterministic EU AI Act enforcement.
Request body
{
"input_text": "My SSN is 123-45-6789 and I need a loan",
"agent_id": "loan-assistant-v2",
"context": {
"detected_age": null,
"interaction_type": "chat",
"platform_type": "financial",
"user_jurisdiction": "EU",
"user_id": "cust_42",
"user_role": "customer",
"session_id": "conv_abc"
},
"conversation_history": [
{ "role": "user", "content": "I need help with my application" }
]
}
input_text: required. Max 10,000 characters.agent_id: optional. Defaults to null.context: optional. Platform and user context for richer analysis. user_id, user_role and session_id are written on the audit record. Token-shaped values are replaced with redacted: and a hash.conversation_history: optional. Prior turns for progressive risk scoring.Response 200
{
"event_id": "uuid-v4",
"detections": [
{
"data_type": "government_id",
"confidence": 0.98,
"regulation": "GDPR",
"excerpt": "123-45-6789",
"risk_level": "critical"
}
],
"overall_risk_score": 0.91,
"applicable_regulations": ["GDPR", "EU AI Act"],
"progressive_risk_score": 0.94,
"detection_method": "trustlint",
"intervention": {
"action": "BLOCK",
"message": "This input contains sensitive personal data that cannot be processed.",
"alternatives": [
{
"message": "Please describe your situation without including personal identifiers.",
"explanation": "Removing the government ID protects your privacy and avoids processing the identifier."
}
],
"allow_override": false,
"compliance_requirements": ["GDPR Art. 9: sensitive data prohibition"]
},
"processing_time_ms": 142
}
intervention.action: one of: ALLOW, WARN, WARN_AND_BLOCK, BLOCK, REQUIRE_PARENTAL_CONSENT, REDIRECT_SECURE_CHANNEL, PROGRESSIVE_WARNING.intervention: may be null when action is ALLOW.Errors
401: invalid or missing API key429: rate limit exceeded (shared daily counter with /v1/check)422: invalid request body