Skip to main content

ComplyEdge Python SDK

Prove what your AI decided, without keeping what it saw. Every request and answer is checked against open EU AI Act rules that cite the law: one record per decision, never a copy of the text.

Choose the Right Package

complyedge is the Python client for the hosted ComplyEdge runtime API. It enforces policy decisions in your application and records the resulting evidence trail. For an offline command-line linter with no API key, use TrustLint instead.

Installation

pip install complyedge

Quick Start: EU AI Act in Three Lines

from complyedge import compliance_check

@compliance_check(
    jurisdiction="EU",
    agent_id="my-agent",
    decision_context={  # what only you know, for an ADCR-complete record
        "deciding_system": {"version": "gpt-5.4-2026-08-01"},
        "purpose_ref": "purpose:support-replies",
        "data_categories": ["contact"],
    },
)
def my_agent(prompt):
    return llm.generate(prompt)  # every input and output checked

That's it. Every input and output is checked against the EU AI Act rule set (Article 5, Article 50, GPAI). Inputs and outputs that break a blocking rule are stopped before they reach the user. Every check gets a record with an event_id, the rules that fired (if any), a timestamp and a keyed hash of the text; every block by a rule also gets its legal citation. decision_context is optional: without it every check still runs and is recorded, but the record does not meet ADCR class Record (see Tell the record what only you know). With the default fail mode, open, an API outage lets traffic through unchecked and unrecorded; set COMPLYEDGE_FAIL_MODE=closed, or pass config=ComplianceConfig(fail_mode="closed"), to raise ComplianceUnavailableError instead. Without an API key the decorator always runs the function unchecked.

Classifiers (eu-ai-act-* MCPs) score the system. ComplyEdge checks and records this prompt or output. Article 50 here is unlabeled or deceptive use, not C2PA watermarking.

Each line is an alternative; pick the one you need.

pip install complyedge                               # this SDK: hosted checks and the decorator
pip install 'complyedge[mcp]'                        # plus the MCP server: complyedge-mcp
pip install 'complyedge[agents]'                     # plus the OpenAI Agents guardrail
pip install trustlint                                # offline linter CLI, separate package
npx -y @complyedge/mcp                               # the MCP server on Node, no Python
claude mcp add complyedge -- npx -y @complyedge/mcp  # add the Node MCP server to Claude Code

OpenAI Agents extra (hosted path; needs COMPLYEDGE_API_KEY): from complyedge.agents import create_compliance_guardrail

GitHub Action: uses: complyedge/trustlint-action@v1

The decorator reads your API key from the COMPLYEDGE_API_KEY environment variable by default. Pass api_key_env="MY_VAR" to use a different one.

Multi-Jurisdiction Enforcement

jurisdiction is 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)). Default: EU.

Value What the hosted API enforces deterministically
EU EU AI Act: Article 5 prohibited practices, plus Article 6 high-risk, Article 50 and GPAI (Articles 51 to 55) rules that fire on text describing a missing control; prompt-injection detection; personal data and secrets (citing GDPR). Any rule that fires blocks the call.
US, US-* SEC Regulation FD selective disclosure + prompt-injection detection

HIPAA, COPPA, TCPA, BIPA, CCPA, NYC LL144 and ECPA rules, and the GDPR YAML rules (consent, data minimisation, DPIA, erasure, breach notification, transfers), run offline in TrustLint (pip install trustlint), not on the hosted /v1/check path. The hosted personal data and secrets rules above cite GDPR Articles 5(1)(c) and 32(1).

@compliance_check(jurisdiction="EU", agent_id="hr-screening")
def hr_screening(candidate: str) -> str:
    return llm.generate(candidate)

Per-rule scoping (e.g. only Article 5) is planned but not yet exposed in the SDK: all rules for the selected jurisdiction run today.

Additional Installation Options

# Development setup
pip install 'complyedge[dev]'

# Local development from source
pip install -e ./sdks/python

Client API: Without the Decorator

from complyedge import ComplyEdge

ce = ComplyEdge(api_key="your-key")
result = ce.check("AI-generated content", jurisdiction="EU")

if result.allowed:
    print("Content approved")
else:
    for v in result.violations:
        print(f"{v.rule_id}: {v.rule_description}")  # the rule's legal citation

Record who each check acts for

Every audit record has user_id, user_role and session_id. They are filled only when you send them; leave them out and those columns are blank in your audit export.

# Per call
ce.check(text, user_id="ref_5d81e2c4", user_role="recruiter", session_id="conv_abc")

