Skip to content

Client invoices

Client invoices are the agency-billing surface: draft, issue, pay, void, and render an invoice for a client account.

Generated from contract version 1.0.0 — the same document /v1/api/openapi.json serves.

  • An API key in x-api-key, or a browser session cookie
  • X-Organization-Id naming the workspace to act in, unless the session already has an active one
  • 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.

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.

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 bodyapplication/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.

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 bodyapplication/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.

Responses

Status Body Description
200 string (binary) The agency’s logo AS IT WAS AT ISSUE — not the workspace’s current one. The Content-Type is the format recorded on the invoice, accompanied by 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 bodyapplication/json, PayInvoice (required)

The contract does not pin this body’s properties.

Responses

Status Body Description
200 ClientInvoice The settled invoice. This is an OUT-OF-BAND settlement — an agency member asserting money arrived somewhere hlix cannot see — recorded under its own audit action so it is never confused with provider-verified payment. Any outstanding hosted checkout is cancelled, so the invoice cannot also be paid 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.

Request bodyapplication/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 the provider’s reference for it — and nothing else. No card field, no payment token and no credential of any kind crosses this boundary: the payer enters those on the provider’s own page. Calling this does NOT mark the invoice paid. A PROVIDER payment settles the invoice only through the provider’s signed webhook, reconciled on amount, currency and invoice id; the one other route to paid is POST /:id/pay, an audited out-of-band settlement recorded by an agency member under its own audit action.
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.

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 bodyapplication/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 one KEEPS its number — a hole in the sequence reads as a deleted document. Corrections are a replacement invoice naming this one, never an edit.
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.

These apply to every operation on this page.

  • 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 — no such resource in this workspace. Absent and not-visible are deliberately the same answer; do not infer cross-tenant existence from it.
  • 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.