Skip to content

Client invoices

Client invoices operations in the Hlix API.

Client invoices are invoices an agency issues to its client accounts. These operations create drafts, issue and void invoices, render PDFs, open provider-hosted checkouts and record out-of-band settlements.

See the OpenAPI document for schemas and operation IDs.

  • Protected operations require an API key in x-api-key or a browser session cookie; some actions require a verified user session
  • Tenant-scoped operations use X-Organization-Id; browser sessions can use their active workspace. Discovery and personal-workspace bootstrap do not require an active workspace
  • The base URL for your deployment, https://server.hlix.ai by default
Method Path Operation
GET /v1/api/client-billing/invoices List invoices
POST /v1/api/client-billing/invoices Assemble a draft invoice from billables
GET /v1/api/client-billing/invoices/{id} Get one invoice with its lines
POST /v1/api/client-billing/invoices/{id}/issue Issue a draft, assigning its number
GET /v1/api/client-billing/invoices/{id}/logo Download the logo frozen onto this invoice
POST /v1/api/client-billing/invoices/{id}/pay Record an out-of-band settlement (bank transfer, cheque)
POST /v1/api/client-billing/invoices/{id}/payment-link Open a provider-hosted checkout for an issued invoice
GET /v1/api/client-billing/invoices/{id}/pdf Download the invoice as a PDF
POST /v1/api/client-billing/invoices/{id}/void Withdraw an invoice, or discard a draft

GET /v1/api/client-billing/invoices · operation ID listClientInvoices

Parameters

Name In Required Type Description
clientAccountId query no string Only this customer’s invoices.
status query no string One of draft, final, void, paid.
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.
X-Client-Portal header no string The agency Workspace ID for a signed-in client’s portal requests. A verified user session and portal membership are required; API keys cannot authenticate portal access. This header does not grant agency administration access.

Responses

Status Body Description
200 ClientInvoice[] Invoice headers, newest first. lines is empty on this projection — read one invoice to get them.
400 ApiError The request named no active organization.
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator. Invoices are agency-only, reads included.
404 ApiError The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist.

POST /v1/api/client-billing/invoices · operation ID createClientInvoiceDraft

Parameters

Name In Required Type Description
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.

Request body — application/json, CreateInvoiceDraft (required)

Property Type Required Notes
billableIds string[] yes
buyerAddress string yes min length 1, max length 500
buyerBillingEmail string (email) | null no
buyerLegalName string no min length 1, max length 200
dueAt string (date-time) yes
paymentTerms string no min length 1, max length 200
replacesInvoiceId string | null no
sellerAddress string no min length 1, max length 500
sellerLegalName string no min length 1, max length 200
taxRatesBps object no

Responses

Status Body Description
201 ClientInvoice The draft, with its lines snapshotted from the ledger and its totals computed once and stored.
400 ValidationError | ApiError The JSON body failed schema validation (ValidationError), or the request named no active organization (ApiError).
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator. Invoices are agency-only, reads included.
404 ApiError A named billable or the client account is not this workspace’s.
409 ApiError The set cannot be invoiced: it spans two customers or two currencies, a charge nets to zero, a tax class has no rate, a correction’s charge was never invoiced, or the total would exceed what an invoice can represent. The message names which.
422 ApiError A database constraint refused the draft.

GET /v1/api/client-billing/invoices/{id} · operation ID getClientInvoice

Parameters

Name In Required Type Description
id path yes string
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.
X-Client-Portal header no string The agency Workspace ID for a signed-in client’s portal requests. A verified user session and portal membership are required; API keys cannot authenticate portal access. This header does not grant agency administration access.

Responses

Status Body Description
200 ClientInvoice The invoice and every line it was built from.
400 ApiError The request named no active organization.
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator. Invoices are agency-only, reads included.
404 ApiError No such invoice in this workspace. Never a 403 — ‘forbidden’ would confirm that an invoice exists for a customer the caller was never shown.

POST /v1/api/client-billing/invoices/{id}/issue · operation ID issueClientInvoice

Parameters

Name In Required Type Description
id path yes string
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.

Request body — application/json, IssueInvoice (required)

The contract does not pin this body’s properties.

Responses

Status Body Description
200 ClientInvoice The issued invoice. invoiceNumber and invoiceSequence are assigned by the database at this moment and are gapless per workspace.
400 ValidationError | ApiError The JSON body failed schema validation (ValidationError), or the request named no active organization (ApiError).
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator. Invoices are agency-only, reads included.
404 ApiError No such invoice in this workspace. Never a 403 — ‘forbidden’ would confirm that an invoice exists for a customer the caller was never shown.
409 ApiError Not issuable: already issued, no lines, the header does not reconcile with its lines, a charge on it is already invoiced, or a correction of one is missing from it.
422 ApiError A database constraint refused the issue.

Download the logo frozen onto this invoice

Section titled “Download the logo frozen onto this invoice”

GET /v1/api/client-billing/invoices/{id}/logo · operation ID getClientInvoiceLogo

Parameters

Name In Required Type Description
id path yes string
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.
X-Client-Portal header no string The agency Workspace ID for a signed-in client’s portal requests. A verified user session and portal membership are required; API keys cannot authenticate portal access. This header does not grant agency administration access.

Responses

