Skip to main content

Timbro Invoices for Python

timbro-invoices is the Python client for the canonical /v1/invoices API. Invoice request and response wire shapes are defined by the Timbro API; the installed package carries a generated projection of that contract.

Requires Python 3.10 or later.

pip install timbro-invoices

Compatibility

timbro-invoices 0.9 belongs to the same compatible set as @timbro/payments, @timbro/invoices, and @timbro/protocol 0.9. Packages that share a minor version work together.

The client validates requests strictly and accepts additional properties in responses. Timbro may add a property to a response, at any depth and in any union variant, without a breaking release; the client ignores what it does not know and returns it unchanged. Required fields, types, formats, and enum values stay enforced, so removing or renaming a field, or adding a value to an existing enum, is a breaking change. An unknown webhook event type is returned to you, after the envelope and scope checks, instead of raising.

from timbro_invoices import TimbroInvoices

client = TimbroInvoices(api_key="your-invoice-api-key")
preview = client.preview_invoice(invoice_request)
invoice = client.create_invoice(invoice_request)
current = client.retrieve_invoice(invoice["id"])
page = client.list_invoices(invoice_reference="odoo:2026:1042")
xml = client.download_xml(invoice["id"])
pdf = client.download_pdf(invoice["id"])

# Replace a retained, replaceable Invoice with a new canonical request.
replacement = client.replace_invoice(
    rejected_invoice["id"],
    {**invoice_request, "invoiceReference": "odoo:2026:1042-r1"},
)

# Share an accepted receipt with a payment service.
receipt_access = client.share_receipt(invoice["id"])
receipt = client.retrieve_receipt(receipt_access)
receipt_pdf = client.download_receipt_pdf(receipt_access)

Keep the receipt access grant on your server and pass it to the receiving service over an authenticated channel. Restricted reads use its accessToken; the token is never sent in the URL and grants access only to receipt data and its PDF. Receipt PDF downloads verify the Invoice identity, media type, and SHA-256 headers. Other file downloads also verify Timbro's security metadata. HTTP problems preserve Timbro's status and machine-readable code. The distribution uses jsonschema and regex to validate data against the generated OpenAPI contract.

A 422 admission refusal has no retained Invoice ID. Correct the request and call create_invoice; replace_invoice applies to a retained replaceable Invoice. Authority-rejected numbering gaps still require the existing administrator authorization. A replacement retains the predecessor's Source ID, uses a new Source version and invoiceReference, and exposes its predecessor in replacesInvoiceId.

Deliveries

Email an Invoice to its buyer and read the delivery back. Retrying with the same idempotency key (16 to 255 characters from A-Z, a-z, 0-9, ., _, :, and -) returns the same delivery. retrieve_delivery returns None when Timbro has no such delivery for the Invoice.

delivery = client.create_delivery(
    invoice["id"],
    recipient_email="buyer@example.do",
    idempotency_key="delivery-order-1042-0001",
    account_claim_url="https://example.do/account/claim",  # optional, https only
)
current = client.retrieve_delivery(invoice["id"], delivery["id"])

Webhooks

verify_webhook_signature checks the Standard Webhooks signature over the original request bytes. parse_invoice_webhook_event does not check the signature, so call the verifier first. The parser then checks the event envelope against the generated contract and confirms that the event belongs to your organization, environment, and Source connection. An event type that this package version does not know is returned as an UnknownInvoiceWebhookEvent instead of raising; is_known_invoice_webhook_event narrows the result for type checkers.

verify_webhook_signature(body, headers, signing_secret)
event = parse_invoice_webhook_event(
    body, message_id=headers["webhook-id"], organization_id=organization_id,
    environment="production", source_connection_id=source_connection_id,
)
if is_known_invoice_webhook_event(event) and event["type"] == "invoice.accepted":
    ...

Errors and validation

  • InvalidInvoiceRequest, a ValueError, is raised before any request is sent when a request does not match the contract. Its path attribute names the failing field as a JSON path, for example $.items[0].quantity; a failure on a method argument, such as idempotency_key, names the argument instead. The message never contains the rejected value.
  • TimbroHttpError carries Timbro's status, machine-readable code, request_id, and problems. A response that breaks the contract raises it with the code invalid_invoice_response.
  • validate_contract_schema(name, value) validates a value strictly against a named schema of the generated contract and raises SchemaValidationError, a ValueError with a path. Use it to check a payload before you store or queue it.
  • InvalidWebhook is raised for a bad signature or signing secret, a malformed envelope, or an event outside your organization, environment, or Source connection.

Development

Regenerate the contract projection with python python-sdk/scripts/generate_contract.py. Run the contract check and the package tests in a temporary virtual environment with python python-sdk/scripts/verify.py, or run only the tests with PYTHONPATH=python-sdk python -m unittest discover -s python-sdk/tests. Add --wheel path/to/timbro_invoices-0.9.0-py3-none-any.whl to verify.py to test a built wheel instead of the source tree.

Metadata

Release files for timbro-invoices 0.9.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 timbro-invoices 0.9.0
File Size Uploaded
timbro_invoices-0.9.0.tar.gz 40.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for timbro-invoices 0.9.0
File Interpreter ABI Platform
timbro_invoices-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 74.3 kB

Release files / timbro_invoices-0.9.0.tar.gz

Download URL timbro_invoices-0.9.0.tar.gz
Size 40.2 kB
Tags Source
SHA-256 checksum
How to use checksums
424b08571ce2802c0a1aac39f35eb967356cfb965921be63a8b245b9fdd7616b
BLAKE2b-256 checksum
How to use checksums
8107a603d948da7afd4f030ed3666349e60a261d553066b839c47f4fc54ff009
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / timbro_invoices-0.9.0-py3-none-any.whl

Download URL timbro_invoices-0.9.0-py3-none-any.whl
Size 34.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad8db61da34d06edca981663c85156addc72a5588db238168bfbb2a1fd35417c
BLAKE2b-256 checksum
How to use checksums
dd00fd276c499bbfb52506beeba8d4db6b213f0dfe0ff6384ed02b82d3890260
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4
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