invoicecraftly
Official Python client for the InvoiceCraftly Developer Document API.
Use it to generate an invoice PDF, check EN16931-core readiness, or prepare the currently supported EN16931-core XML artifact. The package is intentionally a thin HTTP client: InvoiceCraftly's API remains authoritative for invoice validation, calculations, readiness and rendering.
Status
Public beta client for InvoiceCraftly API v1. The package is published on PyPI and verified with clean public-registry installs.
Install
pip install invoicecraftly
Requirements
- Python 3.11 or newer
- an InvoiceCraftly Developer API key
- server-side code or another trusted environment where the API key can remain secret
Do not put an InvoiceCraftly API key in browser JavaScript, commit it to Git, or include it in public logs.
Generate a PDF
import os
from invoicecraftly import InvoiceCraftly
client = InvoiceCraftly(api_key=os.environ["INVOICECRAFTLY_API_KEY"])
invoice = {
"type": "invoice",
"number": "INV-1042",
"issueDate": "2026-09-05",
"dueDate": "2026-09-19",
"currency": "USD",
"seller": {
"name": "Fixture Seller Studio",
"addressLines": ["12 Render Way", "Austin, TX 73301", "United States"],
},
"buyer": {
"name": "Fixture Buyer Co",
"addressLines": ["400 Client Ave", "Denver, CO 80202", "United States"],
},
"items": [
{
"description": "Brand design retainer",
"quantity": 2,
"unitPrice": 150,
"taxRate": 8.25,
"taxLabel": "Sales Tax",
}
],
"payment": {
"iban": "DE89370400440532013000",
"reference": "INV-1042",
"terms": "Net 14",
},
}
result = client.documents.pdf(invoice)
result.write_to("invoice.pdf")
print(result.render_duration_ms, result.request_id)
The fictional fixture intentionally matches InvoiceCraftly's canonical developer example.
Check EN16931-core readiness
supplement = {
"version": 1,
"seller": {
"postalAddress": {
"countryCode": "NO",
"city": "Oslo",
"postalCode": "0154",
},
"taxId": {"role": "legal-registration", "schemeId": "0192"},
"vatIdentifier": "NO123456785MVA",
},
"lines": [{"sourceIndex": 0, "unitCode": "HUR", "vatCategoryCode": "S"}],
}
readiness = client.invoices.readiness({"document": invoice, "supplement": supplement})
if not readiness["ready"]:
print(readiness["gaps"])
This is the currently released EN16931-core readiness surface. It is not a Peppol BIS conformance or delivery claim.
Generate the currently supported structured XML
structured = client.documents.structured({"document": invoice, "supplement": supplement})
if structured["ready"] and structured["artifact"]:
print(structured["artifact"]["content"])
prepared is not sent: this client does not submit invoices to Peppol or another delivery network.
Error handling
from invoicecraftly import InvoiceCraftlyError
try:
result = client.documents.pdf(invoice)
except InvoiceCraftlyError as error:
print(error.status, error.code, error.request_id)
if error.retry_after_seconds is not None:
print(f"Retry after {error.retry_after_seconds:g}s")
Public API failures preserve HTTP status, public error code, request ID, details and Retry-After where available. Local transport failures use NETWORK_ERROR, REQUEST_TIMEOUT, or UNEXPECTED_RESPONSE.
Timeout policy
The default request timeout is 20 seconds. Override it on the client or one request:
client = InvoiceCraftly(
api_key=os.environ["INVOICECRAFTLY_API_KEY"],
timeout=15,
)
result = client.documents.pdf(invoice, timeout=30)
The first release line is synchronous and intentionally does not hide retries or background work.
Privacy and security
Calling the Developer Document API is remote processing initiated by your integration. The SDK itself has no telemetry and makes no tracking calls. It does not persist invoice bodies or PDFs; PdfResult.write_to(...) writes bytes only when your code explicitly asks it to.
Never post real invoice/customer/payment data in a public GitHub issue. See:
API compatibility
Package version and API version are separate. invoicecraftly 0.x targets the released InvoiceCraftly API v1 surface documented at https://invoicecraftly.com/developers/.
The client intentionally does not implement invoice totals, VAT rules, route decisions, EN16931 validation rules, Peppol logic, or delivery logic locally.
Development
python -m pip install -e .
python -m unittest discover -s tests -v
python -m compileall -q src
python -m pip install --upgrade build
python -m build
The package has zero runtime dependencies and ships a py.typed marker for type-checker discovery.
Releases
See RELEASE.md. Releases use .github/workflows/release.yml with PyPI Trusted Publishing/OIDC; no long-lived PyPI token is required in the repository.
Support
Use this repository's Issues tab for SDK bugs or documentation problems that contain no sensitive invoice data. For account-specific or sensitive matters, use InvoiceCraftly's contact/security routes instead of a public issue.
License
MIT
Metadata
Release files for invoicecraftly 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| invoicecraftly-0.1.1.tar.gz | 12.4 kB | With provenance | Details for invoicecraftly-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| invoicecraftly-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for invoicecraftly-0.1.1-py3-none-any.whl |
Total release size: 21.9 kB
Release files / invoicecraftly-0.1.1.tar.gz
| Download URL | invoicecraftly-0.1.1.tar.gz |
|---|---|
| Size | 12.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
926a4f506709447badcf8edb598a8ba95ae3575b53954d0d02ea7efa790d7fc5
|
|
BLAKE2b-256 checksum How to use checksums |
58798496b05215820c8e727b458ab752fdefc4e5f10ed648661ba77b25199f8e
|
| 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 8, 2026.
Transparency logRelease files / invoicecraftly-0.1.1-py3-none-any.whl
| Download URL | invoicecraftly-0.1.1-py3-none-any.whl |
|---|---|
| Size | 9.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9986eb2cbf14fa8520f06476ae91319b0468b18cc8c29c072af7ec1caf321090
|
|
BLAKE2b-256 checksum How to use checksums |
7e4772ce1ba67cfba361bc2c755f4ee3c3285b41a238d69228142914434b1454
|
| 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 8, 2026.
Transparency logSecurity for invoicecraftly 0.1.1
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.
Attestation for invoicecraftly-0.1.1.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 8, 2026.
Transparency logA 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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.