Skip to main content

horizonpay-invoice-ai

The official Python SDK for the Invoice-AI API. It supports Python 3.10+, with a sync client (InvoiceAI) and an asyncio client (AsyncInvoiceAI), and depends only on httpx and pydantic.

pip install horizonpay-invoice-ai      # or: uv add horizonpay-invoice-ai
from invoice_ai import InvoiceAI

client = InvoiceAI()  # reads INVOICE_AI_API_KEY

customer = client.customers.create(name="Acme", email="ap@acme.com")
draft = client.invoices.create(customer=customer.id, items=[{"price": "price_…", "quantity": 1}])
client.invoices.finalize(draft.id)
client.invoices.send(draft.id)

for inv in client.invoices.list(status="open"):  # walks every page
    print(inv.number)

Async works the same way:

from invoice_ai import AsyncInvoiceAI

async with AsyncInvoiceAI() as client:
    invoice = await client.invoices.retrieve("in_…")
    async for inv in client.invoices.list(status="open"):
        print(inv.number)

What it handles for you

  • Retries. Network errors, timeouts, 408, 409 conflict, 429 and 5xx are retried up to max_retries (default 2). Backoff is exponential with jitter, and the SDK waits out Retry-After / RateLimit-Reset. A PATCH or DELETE that may have reached the server is never resent.
  • Idempotency. Every POST gets an Idempotency-Key, and retries reuse it, so a retried create can't run twice. To choose the key yourself, pass idempotency_key=....
  • Pagination. list() returns one page (data, next_cursor, has_more). Iterating it (for / async for) walks every page. .to_list(limit=500) collects a bounded number of items.
  • Errors. Each server code has its own exception: ValidationError (with .fields), InvalidStateError, NotFoundError, RateLimitError, IdempotencyError and the rest. They all extend APIError, which carries status, code, detail and request_id.
  • Webhooks. client.webhooks.construct_event(raw_body, headers, secret) (or Webhook(secret).verify(raw_body, headers)) verifies the Standard Webhooks signature and returns a typed WebhookEvent.
  • Money. Amounts are integers in minor units. to_minor("25.00", "USD"), from_minor(2500, "USD") (a Decimal) and format_money(5000, "JPY") use each currency's own number of decimals.
  • Types. Every response is a Pydantic v2 model generated from the OpenAPI spec (invoice_ai.types). Parsing is lenient: a field or enum value the SDK doesn't know yet never raises.

Every method takes keyword arguments, with path parameters first (client.invoices.void("in_…", reason="Duplicate")), plus the request options idempotency_key, timeout (in seconds, not milliseconds), max_retries and extra_headers. To read headers, use .with_raw_response:

raw = client.invoices.with_raw_response.retrieve("in_…")
raw.request_id; raw.rate_limit.remaining; raw.idempotent_replayed
invoice = raw.parse()

For endpoints the SDK doesn't wrap yet, use client.request("GET", "/business").

Verifying webhooks

Pass the raw request body to Webhook.verify (or client.webhooks.construct_event). A body that has been parsed and re-serialised as JSON won't match the signature. With FastAPI:

import os

from fastapi import FastAPI, HTTPException, Request
from invoice_ai import Webhook, WebhookVerificationError

app = FastAPI()
webhook = Webhook(os.environ["INVOICE_AI_WEBHOOK_SECRET"])  # whsec_…, from webhook_endpoints.create()


@app.post("/webhooks/invoice-ai")
async def invoice_ai_webhook(request: Request) -> dict[str, bool]:
    raw = await request.body()  # bytes, exactly as sent
    try:
        event = webhook.verify(raw, request.headers)
    except WebhookVerificationError as e:
        raise HTTPException(status_code=400, detail=str(e)) from e

    if event.type == "invoice.paid":
        print(f"{event.data.object.number} was paid")
    return {"received": True}

Deliveries can repeat, so deduplicate on event.id. For a standard-library version, see examples/verify_webhook.py.

Configuration

Option Env var Default
api_key INVOICE_AI_API_KEY —
base_url INVOICE_AI_BASE_URL https://invoice.horizonpay.co/api/v1
timeout 60 (seconds; a float, e.g. 2.5)
max_retries 2
log_level INVOICE_AI_LOG warn (debug logs each request to the invoice_ai logger, with secrets redacted)
http_client a new httpx.Client / httpx.AsyncClient
default_headers —

For runnable scripts, see examples/.

Development

The spec is the source of truth. After changing spec/openapi.json, run pnpm sdk:gen from the repo root. It regenerates invoice_ai/resources/, invoice_ai/types/, _operations.py and _meta.py; don't edit those by hand.

uv sync
uv run pytest                 # unit tests
uv run pytest -m contract     # every method against a Prism mock of the spec (needs npx)
uv run ruff check && uv run mypy invoice_ai

Metadata

Release files for horizonpay-invoice-ai 0.1.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 horizonpay-invoice-ai 0.1.0
File Size Uploaded
horizonpay_invoice_ai-0.1.0.tar.gz 44.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for horizonpay-invoice-ai 0.1.0
File Interpreter ABI Platform
horizonpay_invoice_ai-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 105.2 kB

Release files / horizonpay_invoice_ai-0.1.0.tar.gz

Download URL horizonpay_invoice_ai-0.1.0.tar.gz
Size 44.6 kB
Tags Source
SHA-256 checksum
How to use checksums
61042c3409091327e8fa0073908f765a6f310f83b518cdc4d94fe0174cb618ef
BLAKE2b-256 checksum
How to use checksums
8ac43f741fd1597cfb0c731e1fc9f3cc0c8335596d895b643ecf2fc261df45a0
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 Oct 4, 2026.

Transparency log

Release files / horizonpay_invoice_ai-0.1.0-py3-none-any.whl

Download URL horizonpay_invoice_ai-0.1.0-py3-none-any.whl
Size 60.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9e51e760e5675dbe33027ded962775ce2b80e6a6eb9d0dee681bfa1e4f1222bd
BLAKE2b-256 checksum
How to use checksums
bbf8af8883273cc6ec804fbb9371888a2be608993c457cb69d81b54e77e2a82b
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 Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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