Skip to main content

Official Python SDK for the CertiSigma attestation & verification API

Project description

CertiSigma Python SDK

Official Python client for the CertiSigma cryptographic attestation API.

PyPI npm License: MIT

Installation

pip install certisigma

Or from source:

cd sdk/python
pip install -e .

Quick Start

import os
from certisigma import CertiSigmaClient, hash_file, hash_bytes

client = CertiSigmaClient(api_key=os.environ["CERTISIGMA_API_KEY"])

# 1. Compute the SHA-256 hash of your file
file_hash = hash_file("contract.pdf")

# 2. Attest — creates a timestamped, signed proof of existence
result = client.attest(file_hash, source="my-app")
print(f"Attestation: {result.id} at {result.timestamp}")
print(f"ECDSA signature: {result.signature}")

# 3. Verify — confirm the hash was attested
check = client.verify(file_hash)
print(f"Exists: {check.exists}, Level: {check.level}")

# Or hash raw bytes
data_hash = hash_bytes(b"any raw content")
result = client.attest(data_hash)

Public Verification (No API Key)

Verification endpoints are public. You can verify attestations without any API key:

from certisigma import CertiSigmaClient, hash_file

# No api_key needed — works out of the box
client = CertiSigmaClient()

file_hash = hash_file("contract.pdf")
check = client.verify(file_hash)
print(f"Exists: {check.exists}, Level: {check.level}")

# Batch verify also works without a key
results = client.batch_verify([file_hash])
print(f"Found: {results.found}/{results.count}")

Hashing Utilities

Standalone SHA-256 hash functions -- compute hashes without attestation:

from certisigma import hash_file, hash_bytes

# Hash a file (streamed, constant memory)
file_hash = hash_file("/path/to/document.pdf")
print(f"SHA-256: {file_hash}")

# Hash raw bytes
data_hash = hash_bytes(b"raw content")

# Verify a file against a known hash
assert hash_file("/path/to/document.pdf") == file_hash

Or hash + attest in one step:

result = client.attest_file("/path/to/document.pdf")
print(f"Attested: {result.hash_hex}")

Async Support

import asyncio, os
from certisigma import AsyncCertiSigmaClient

async def main():
    async with AsyncCertiSigmaClient(api_key=os.environ["CERTISIGMA_API_KEY"]) as client:
        result = await client.attest("abcdef..." * 4 + "0" * 16)
        print(result.id)

asyncio.run(main())

Batch Operations

# Attest up to 100 hashes in one call — returns full claim metadata per item
batch = client.batch_attest(
    ["aabb..." * 4, "ccdd..." * 4],
    source="monthly-invoices"
)
print(f"Created: {batch.created}, Existing: {batch.existing}")
for att in batch.attestations:
    print(f"  {att['id']} claim={att['claim_id']} src={att['source']}")

# Verify batch (public, no key needed)
results = client.batch_verify(["aabb..." * 4, "ccdd..." * 4])
print(f"Found: {results.found}/{results.count}")

# Detailed mode — certification level + claim metadata (requires api_key)
results = client.batch_verify(["aabb..." * 4], detailed=True)
for r in results.results:
    if r["exists"]:
        print(f"  {r['id']} level={r['level']} src={r['source']}")

Attestation Status

Check the current trust tier of an attestation (public, no API key needed):

status = client.status("att_1234")
print(f"Level: {status.level}")  # "T0", "T1", or "T2"
print(f"Signature: {status.signature_available}")
print(f"Merkle: {status.merkle_proof_available}")
print(f"OTS: {status.ots_available}")
Method Input Auth Best for
verify(hash) SHA-256 hash Optional Compliance checks, "does this hash exist?"
status(att_id) Attestation ID No Dashboards, progress tracking, polling
get_evidence(att_id) Attestation ID No Independent verification, long-term archival

Metadata Management

# Update claim metadata
result = client.update_metadata("att_1234", source="pipeline-v2", extra_data={"project": "alpha"})

# Soft-delete claim
client.delete_metadata("att_1234")

# Get evidence
evidence = client.get_evidence("att_1234")
print(evidence.level, evidence.t0)

Evidence & OTS Verification

import os
from certisigma import CertiSigmaClient, get_blockchain_url, save_ots_proof

client = CertiSigmaClient(api_key=os.environ["CERTISIGMA_API_KEY"])

# Get full cryptographic evidence (T0 + T1 + T2)
evidence = client.get_evidence("att_1234")

if evidence.level == "T2":
    # Bitcoin block explorer link
    print(get_blockchain_url(evidence))        # mempool.space/block/...
    print(get_blockchain_url(evidence, "tx"))   # mempool.space/tx/...

    # Save the raw .ots proof for independent verification
    save_ots_proof(evidence, "contract.pdf.ots")
    # Then verify with: ots verify contract.pdf.ots

