CertySign Trust Services SDK — sign, verify, and manage digital signatures
Project description
CertySign SDK — Python
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
646d74bdd7e6475133a7f6309d15dec66e216a9fdcd962f992bd548bb4ecfa43
|
|
| MD5 |
87da855113ab1c522afde79f56cd8697
|
|
| BLAKE2b-256 |
2f02cf33d90f10ff67fe9525de634ced2978d98f3cf3dd87d93c4682af614dad
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3eab8dd5dd9312b2fe1f0aa8ebeb6d4ff46220703012d29cc61e0f20e50507b9
|
|
| MD5 |
2c0b7004739904d1edc3da01de5184bd
|
|
| BLAKE2b-256 |
0a92c96bb13b9f481e707f32addc17112e2ac663b584e2273eeea945332fcbd2
|