# Client defaults for an agent that always acts for the same person
ce = ComplyEdge(api_key=api_key, user_id="ref_5d81e2c4", user_role="recruiter", session_id=run_id)

# Decorator: a dict, or a zero-argument function read on every call
@compliance_check(jurisdiction="EU",
                  attribution=lambda: {"user_id": current_user.id, "session_id": request_id})
def answer(prompt: str) -> str:
    ...

ComplyEdgeClient.check_compliance() and the async client take the same three keyword arguments; they override the same keys in context. Use a stable identifier from your own system, never a name or an email address. user_id and session_id are stored as keyed pseudonyms (p1:...) under your account's own key, not as sent; user_role is stored as sent, so it must name a role, not a person.

Never send a credential in these fields: a login token, session cookie, JWT or API key would sit in every audit record and export. If your session id doubles as a login token, send a hash of it (for example the first 16 hex characters of its SHA-256). ComplyEdge replaces any token- or key-shaped value with redacted: plus a hash before the record is written.

Prove a record was about a given text

ComplyEdge never stores the prompt or the answer. The record keeps text_hash, a keyed hash (HMAC-SHA-256) of the input under your account's own key, so it cannot be recomputed locally. Keep the event_id next to your own copy of the text, and ask the API when you need to prove the pair:

result = ce.check(text)
app_log.info("chat turn", prompt=text, complyedge_event_id=result.event_id)  # your own log
# later, in an audit or a complaint:
assert ce.verify_input(result.event_id, text)  # True only for this exact text

Optional: pass receipt_journal="/var/lib/app/complyedge-receipts.jsonl" to ComplyEdge(...) (or use ReceiptJournal yourself) to append event_id, text_hash, and digests locally after each non-sandbox check. The journal never stores the prompt; your app log still holds the text.

The full walkthrough, including what happens if you delete your copy early: https://complyedge.io/docs/audit-reconciliation.html

result.text_hash_alg is "hmac-sha256-1"; records written before the keyed hash was introduced carry none and hold a plain SHA-256, which verify_input also checks.

Tell the record what only you know

The audit record can carry fields ComplyEdge cannot know: the version of your AI system, the purpose of the processing and the categories of personal data the decision used. Pass them as decision_context; they are written to the record as ADCR 0.1.0 fields (https://complyedge.io/producer-profile/). decision_context is optional: without it the check runs and is recorded, but the record does not meet ADCR class Record. When you send it, deciding_system.version, purpose_ref and data_categories ([] when none) are required; every other key is optional. check(), is_safe(), the global check() and is_safe(), check_compliance() and the decorator (a dict, or a zero-argument function read on every call) all take it.

result = ce.check(
    text,
    decision_context={
        "deciding_system": {"version": "gpt-5.4-2026-08-01"},
        "purpose_ref": "purpose:support-replies",
        "data_categories": ["contact"],
    },
)

Try a case without recording it

sandbox=True calls POST /v1/sandbox/check: the same rules, the same tenant settings and the same verdict, but no audit entry, no usage and no count against your plan's daily limit (sandbox calls have their own caps: 60 a minute, 1,000 a day). Use it to test cases before wiring an integration. A sandbox result is never evidence: result.sandbox is True and result.audit_logged is False.

result = ce.check("Score users based on their social behavior", sandbox=True)
print(result.blocked, result.sandbox)  # True True

Or the global convenience functions:

from complyedge import is_safe, check
import os

api_key = os.environ["COMPLYEDGE_API_KEY"]

# Boolean check
if not is_safe(text, api_key=api_key, jurisdiction="EU"):
    raise ValueError("Compliance violation")

# Full result
result = check(text, api_key=api_key, jurisdiction="EU")

Rotating your key

Keys are shown once, at creation, and stored as a hash: a lost key cannot be recovered, only replaced. Rotate without downtime, in this order:

  1. In the dashboard, open API Key and click Rotate key on the card (or Rotate on a row under Other active keys), then confirm. A new key is minted and shown once; the old one keeps working.
  2. Put the new key in your integration (COMPLYEDGE_API_KEY or the api_key you pass to the client) and deploy.
  3. Back in the reveal, click Revoke previous key. Requests with the old key fail from that moment. If you need more time, Keep both for now and revoke it later from the API Key page, where every active key is listed.

Compromised key: revoke first (Revoke this key on the card, or Revoke on the row), then rotate. Via the API the same flow is POST /v1/account/api-keys, then DELETE /v1/account/api-keys/{key_id} for the old key.

Company name on the public trust surface

Your public AI Trust Center and Enforcement Seal show one company name: the one set in the dashboard under Account, Profile. display_name on PATCH /v1/tenant/trust sets the same value, so an API call and the profile never disagree. Email is your sign-in and cannot be changed from the dashboard.

Regions

Two regions, one home per account, chosen when you sign up and create your first API key: EU (eu.api.complyedge.io, key prefix ce_eu_) or US (api.complyedge.io, key prefix ce_). The SDK reads the prefix and picks the host. To change the region later, use Request a region change in the dashboard; you get a new key for it. base_url, region, COMPLYEDGE_API_URL, and COMPLYEDGE_REGION only choose which host to call. They do not change the account's region.

The region is where your prompts and audit records are processed and stored. It does not decide 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). Choose the region your own contracts or customers ask for.

