Skip to main content

didit-sdk

CI PyPI version Python versions License: MIT Checked with mypy Ruff

Official-grade, community-maintained Python SDK for Didit Identity Verification & KYC.


Highlights

  • Ergonomic Sync & Async: Dual-client architecture built on top of high-performance httpx.
  • Strictly Typed & Validated: 100% type annotations (PEP 561 compliant with py.typed) and robust Pydantic v2 domain models.
  • Cryptographic Security: Constant-time HMAC-SHA256 signature verification supporting canonical JSON float-normalization (X-Signature-V2) and replay-attack protection via timestamp freshness windows.
  • FastAPI Integration: Plug-and-play DiditWebhookGuard dependency for securing webhook endpoints with zero boilerplate.
  • Zero-Network Simulation Mode: Built-in SimulatedDidit and SimulatedAsyncDidit to run unit tests and local end-to-end user flows completely offline without live credentials.
  • Resilient Error Hierarchy: Typed exceptions (DiditAuthenticationError, DiditRateLimitError, DiditNotFoundError, DiditServerError) with automated rate-limit retry duration parsing.

Installation

# Core SDK (httpx + pydantic)
pip install didit-sdk

# With FastAPI integration
pip install "didit-sdk[fastapi]"

Quickstart

1. Synchronous Client

from didit import Didit, SessionStatus

# Initialize client (falls back to DIDIT_API_KEY environment variable if omitted)
client = Didit(api_key="your_api_key", webhook_secret="your_webhook_secret")

# Create a verification session
session = client.sessions.create(
    vendor_data="user_12345",
    workflow_id="wf_kyc_standard",
    callback="https://yourapp.com/kyc/complete",
    language="es",
)

print(f"Verification URL: {session.url}")
print(f"Session ID: {session.session_id}")

# Fetch verification decision immediately:
decision = client.sessions.get_decision(session.session_id)

# Or poll until a terminal outcome (Approved or Declined) is reached:
decision = client.sessions.poll_decision(session.session_id, timeout=60.0, interval=2.0)
if decision.status == SessionStatus.APPROVED:
    print(f"User approved! Document: {decision.document.document_number}")

2. Asynchronous Client (asyncio)

import asyncio
from didit import AsyncDidit, SessionStatus


async def main():
    async with AsyncDidit(api_key="your_api_key") as client:
        session = await client.sessions.create(
            vendor_data="user_987",
            workflow_id="wf_kyc_standard",
        )
        print(f"Session URL: {session.url}")

        decision = await client.sessions.get_decision(session.session_id)
        if decision.status.is_terminal:
            print(f"Final outcome: {decision.status}")


asyncio.run(main())

Securing Webhooks with FastAPI

Didit dispatches signed HTTP POST events upon verification completion. didit-sdk provides a dedicated FastAPI dependency to verify signatures in constant time and prevent replay attacks:

from fastapi import FastAPI, Depends
from didit import WebhookPayload, SessionStatus
from didit.integrations.fastapi import DiditWebhookGuard

app = FastAPI()

# Guard reads secret from argument or DIDIT_WEBHOOK_SECRET env var
webhook_guard = DiditWebhookGuard(secret="whsec_...")


@app.post("/api/v1/webhooks/didit")
async def handle_didit_event(
    payload: WebhookPayload = Depends(webhook_guard),
):
    print(f"Received event for session: {payload.session_id}")

    if payload.status == SessionStatus.APPROVED:
        # Mark user verified in your database
        ...
    elif payload.status == SessionStatus.DECLINED:
        # Handle rejection
        ...

    return {"received": True}

Testing & Offline Simulation

Developing without live credentials or mock servers? Use the built-in simulator:

from didit import SimulatedDidit, SessionStatus

# Create in-memory client
sim = SimulatedDidit(webhook_secret="test_secret")

# 1. Create a simulated session
session = sim.sessions.create(vendor_data="dev_user", workflow_id="wf_dev")
assert session.session_id.startswith("sim_")

# 2. Simulate user passing identity check
sim.approve_session(session.session_id)

decision = sim.sessions.get_decision(session.session_id)
assert decision.status == SessionStatus.APPROVED

# 3. Generate signed webhook payloads to test your local receiver
raw_body, headers = sim.generate_webhook_event(session.session_id)
# headers contain valid X-Signature-V2 and fresh X-Timestamp!

Exception Handling

All client errors inherit from DiditError:

from didit import Didit
from didit.errors import (
    DiditAuthenticationError,
    DiditNotFoundError,
    DiditRateLimitError,
    DiditServerError,
)

client = Didit()

try:
    decision = client.sessions.get_decision("non_existent_session")
except DiditNotFoundError:
    print("Session not found")
except DiditRateLimitError as exc:
    print(f"Rate limited. Retry after {exc.retry_after} seconds.")
except DiditAuthenticationError:
    print("Invalid API key")
except DiditServerError as exc:
    print(f"Didit server error ({exc.status_code}): {exc.response_body}")

Environment Variables

Variable Default Description
DIDIT_API_KEY None (Required) Your Didit secret API key
DIDIT_BASE_URL https://verification.didit.me/v3 Didit API base URL
DIDIT_WEBHOOK_SECRET None Shared webhook HMAC secret
DIDIT_TIMEOUT 30.0 HTTP request timeout in seconds
DIDIT_MAX_RETRIES 2 Maximum retry attempts for transient errors

Development & Testing

# Clone the repository
git clone https://github.com/agustin18/didit-sdk.git
cd didit-sdk

# Install dependencies with uv
uv sync --extra dev

# Run unit tests with 100% coverage gate
uv run pytest --cov=didit --cov-report=term-missing

# Lint & Format check
uv run ruff check .
uv run ruff format --check .

# Strict type check
uv run mypy src/didit

License

This project is licensed under the terms of the MIT License.

Metadata

Release files for didit-sdk 0.1.0

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

Source distribution (sdist)

Source distribution for didit-sdk 0.1.0
File Size Uploaded
didit_sdk-0.1.0.tar.gz 22.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for didit-sdk 0.1.0
File Interpreter ABI Platform
didit_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 42.5 kB

Release files / didit_sdk-0.1.0.tar.gz

Download URL didit_sdk-0.1.0.tar.gz
Size 22.1 kB
Tags Source
SHA-256 checksum
How to use checksums
5d347c2f30849b6d6001028039e2c15d8a7a4d00ce2b6dab1a66639778abc6b5
BLAKE2b-256 checksum
How to use checksums
9639f0a94c51607a797a2d3f45de68b1dcaf42716847b2c5857adedf03279b12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 29, 2026.

Transparency log

Release files / didit_sdk-0.1.0-py3-none-any.whl

Download URL didit_sdk-0.1.0-py3-none-any.whl
Size 20.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bd8494e825c9165e67d7c6529094b86da9bfdf36318233c97ea4bf1973aef3e7
BLAKE2b-256 checksum
How to use checksums
a28707efdda0698b3ec55f98ed01698c6cdfab07ceaf581f20eb8cf07c86421d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 29, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 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