Python SDK
The official Python SDK is published as docjet on PyPI. Python 3.10+, fully typed (ships py.typed), one dependency (httpx).
Install
Section titled “Install”pip install docjetRender a PDF
Section titled “Render a PDF”from docjet import DocJetClient
client = DocJetClient(api_key="binfra_your_key")
# Returns a signed download URLresult = client.render( template_id="invoice-ro", data={"client": "Demo SRL", "total": 1000},)print(result["url"])Pass html=... instead of template_id=... to render your own HTML (max 512 KB).
Full surface
Section titled “Full surface”client.render(template_id=..., data=..., options=...) # PDF -> {"url": ...}client.render_image(template_id=..., data=...) # PNG -> {"url": ...}client.list_templates() # public, no authclient.usage() # current-period usageVerify webhook signatures
Section titled “Verify webhook signatures”Async DocJet callbacks are signed with X-DocJet-Signature: t=<unix-seconds>,v1=<hmac-sha256-hex>. Verify in one call — constant-time comparison and a 5-minute replay window included:
from docjet import verify_webhook_signature
# Flask example — works the same in FastAPI, Django, etc.@app.post("/webhooks/docjet")def docjet_webhook(): raw_body = request.get_data(as_text=True) # RAW body, before JSON parsing header = request.headers.get("X-DocJet-Signature", "")
if not verify_webhook_signature(raw_body, header, WEBHOOK_SECRET): return "invalid signature", 400
payload = json.loads(raw_body) # now safe to trust return "", 204- Get your signing secret:
GET /v1/keys/webhook-secret - Pass the raw request body — verifying a re-serialized body will fail
- Tampered, expired (>300 s old), or malformed signatures return
False - Custom tolerance:
verify_webhook_signature(body, header, secret, tolerance_seconds=600)
Error handling
Section titled “Error handling”Non-2xx responses raise DocJetError with the API error code and HTTP status:
from docjet import DocJetClient, DocJetError
try: client.render(template_id="invoice-ro", data={})except DocJetError as e: print(e.code) # e.g. "QUOTA_EXCEEDED" print(e.status_code) # e.g. 429Invalid template_id values are rejected locally (no network call) — template IDs must match ^[a-z0-9][a-z0-9-]{0,63}$. See Errors & limits for the full taxonomy.