ce = ComplyEdge(api_key="ce_eu_...")   # -> https://eu.api.complyedge.io
ce = ComplyEdge(api_key="ce_...")      # -> https://api.complyedge.io

To override, highest precedence first: base_url= (or COMPLYEDGE_API_URL), then region="us" | "eu" (or COMPLYEDGE_REGION), then the key prefix, then EU. A key presented to the other region's stack is refused with 401 {"detail": {"error": "wrong_region", "use": "<host>"}} before any lookup.

MCP Server: Use ComplyEdge as an AI Agent Tool

Agent/MCP tools that check prompts and outputs against ComplyEdge’s TrustLint corpus with cited findings: not another EU AI Act risk-tier chatbot and not a law-search database.

Hosted Streamable HTTP (preferred for remote clients): https://mcp.complyedge.io/mcp

Local stdio for any MCP-compatible host (Claude, Cursor, Inspector):

pip install 'complyedge[mcp]>=0.2.8'
python -m complyedge.mcp_server
# or: complyedge-mcp

Add to your MCP client config (e.g. claude_desktop_config.json):

{
  "mcpServers": {
    "complyedge": {
      "command": "complyedge-mcp"
    }
  }
}

(command/args with python -m complyedge.mcp_server is also valid.)

Exposed tools (TrustLint offline YAML rule set):

Tool Description
check_compliance Check text against TrustLint rules. Returns PASS/FAIL with cited findings.
list_rules List available TrustLint rules, filterable by jurisdiction.
scan_prompt Pre-generation prompt scan. Returns SAFE or RISK_DETECTED.

No API key is required for these tools. The optional extra installs mcp and trustlint (engine + bundled rules). This MCP path does not run the REST API policy engine.

Optional hosted sandbox. Set COMPLYEDGE_API_KEY in the server's environment and a fourth tool appears:

Tool Description
sandbox_check Hosted enforcement in sandbox mode (POST /v1/sandbox/check): your tenant's real rules and settings, same verdict as production, and nothing recorded: no audit entry, no usage, and no count against your plan's daily limit (sandbox calls have their own caps: 60 a minute, 1,000 a day). Returns BLOCKED with rule ID and article citation, or ALLOWED. Never evidence.

Without the key the tool is not listed and the server stays fully offline.

On the hosted server (https://mcp.complyedge.io/mcp) sandbox_check is always listed and works only for a caller that sends its own key as the Authorization: Bearer <key> header on the MCP connection (set it in your MCP client's headers). The key is never a tool argument and never logged; the hosted server keeps no keys.

Documentation

Metadata

Release files for complyedge 0.2.23

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for complyedge 0.2.23
File Size Uploaded Provenance
complyedge-0.2.23.tar.gz 49.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for complyedge 0.2.23
File Interpreter ABI Platform
complyedge-0.2.23-py3-none-any.whl Python 3 none any Details

Total release size: 97.7 kB

Release files / complyedge-0.2.23.tar.gz

Download URL complyedge-0.2.23.tar.gz
Size 49.9 kB
Tags Source
SHA-256 checksum
How to use checksums
cbb670fdea99c6f70be4387d3c09e935595ad1b81e706287f31e09b7e52a7f99
BLAKE2b-256 checksum
How to use checksums
c5c184430919de1dfdefab31e6beecb844d668037e26279b3bd2b81986d9bbb1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / complyedge-0.2.23-py3-none-any.whl

Download URL complyedge-0.2.23-py3-none-any.whl
Size 47.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b5cede1b6bc8bc47d9fd63e71518641fee5043c8a7b836b1efde01bf0eb5d9e9
BLAKE2b-256 checksum
How to use checksums
f51ee954170e187595971b264d819c9b64fd809661c5efb80a6e9364b7ac36ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Security for complyedge 0.2.23

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for complyedge-0.2.23.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page