Skip to main content

CertySign Trust Services SDK — sign, verify, and manage digital signatures

Project description

CertySign SDK — Python

PyPI version Python 3.8+

Official Python SDK for the CertySign Trust Services platform. Mirrors the @certysign/sdk Node.js package feature-for-feature.

Privacy-first: Your documents never leave your infrastructure. Only cryptographic hashes are transmitted to the API.


Installation

pip install certysign-sdk

For PAdES PDF signing with TSA timestamp support:

pip install "certysign-sdk[asn1]"

Quick start

from certysign_sdk import CertySignClient

client = CertySignClient(
    public_key="YOUR_API_KEY_ID",
    secret_key="YOUR_API_KEY_SECRET",
    environment="staging",
)

# Optional: check that the configured key can reach the API
status = client.ping()
print(status["success"])

Core workflows

1 — Hash-based signing (recommended)

The document never leaves your server.

# Hash raw document bytes locally and send only the hash
result = client.sign.hash_and_sign(
    document=open("invoice.pdf", "rb").read(),
    file_name="invoice.pdf",
    reason="Invoice approval",
)

If you already computed the hash yourself, use sign_hash() instead:

doc_hash = client.hasher.hash_file("invoice.pdf")

result = client.sign.sign_hash(
    document_hash=doc_hash["hash"],
    hash_algorithm=doc_hash["algorithm"],
    file_name="invoice.pdf",
)

2 — Local PDF signature embedding (PAdES)

with open("invoice.pdf", "rb") as f:
    pdf_bytes = f.read()

signed_pdf = client.embedder.embed_in_pdf(
    pdf_bytes,
    reason="Invoice approval",
    sign_callback=lambda h: client.sign.sign_hash(
        document_hash=h,
        hash_algorithm="sha256",
    ),
)

with open("invoice-signed.pdf", "wb") as f:
    f.write(signed_pdf)

3 — PAdES B-T (with RFC 3161 timestamp)

client = CertySignClient(
    public_key="...",
    secret_key="...",
    tsa_url="https://tsa.certysign.io",  # upgrades to PAdES B-T automatically
)

signed_pdf = client.embedder.embed_in_pdf(pdf_bytes, sign_callback=...)

4 — XML signing (XMLDSig enveloped)

with open("document.xml") as f:
    xml_content = f.read()

# Hash and sign
doc_hash = client.hasher.hash(xml_content.encode())
result = client.sign.sign_hash(
    document_hash=doc_hash["hash"],
    hash_algorithm=doc_hash["algorithm"],
)

# Embed signature
signed_xml = client.embedder.embed_in_xml(
    xml_content,
    signature=result["data"]["signature"],
    certificate=result["data"]["certificate"],
    document_hash=doc_hash["hash"],
)

5 — JSON signing

payload = {"amount": 1500, "currency": "USD", "recipient": "Alice"}
doc_hash = client.hasher.hash(json.dumps(payload).encode())
result = client.sign.sign_hash(document_hash=doc_hash["hash"])

signed_envelope = client.embedder.embed_in_json(
    payload,
    signature=result["data"]["signature"],
    certificate=result["data"]["certificate"],
)

6 — Signature envelope workflow (multi-recipient)

# Create envelope
envelope = client.envelopes.create(
    title="Service Agreement",
    signers=[
        {"email": "alice@example.com", "name": "Alice"},
        {"email": "bob@example.com", "name": "Bob"},
    ],
)

# Upload documents
client.envelopes.upload_documents(
    envelope["data"]["id"],
    [{"name": "agreement.pdf", "data": open("agreement.pdf", "rb").read()}],
)

# Send to signers
client.envelopes.send(envelope["data"]["id"])

7 — Signing sessions (OTP verification)

session = client.sessions.create(
    envelope_id=envelope_id,
    recipients=[{"email": "alice@example.com"}],
)

# Trigger OTP delivery
client.sessions.send_otp(session["data"]["id"], recipient_id)

