Skip to main content

cmp-consent

Python SDK for the CMP officer-assisted deferred consent flow. Runs in your backend (server-to-server) and holds the application API key — never ship the key to a browser.

Three jobs: raise consent requests, gate PII processing on verify(), and verify CMP's signed webhooks.

Install

pip install cmp-consent

Authentication

Credential Direction Header
API key cmpk_live_… SDK → CMP X-API-Key (application-scoped)
Webhook secret whsec_… CMP → SDK HMAC X-CMP-Signature (for verify_webhook)
from promiz import CMPClient

cmp = CMPClient(
    api_base="https://cmp-api.yourdomain",
    api_key="cmpk_live_…",
    webhook_secret="whsec_…",   # only needed for verify_webhook
    timeout=10, retries=2,
)

1) Raise a request (officer submitted)

req = cmp.create_consent_request(
    email="user@example.com",
    notice="kyc-notice",           # the notice key for the application
    requested_by=officer.id,
    idempotency_key=submit_id,     # a retried submit won't double-send the email
)
save(applicant_id, consent_id=req.consent_id)   # store consent_id at t=0

CMP creates a PENDING request, emails the principal a single-use magic link, and returns consent_id immediately.

2) Gate every use of the PII

from cmp_consent import ConsentPending

res = cmp.verify(consent_id=req.consent_id, purpose="bureau_pull")
if not res.allowed:
    raise ConsentPending(res.reason)     # PENDING/DECLINED/EXPIRED → do not process
proceed(proof=res.integrity_hash)        # allowed → consent-backed

verify() is fail-closed: any network error or timeout returns allowed=False (it never raises), so PII is never processed on an ambiguous result. Prefer require_consent(...) when you want it to raise instead:

cmp.require_consent(consent_id=cid, purpose="bureau_pull")   # raises if not granted

3) Receive the callback

# in your webhook route — pass the RAW body bytes
event = cmp.verify_webhook(request.headers, request.body)
if event.type == "CONSENT_GRANTED" and is_new(event.event_id):   # dedupe by event_id
    unblock(event.consent_id)

Webhooks are at-least-once and unordered: dedupe by event.event_id, order by event.consent_seq, and treat verify() as the source of truth on any ambiguity.

Manage

cmp.get_request(req.request_id)   # poll status (fallback if a webhook is missed)
cmp.resend(req.request_id)        # re-mint an expired magic link
cmp.cancel(req.request_id)        # cancel-on-save-failure

Async

AsyncCMPClient mirrors the same surface with await:

from cmp_consent import AsyncCMPClient

async with AsyncCMPClient(api_base=…, api_key=…) as cmp:
    req = await cmp.create_consent_request(email=e, notice="kyc-notice", requested_by=o)
    res = await cmp.verify(consent_id=req.consent_id, purpose="bureau_pull")

Exceptions

ConsentPending · ConsentDeclined · ConsentExpired · SignatureError · CMPError (base). Each carries .status (HTTP) and .code (envelope code) when available.

Metadata

Release files for promiz 0.1.1

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

Source distribution (sdist)

Source distribution for promiz 0.1.1
File Size Uploaded
promiz-0.1.1.tar.gz 46.0 kB Details

Built distribution (wheel)

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

Total release size: 55.9 kB

Release files / promiz-0.1.1.tar.gz

Download URL promiz-0.1.1.tar.gz
Size 46.0 kB
Tags Source
SHA-256 checksum
How to use checksums
10e8a18061c49988d8729d06d2a077bdfcfeab5db889260b60c8749b24e8c92d
BLAKE2b-256 checksum
How to use checksums
4ca2bc1c39b314129dce91c181249033c5cbdbbb251e53181938417019e2d610
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / promiz-0.1.1-py3-none-any.whl

Download URL promiz-0.1.1-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8c40ebe7c54ce1b940841b0d7a62ea9faa619ed10ce84580c9c137ba19269552
BLAKE2b-256 checksum
How to use checksums
22db45ed9087613bfe5f74dcfd1d130113163ab575116dee70216abf722cff28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

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