Skip to main content

TrustBeat Python SDK

Qualified electronic timestamps and Merkle anchoring — eIDAS-compliant, over a simple API.

Part of TrustBeat — digital trust infrastructure for the EU. All SDKs (Python, TypeScript, Java, C#, Go): trustbeat.eu/sdks.

Install

pip install trustbeat

Quickstart

from trustbeat import TrustBeat

tb = TrustBeat(api_key="tb_live_...")

# Anchor a file (SHA-256 computed locally, file never leaves your machine).
# anchor_file_wait() blocks until the proof is ready (next batch, up to 11 min).
proof = tb.anchor_file_wait("contract.pdf")
print(proof.id)           # tracking ID
print(proof.anchored_at)  # ISO 8601 timestamp
print(proof.merkle_root)  # Merkle root of the batch

# Verify locally — no network call
assert tb.verify(proof)

# Or anchor a raw SHA-256 hash without blocking, then wait for the proof.
job = tb.anchor("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
print(job.id)                   # tracking ID, returned immediately (202)
proof = tb.anchor_wait(job.id)  # blocks up to 11 min

Tamper-Evident Logs (NIS2)

Anchor a log hash together with canonical metadata for NIS2 Article 21 audit trails. The server seals your metadata into the Merkle leaf, so the proof covers both the log content and its context.

import hashlib
from trustbeat import TrustBeat, LogMetadata, LogSource, LogSourceIdentity, LogTimeEnvelope

tb = TrustBeat(api_key="tb_live_...")

# Hash the log yourself — content never leaves your machine.
with open("app.log", "rb") as f:
    log_hash = hashlib.sha256(f.read()).hexdigest()

job = tb.anchor_log(
    log_hash,
    LogMetadata(
        log_source=LogSource(uri="/var/log/app.log", name="Application log"),
        source_identity=LogSourceIdentity(hostname="web-01", service_name="payments"),
        time_envelope=LogTimeEnvelope(start_at="2026-04-15T00:00:00Z",
                                      end_at="2026-04-15T23:59:59Z"),
    ),
    label="incident-2026-05",
)
print(job.id, job.combined_hash)

# Wait for the qualified anchor (next batch, up to 11 min), then verify locally.
proof = tb.anchor_log_wait(job.id)
assert proof.verification_status == "VERIFIED"
assert tb.verify(proof.proof)

Webhooks

If your account has a webhook secret configured, every delivery is signed with an X-TrustBeat-Signature header. Verify it with the raw request body — before any JSON parsing:

from trustbeat import verify_webhook_signature

# e.g. in a Flask/FastAPI handler; body must be the raw bytes as received
if not verify_webhook_signature(raw_body, signature_header, webhook_secret):
    raise ValueError("Invalid webhook signature")

Also available as TrustBeat.verify_webhook_signature(...). Rejects replays older than 5 minutes by default (tolerance_secs to override).

Portable proof bundles for offline verification: export_ai_decision(id), export_verification(id), export_log(id) — each returns raw JSON bundle bytes.

Batches and rate limits

A batch carries up to 1,000 hashes and is all-or-nothing: if the call fails, none of them was queued. (API servers deployed before 26 Sep 2026 accept at most 100.)

Anchoring is rate-limited per account (see your plan). A rate-limited request (HTTP 429) is retried automatically, waiting the Retry-After the server sends — twice by default. Retrying is always safe: a refused submission was never queued. When the retries run out you get the rate-limit error, carrying the wait the server asked for.

from trustbeat import TrustBeat, RateLimitError

tb = TrustBeat(api_key="tb_live_...", max_retries=2)   # 0 turns retrying off

try:
    submission = tb.anchor_batch(hashes)               # up to 1,000
except RateLimitError as e:
    print(f"still limited; server asked to wait {e.retry_after} s")

Requirements

  • Python 3.9+
  • Zero runtime dependencies (stdlib only)

Documentation

Full API reference and guides at api.trustbeat.eu/docs

License

MIT — see LICENSE

Merkle algorithm

Every proof declares how it must be folded, in proof.merkle_algorithm:

Value Construction
trustbeat-legacy-sha256 leaf = your hash, parent = SHA-256(left || right)
rfc6962-sha256 leaf = SHA-256(0x00 || hash), parent = SHA-256(0x01 || left || right)

verify() dispatches on it for you. A proof with no label was issued before the field existed and is legacy. If a proof declares an algorithm this SDK version does not implement, verify() raises UnsupportedAlgorithmError rather than returning False — "cannot check" is not "invalid".

from trustbeat import UnsupportedAlgorithmError

try:
    ok = tb.verify(proof)
except UnsupportedAlgorithmError:
    # This SDK is older than the proof. Upgrade, or check it server-side.
    raise

Audit event proofs

verify_audit_event() folds an audit event proof the same way:

from trustbeat import IncompleteProofError

proof = tb.get_audit_event_proof(event_id)
try:
    assert tb.verify_audit_event(proof)
except IncompleteProofError:
    # The server predates API 1.46 and sent no merkle_root, so there is nothing
    # to fold against. The proof is not invalid — verify it server-side instead.
    pass

Treating that exception as a failed proof would be wrong: it means "cannot check", not "tampered".

Metadata

Release files for trustbeat 0.5.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 trustbeat 0.5.0
File Size Uploaded Provenance
trustbeat-0.5.0.tar.gz 38.9 kB With provenance Details

Built distribution (wheel)

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

Total release size: 64.3 kB

Release files / trustbeat-0.5.0.tar.gz

Download URL trustbeat-0.5.0.tar.gz
Size 38.9 kB
Tags Source
SHA-256 checksum
How to use checksums
5bc68506630f36741bbbd16569a27734fa547d1a377181968359c8cf6150a34a
BLAKE2b-256 checksum
How to use checksums
e9f50c048f71812ba5c16bbf0b9a1985e2a850674a4f3d5daebb805c8e785fa3
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 27, 2026.

Transparency log

Release files / trustbeat-0.5.0-py3-none-any.whl

Download URL trustbeat-0.5.0-py3-none-any.whl
Size 25.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
826858e660da86fb16dd48a68e216c77bf97d2d64a68e1006fd5dcdf68baea10
BLAKE2b-256 checksum
How to use checksums
01652ce6318e9be22ac2f8a7eb31fc13e0eaccee5e3ea2dc1b45eecab25af32b
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 27, 2026.

Transparency log

Security for trustbeat 0.5.0

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 trustbeat-0.5.0.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 Sep 27, 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.

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