Client-Side Encryption (Zero Knowledge)

Requires: pip install certisigma[crypto]

from certisigma.crypto import generate_key, encrypt_metadata, decrypt_metadata

# Generate a key (store securely — server never sees it)
key = generate_key()

# Encrypt before sending
encrypted = encrypt_metadata({"secret": "classified"}, key)
result = client.attest(hash_hex, extra_data=encrypted, client_encrypted=True)

# Decrypt after retrieving
plaintext = decrypt_metadata(result.extra_data, key)

Error Handling

from certisigma import (
    CertiSigmaError,
    AuthenticationError,
    RateLimitError,
    QuotaExceededError,
)

try:
    client.attest(hash_hex)
except AuthenticationError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after}s")
except QuotaExceededError:
    print("Monthly quota reached")
except CertiSigmaError as e:
    print(f"API error {e.status_code}: {e}")

Configuration

Parameter Default Description
api_key None Bearer token (cs_live_...). Optional for verify/health.
base_url https://api.certisigma.ch API endpoint
timeout 30.0 Request timeout in seconds

Proxy: httpx respects HTTP_PROXY / HTTPS_PROXY / NO_PROXY environment variables. Custom TLS CA: Configure httpx with verify="/path/to/ca-bundle.pem" for corporate proxies. Retry: Not built-in. Implement at caller level — retry only on 429 and 5xx, fail fast on other 4xx.

Share Tokens (Forensic Metadata Sharing)

Create time-limited, auditable tokens for sharing attestation metadata with forensic analysts:

token = client.create_share_token(
    attestation_ids=[42, 43, 44],
    expires_in=86400,
    recipient_label="forensic-analyst",
    max_uses=10,
)
print(f"Share token: {token.share_token}")  # shown once, save it

tokens = client.list_share_tokens()
client.revoke_share_token(token.id)

Structured Tagging

Multi-dimensional classification of attestations with server-side querying:

client.put_tags("att_42", tags=[
    {"key": "department", "value": "hr"},
    {"key": "classification", "value": "confidential"},
])

tags = client.get_tags("att_42")

results = client.query_tags(
    filter={"and": [
        {"key": "department", "value": "hr"},
        {"key": "classification", "value": "confidential"},
    ]},
    limit=100,
)
print(f"Found {results.count} matching attestations")

Read Metadata

Explicit metadata read without re-verifying:

meta = client.get_metadata("att_42")
print(f"Source: {meta.source}, Extra: {meta.extra_data}")

Security & Privacy

CertiSigma is a public attestation platform. Cryptographic proofs (hash, signature, Merkle, OTS) are intentionally public and verifiable by any party. Organizational metadata (source, extra_data) is never exposed on public endpoints — only the authenticated API key owner can read their own claim data. For sensitive metadata, use client-side encryption (encrypt_metadata()).

See the Security & Privacy Model in the full documentation for the complete threat model and data boundary.

Test Vectors

Canonical test vectors with real production data are available for independent T0/T1/T2 verification:

Compatibility

  • Follows Semantic Versioning 2.0.0.
  • SDK v1.x targets API v1 (/v1/ prefix). Breaking API changes get a new prefix with 12-month deprecation window.
  • See full SDK documentation for error codes, webhook semantics, T0 signature format, and compatibility policy.

Requirements

  • Python 3.10+
  • httpx >= 0.25.0
  • cryptography >= 44.0.0 (optional, for certisigma.crypto)

License

MIT — Ten Sigma Sagl, Lugano, Switzerland

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

certisigma-1.6.0.tar.gz (20.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

certisigma-1.6.0-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file certisigma-1.6.0.tar.gz.

File metadata

  • Download URL: certisigma-1.6.0.tar.gz
  • Upload date:
  • Size: 20.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for certisigma-1.6.0.tar.gz
Algorithm Hash digest
SHA256 4f08e40d9b5878af34607d3301ba1d64f6e6589d9a6bd471b32e1462d3193f5e
MD5 4938bfcd3977a1c12c3e785e5419fa4e
BLAKE2b-256 69e68ee85a518d33e724500a20219841bc5ea6e0f48fb6fa2c142021b4e08dc0

See more details on using hashes here.

File details

Details for the file certisigma-1.6.0-py3-none-any.whl.

File metadata

  • Download URL: certisigma-1.6.0-py3-none-any.whl
  • Upload date:
  • Size: 13.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for certisigma-1.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fffca440d79503329047c07544d0e76559b3d0d323221ab7faeea079dbead9b5
MD5 f4e44165887427c4d337b7e6fd37e2fd
BLAKE2b-256 ea37ba3ccf3cfa6ee9f989647c3e39e0bc178a42fd5177b3ae19ddc1d461e760

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page