Status Body Description
200 string (binary) The agency logo frozen when the invoice was issued. Content-Type matches the format recorded on the invoice, with X-Content-Type-Options: nosniff.
400 ApiError The request named no active organization.
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator. Invoices are agency-only, reads included.
404 ApiError No such invoice, or it carries no logo.

Record an out-of-band settlement (bank transfer, cheque)

Section titled “Record an out-of-band settlement (bank transfer, cheque)”

POST /v1/api/client-billing/invoices/{id}/pay · operation ID payClientInvoice

Parameters

Name In Required Type Description
id path yes string
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.

Request body — application/json, PayInvoice (required)

The contract does not pin this body’s properties.

Responses

Status Body Description
200 ClientInvoice The invoice settled through an audited out-of-band payment recorded by an agency member. This is separate from provider-verified payment. Any open hosted checkout is cancelled to prevent a second payment through the provider.
400 ValidationError | ApiError The JSON body failed schema validation (ValidationError), or the request named no active organization (ApiError).
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator. Invoices are agency-only, reads included.
404 ApiError No such invoice in this workspace. Never a 403 — ‘forbidden’ would confirm that an invoice exists for a customer the caller was never shown.
409 ApiError Only an issued, unpaid invoice can be settled.
422 ApiError A database constraint refused the payment.

Open a provider-hosted checkout for an issued invoice

Section titled “Open a provider-hosted checkout for an issued invoice”

POST /v1/api/client-billing/invoices/{id}/payment-link · operation ID createClientInvoicePaymentLink

Parameters

Name In Required Type Description
id path yes string
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.
X-Client-Portal header no string The agency Workspace ID for a signed-in client’s portal requests. A verified user session and portal membership are required; API keys cannot authenticate portal access. This header does not grant agency administration access.

Request body — application/json, PaymentLink (required)

Property Type Required Notes
successUrl string (uri) no max length 2000

Responses

Status Body Description
200 ClientPaymentLink A provider-hosted checkout URL and its payment reference. Payment details are entered on the provider’s page and are not returned by this endpoint. Creating a checkout does not mark the invoice paid. Provider payments settle only after a signed webhook is reconciled against the invoice ID, amount and currency. An agency member can separately record an audited out-of-band settlement through POST /v1/api/client-billing/invoices/{id}/pay.
400 ValidationError | ApiError The JSON body failed schema validation (ValidationError), or the request named no active organization (ApiError).
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator attempting something other than reading or paying its own invoice.
404 ApiError No such invoice in this workspace. Never a 403 — ‘forbidden’ would confirm that an invoice exists for a customer the caller was never shown.
409 ApiError Not payable: the invoice is a draft, void or already paid, it already has a checkout open with a different provider, or its total is above what the provider will take in one payment.
501 ApiError No payment provider is connected for this deployment. The invoice can still be issued, sent and paid outside hlix.

GET /v1/api/client-billing/invoices/{id}/pdf · operation ID getClientInvoicePdf

Parameters

Name In Required Type Description
id path yes string
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.
X-Client-Portal header no string The agency Workspace ID for a signed-in client’s portal requests. A verified user session and portal membership are required; API keys cannot authenticate portal access. This header does not grant agency administration access.

Responses

Status Body Description
200 string (binary) The rendered invoice, every line included.
400 ApiError The request named no active organization.
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator. Invoices are agency-only, reads included.
404 ApiError No such invoice in this workspace. Never a 403 — ‘forbidden’ would confirm that an invoice exists for a customer the caller was never shown.
409 ApiError The invoice is a draft, or its stored totals no longer reconcile with its stored lines. Rendering a document that does not add up is refused rather than attempted.
415 ApiError The invoice is valid but this renderer cannot encode it — a party name or line description outside Latin-1. Retrying will not help; read the invoice through getClientInvoice instead.

POST /v1/api/client-billing/invoices/{id}/void · operation ID voidClientInvoice

Parameters

Name In Required Type Description
id path yes string
X-Organization-Id header no string The workspace (organization) to act in. Omitted, the session’s active organization is used.

Request body — application/json, VoidInvoice (required)

Property Type Required Notes
reason string yes min length 1, max length 500

Responses

Status Body Description
200 ClientInvoice The voided invoice. An issued invoice retains its number. To correct it, issue a replacement invoice referencing the original.
400 ValidationError | ApiError The JSON body failed schema validation (ValidationError), or the request named no active organization (ApiError).
401 ApiError No valid session or API key.
403 ApiError The caller is a client collaborator. Invoices are agency-only, reads included.
404 ApiError No such invoice in this workspace. Never a 403 — ‘forbidden’ would confirm that an invoice exists for a customer the caller was never shown.
409 ApiError The invoice is already void.
422 ApiError A database constraint refused the void.

The response table for each operation lists its documented errors. Common status codes include:

  • 400 — the body failed schema validation, or the request named no active organization. A ValidationError body carries the failing fields; an ApiError body carries only error.
  • 401 — no valid session or API key.
  • 403 — authenticated, but not a member of the named organization, or a client collaborator without the required access.
  • 404 — check the resource ID and your access to the selected Workspace.
  • 409 — the expected revision or state is stale, or another operation currently owns the transition.
  • 500 — the operation failed server-side. Retry only where an idempotency key makes that safe.