# Verify OTP and sign
client.sessions.verify_otp(session["data"]["id"], recipient_id, "123456")
client.sessions.recipient_sign(session["data"]["id"], recipient_id, signing_token)

API Reference

CertySignClient

Parameter Type Default Description
public_key str required X-API-Key-Id header value
secret_key str required X-API-Key-Secret header value
environment str 'production' 'production' | 'staging' | 'development' | 'test'
base_url str None Override API base URL completely
timeout int 30 HTTP timeout in seconds
retries int 3 Max retries for transient failures
debug bool False Verbose request logging
tsa_url str None TSA service URL for PAdES-T timestamps

Resources

Property Class Description
client.sign HashSigningResource Hash-based signing (recommended)
client.certificates CertificateResource Certificate lifecycle
client.pki PkiResource CRL, OCSP, chain, info
client.envelopes EnvelopeResource Signature envelopes
client.sessions SigningSessionResource OTP-verified signing sessions
client.dashboard DashboardResource Analytics
client.hasher DocumentHasher Local hashing (no network)
client.embedder SignatureEmbedder Local signature embedding (no network)
client.legacy_sign SigningResource Legacy upload-based signing

DocumentHasher

from certysign_sdk.utils import DocumentHasher

hasher = DocumentHasher()

# Hash bytes
result = hasher.hash(b"hello world")
# → {"hash": "b94d27b9...", "algorithm": "sha256", "size": 11}

# Hash a file
result = hasher.hash_file("document.pdf")
# → {"hash": "...", "algorithm": "sha256", "size": 204800, "file_name": "document.pdf"}

# Hash many documents
results = hasher.hash_many([b"doc1", b"doc2"])

# Hash multiple files
results = hasher.hash_files(["a.pdf", "b.pdf"])

Supported algorithms: sha256 (default), sha384, sha512.


SignatureEmbedder

from certysign_sdk.utils import SignatureEmbedder

embedder = SignatureEmbedder(tsa_url="https://tsa.certysign.io")

# PDF (PAdES)
signed_pdf = embedder.embed_in_pdf(pdf_bytes, sign_callback=my_sign_fn)

# XML (XMLDSig enveloped)
signed_xml = embedder.embed_in_xml(xml_str, signature="...", certificate="...")

# JSON (signed envelope)
signed_json = embedder.embed_in_json(data, signature="...", certificate="...")

Error handling

from certysign_sdk import CertySignError

try:
    result = client.sign.hash_and_sign(document_hash="...")
except CertySignError as e:
    print(f"Status: {e.status_code}, Code: {e.code}, Message: {e}")
    print(f"Details: {e.details}")

Environments

environment Base URL
production https://core.certysign.io
staging https://service.certysign.io
development http://localhost:8000
test http://localhost:8000

License

MIT © CertySign Trust Services

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

certysign_sdk-1.3.0.tar.gz (36.1 kB view details)

Uploaded Source

Built Distribution

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

certysign_sdk-1.3.0-py3-none-any.whl (35.2 kB view details)

Uploaded Python 3

File details

Details for the file certysign_sdk-1.3.0.tar.gz.

File metadata

  • Download URL: certysign_sdk-1.3.0.tar.gz
  • Upload date:
  • Size: 36.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for certysign_sdk-1.3.0.tar.gz
Algorithm Hash digest
SHA256 646d74bdd7e6475133a7f6309d15dec66e216a9fdcd962f992bd548bb4ecfa43
MD5 87da855113ab1c522afde79f56cd8697
BLAKE2b-256 2f02cf33d90f10ff67fe9525de634ced2978d98f3cf3dd87d93c4682af614dad

See more details on using hashes here.

File details

Details for the file certysign_sdk-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: certysign_sdk-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 35.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for certysign_sdk-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3eab8dd5dd9312b2fe1f0aa8ebeb6d4ff46220703012d29cc61e0f20e50507b9
MD5 2c0b7004739904d1edc3da01de5184bd
BLAKE2b-256 0a92c96bb13b9f481e707f32addc17112e2ac663b584e2273eeea945332fcbd2

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