> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wellapp.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoice

> Invoice is the core billing document entity in Well, representing receivable and payable documents (commercial invoices, credit notes, purchase orders, receipts

Invoice is the core billing document entity in Well, representing receivable and payable documents (commercial invoices, credit notes, purchase orders, receipts, and related document types) extracted from uploaded files or ingested via connector syncs. It links two Company parties (issuer and receiver) within a Workspace, carries multi-currency financial totals with FX normalization, and tracks both a lifecycle status (draft → issued → paid → canceled) and an orthogonal payment dimension (payment\_status) owned exclusively by the recompute service. Key associations include the source Document, line-item InvoiceItems, matched bank transactions via InvoiceTransaction pivot rows, payment instruments via InvoicePaymentMeans, and the originating WorkspaceConnector for provenance.

| Naming                          | Value          |
| ------------------------------- | -------------- |
| Object                          | Invoice        |
| Resource type (JSON:API `type`) | `invoice`      |
| Collection / records root       | `invoices`     |
| REST base                       | `/v1/invoices` |
| Entity class                    | `Invoice`      |

## API operations

| Operation | Method & path              | Status        |
| --------- | -------------------------- | ------------- |
| List      | `GET /v1/invoices`         | ✅ Implemented |
| Retrieve  | `GET /v1/invoices/{id}`    | ✅ Implemented |
| Create    | `POST /v1/invoices`        | 🟡 Planned    |
| Update    | `PATCH /v1/invoices/{id}`  | ✅ Implemented |
| Delete    | `DELETE /v1/invoices/{id}` | ✅ Implemented |

## Data model

### Attributes

| Field                           | Type                                    | Required | Constraints                                                                                                                                             | Allowed values                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Description                                                                                                                                                                                                                                   |
| ------------------------------- | --------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| invoice\_id                     | string, UUID                            | ✅ Yes    | unique; defaultRaw: gen\_random\_uuid()                                                                                                                 | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Public immutable identifier for the invoice. Exposed in all API responses; used in external references.                                                                                                                                       |
| status                          | string (InvoiceStatusEnum)              | ✅ Yes    | default: draft; nativeEnumName: invoice\_status\_enum                                                                                                   | draft, issued, paid, canceled                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Lifecycle stage of the invoice. Managed by the document extraction and reconciliation pipeline. Do NOT extend — payment dimension is handled by payment\_status.                                                                              |
| payment\_status                 | string (PaymentStatusEnum)              | ✅ Yes    | default: unknown; nativeEnumName: payment\_status\_enum; 🔒 written exclusively by the recompute service                                                | unpaid, partial, paid, overpaid, unknown                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Orthogonal payment dimension tracking how much of the invoice has been settled against matched bank transactions. Owned by the payment-recompute service; not user-writable through Hasura update permissions.                                |
| issue\_date                     | Date (timestamp), nullable              | ⚪ No     | columnType: timestamp; @Enrichable                                                                                                                      | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | The date the invoice was formally issued, as stated on the document. Populated by the AI extraction pipeline.                                                                                                                                 |
| due\_date                       | Date (date), nullable                   | ⚪ No     | columnType: date; @Enrichable                                                                                                                           | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Payment deadline as stated on the invoice. Stored as a calendar date (no time component).                                                                                                                                                     |
| grand\_total                    | number (decimal 12,2), nullable         | ⚪ No     | columnType: decimal(12,2); @Enrichable                                                                                                                  | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Total invoice amount in local\_currency, inclusive of taxes. Surfaced via composite\_total\_amount\_currency on the records page.                                                                                                             |
| items\_total                    | number (decimal 12,2), nullable         | ⚪ No     | columnType: decimal(12,2); @Enrichable                                                                                                                  | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Sum of all line-item amounts before taxes, in local\_currency. Surfaced via composite\_items\_amount\_currency.                                                                                                                               |
| tax\_total                      | number (decimal 12,2), nullable         | ⚪ No     | columnType: decimal(12,2); @Enrichable                                                                                                                  | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Total tax amount in local\_currency. Surfaced via composite\_tax\_amount\_currency.                                                                                                                                                           |
| local\_currency                 | string (CurrencyCodeEnum), nullable     | ⚪ No     | nativeEnumName: currency\_code\_enum; @Enrichable                                                                                                       | ISO 4217 currency codes (EUR, USD, GBP, …) — full list in packages/shared/src/constants/currency-codes.ts                                                                                                                                                                                                                                                                                                                                                                                                                             | Currency in which the invoice was issued. grand\_total, items\_total, and tax\_total are denominated in this currency.                                                                                                                        |
| invoice\_number                 | string, nullable                        | ⚪ No     | no explicit length cap; @Enrichable; partial unique index on (workspace\_pk, invoice\_number) WHERE deleted\_at IS NULL AND invoice\_number IS NOT NULL | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Human-readable invoice reference number as printed on the document (e.g. INV-2026-00412). Used as a deduplication key during import within a workspace.                                                                                       |
| reference\_number               | string, nullable                        | ⚪ No     | length: 100; @Enrichable                                                                                                                                | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | External reference or PO number annotated on the invoice by the issuer. Distinct from purchase\_order\_number (which is the buyer-side PO).                                                                                                   |
| purchase\_order\_number         | string, nullable                        | ⚪ No     | length: 100                                                                                                                                             | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Buyer-side purchase order number linked to this invoice.                                                                                                                                                                                      |
| document\_type\_code            | string (DocumentTypeCodeEnum), nullable | ⚪ No     | nativeEnumName: document\_type\_code\_enum                                                                                                              | UN/EDIFACT D.16A document type codes: 380 (COMMERCIAL\_INVOICE), 381 (CREDIT\_NOTE), 383 (DEBIT\_NOTE), 384 (CORRECTED\_INVOICE), 385 (CONSOLIDATED\_INVOICE), 386 (PREPAYMENT\_INVOICE), 325 (PROFORMA\_INVOICE), 326 (PARTIAL\_INVOICE), and many others — full list in apps/api/src/constants/document-type-code.const.ts                                                                                                                                                                                                          | UN/EDIFACT D.16A document type code classifying the nature of the commercial document. Used to distinguish invoices from credit notes, purchase orders, remittance advices, utility bills, expense receipts, etc.                             |
| billing\_context                | string (BillingContextEnum), nullable   | ⚪ No     | nativeEnumName: billing\_context\_enum                                                                                                                  | subscription, recurring, periodic, installment, retainer, usage\_based, consumption, metered, volume\_based, overage, project, milestone, hourly, fixed\_price, time\_materials, one\_time, event\_based, commission, bonus, reimbursement, maintenance, support, consulting, training, professional\_services, contract, license, rental, lease, franchise, adjustment, refund, credit, penalty, discount, deposit, advance\_payment, escrow, insurance, tax, promotional, trial, freemium, setup, activation, other, mixed, unknown | Commercial context or billing model under which the invoice was raised.                                                                                                                                                                       |
| description                     | string, nullable                        | ⚪ No     | @Enrichable; display\_type: long\_text\_area in overrides.yml                                                                                           | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Free-text description of the goods or services billed, as extracted from the document.                                                                                                                                                        |
| terms                           | string, nullable                        | ⚪ No     | length: 300; @Enrichable; display\_type: long\_text\_area in overrides.yml                                                                              | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Payment terms as stated on the invoice (e.g. Net 30, early payment discount clauses).                                                                                                                                                         |
| accounting\_currency            | string (CurrencyCodeEnum), nullable     | ⚪ No     | nativeEnumName: currency\_code\_enum                                                                                                                    | ISO 4217 currency codes — same enum as local\_currency                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Workspace functional / reporting currency into which totals have been converted by the FX matching pipeline. Present when local\_currency differs from the workspace accounting currency.                                                     |
| accounting\_grand\_total        | string (decimal 12,2), nullable         | ⚪ No     | columnType: decimal(12,2); stored as string to preserve precision                                                                                       | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | grand\_total converted to accounting\_currency via the linked exchange\_rate. Written by the invoice FX matching service.                                                                                                                     |
| accounting\_items\_total        | string (decimal 12,2), nullable         | ⚪ No     | columnType: decimal(12,2); stored as string                                                                                                             | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | items\_total converted to accounting\_currency.                                                                                                                                                                                               |
| accounting\_tax\_total          | string (decimal 12,2), nullable         | ⚪ No     | columnType: decimal(12,2); stored as string                                                                                                             | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | tax\_total converted to accounting\_currency.                                                                                                                                                                                                 |
| paid\_amount                    | string (decimal 12,2), nullable         | ⚪ No     | columnType: decimal(12,2); stored as string; 🔒 written by recompute service                                                                            | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Cumulative amount matched and allocated against this invoice from bank transactions, in local\_currency. Written exclusively by the payment-recompute service.                                                                                |
| balance\_due                    | string (decimal 12,2), nullable         | ⚪ No     | columnType: decimal(12,2); stored as string; 🔒 written by recompute service                                                                            | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Remaining unpaid amount (grand\_total minus paid\_amount), in local\_currency. Derived and written by the payment-recompute service.                                                                                                          |
| last\_payment\_allocation\_date | Date (timestamptz), nullable            | ⚪ No     | columnType: timestamptz; 🔒 written by recompute service                                                                                                | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Timestamp of the most recent payment allocation event processed by the recompute service.                                                                                                                                                     |
| override\_version               | number (integer)                        | ✅ Yes    | default: 0; 🔒 incremented by recompute service on every write; selectable but not user-writable via Hasura update permissions                          | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Optimistic concurrency counter incremented by the payment-recompute service on each write. Used for observability and conflict detection; not a user-settable field.                                                                          |
| shadow\_from\_receipt           | boolean                                 | ✅ Yes    | default: false                                                                                                                                          | true, false                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | True when this invoice row was synthesized from a payment\_receipt document via the mapReceiptToShadowFlat (R1) pipeline rather than extracted from a real bill. Lets the UI distinguish promoted receipts from genuine outstanding invoices. |
| created\_at                     | Date, 🔒 system                         | ✅ Yes    | onCreate: () => new Date()                                                                                                                              | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Timestamp when the invoice row was created. Set once on insert via MikroORM lifecycle hook.                                                                                                                                                   |
| updated\_at                     | Date, 🔒 system                         | ⚪ No     | onCreate + onUpdate: () => new Date()                                                                                                                   | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Timestamp of the last modification. Automatically maintained by MikroORM lifecycle hooks. Declared optional in the entity; absent on rows that have never been updated after initial insert.                                                  |
| deleted\_at                     | Date, nullable                          | ⚪ No     | nullable; all active-row queries must filter deleted\_at IS NULL                                                                                        | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Soft-delete timestamp. Non-null means the invoice is logically deleted and must not appear in active listings. Partial indexes on workspace + created\_at and workspace + source\_connector include WHERE deleted\_at IS NULL.                |

### Relationships

| Name                           | Type                                    | Required        | Description                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | --------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| issuer                         | to-one (company)                        | ⚪ No (nullable) | The Company that issued (sent) this invoice — typically the vendor or service provider. Index: idx\_invoices\_issuer. Used as a hot-path FK rewrite target during company-merge operations.                                                                                                                         |
| receiver                       | to-one (company)                        | ⚪ No (nullable) | The Company that received (was billed by) this invoice — typically the workspace's own company for payables, or the customer for receivables. Index: idx\_invoices\_receiver. Also a hot-path FK rewrite target during company-merge.                                                                               |
| document                       | to-one (document)                       | ⚪ No (nullable) | The source Document from which this invoice was extracted (contains the original file, filename, and organisation/partner slugs). Indexed jointly with deleted\_at via idx\_invoices\_document\_deleted.                                                                                                            |
| workspace                      | to-one (workspace)                      | ⚪ No (nullable) | Tenant boundary. Every active invoice belongs to exactly one Workspace. Partial indexes for active-row listing and source-connector listing both scope to workspace\_pk.                                                                                                                                            |
| source\_workspace\_connector   | to-one (workspace\_connector)           | ⚪ No (nullable) | The WorkspaceConnector instance that ingested this invoice, when it was created via a connector sync. Null for manually uploaded or email-extracted invoices. Partial index idx\_invoices\_workspace\_source\_connector\_active covers (workspace\_pk, source\_workspace\_connector\_pk) WHERE deleted\_at IS NULL. |
| exchange\_rate                 | to-one (exchange\_rate)                 | ⚪ No (nullable) | FK-normalised ExchangeRate row used for multi-currency conversion. Carries rate, source\_currency, target\_currency, rate\_date, and source. Used by the composite\_fx\_rate cell renderer and by accounting\_\* total computation.                                                                                 |
| subscription                   | to-one (subscription)                   | ⚪ No (nullable) | Optional link to a Subscription record when the invoice was generated from a recurring subscription context.                                                                                                                                                                                                        |
| invoice\_items                 | to-many (invoice\_item)                 | —               | Line items (InvoiceItem) belonging to this invoice. Contains per-line quantity, unit price, description, and tax rates. Owned by the invoice — cascade-deleted when the invoice is hard-deleted.                                                                                                                    |
| invoice\_transactions          | to-many (invoice\_transaction)          | —               | Pivot rows (InvoiceTransaction) linking this invoice to matched bank transactions. Written by the reconciliation / payment-recompute service. The existence and amounts of these rows drive paid\_amount and balance\_due.                                                                                          |
| payment\_means                 | to-many (invoice\_payment\_means)       | —               | Payment instrument links (InvoicePaymentMeans) associating bank account / payment method information stated on the invoice (e.g. IBAN to pay to).                                                                                                                                                                   |
| invoice\_workspace\_connectors | to-many (invoice\_workspace\_connector) | —               | Connector provenance pivot rows (InvoiceWorkspaceConnector) recording which WorkspaceConnector instances have touched or are aware of this invoice. Used for deduplication and cross-connector identity resolution.                                                                                                 |

### System-computed

* invoice\_id is generated automatically at insert by Postgres via defaultRaw: gen\_random\_uuid(). It is immutable after creation.
* created\_at is set once on INSERT via MikroORM onCreate: () => new Date() lifecycle hook.
* updated\_at is set on both INSERT and UPDATE via onCreate + onUpdate: () => new Date() lifecycle hooks. It is declared optional in the entity (updated\_at?: Date) and may be absent on rows that have never been modified after creation.
* deleted\_at is null on creation and is set to a Date value by soft-delete logic. All active-row queries must predicate on deleted\_at IS NULL. No hard delete should be issued directly.
* payment\_status (and paid\_amount, balance\_due, last\_payment\_allocation\_date, override\_version) are owned exclusively by the payment-recompute service. Application code and API clients must treat these as read-only. override\_version is an optimistic concurrency counter incremented on every recompute write.
* shadow\_from\_receipt defaults to false. It is set to true only by the mapReceiptToShadowFlat (R1) pipeline when synthesizing an invoice row from a payment\_receipt document.
* accounting\_grand\_total, accounting\_items\_total, accounting\_tax\_total, and accounting\_currency are written by the invoice FX matching service (fx-rate.service.ts + invoice.service.ts) when the invoice local\_currency differs from the workspace accounting currency.
* source\_workspace\_connector (sourceWorkspaceConnector) is set at creation time when the invoice is ingested through a connector sync; it remains null for manually uploaded or email-extracted invoices.
* Fields decorated with @Enrichable (issue\_date, grand\_total, local\_currency, reference\_number, terms, items\_total, tax\_total, description, invoice\_number, due\_date) are eligible for AI enrichment via the enrichment pipeline workers.
* Partial index idx\_invoices\_workspace\_invoice\_number\_active enforces uniqueness of (workspace\_pk, invoice\_number) among non-deleted rows where invoice\_number IS NOT NULL, enabling efficient deduplication on import.
* Partial index idx\_invoices\_workspace\_source\_connector\_active on (workspace\_pk, source\_workspace\_connector\_pk) WHERE deleted\_at IS NULL supports efficient tenant + connector listing queries.
* Partial index idx\_invoices\_workspace\_created\_active on (workspace\_pk, created\_at DESC) WHERE deleted\_at IS NULL mirrors the records-page default sort order to avoid full-table scans.

## Example

```json theme={null}
{
  "data": {
    "type": "invoice",
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "attributes": {
      "invoice_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "status": "issued",
      "payment_status": "partial",
      "issue_date": "2026-04-15T00:00:00.000Z",
      "due_date": "2026-05-15",
      "grand_total": "12450.00",
      "items_total": "10375.00",
      "tax_total": "2075.00",
      "local_currency": "EUR",
      "invoice_number": "INV-2026-00412",
      "reference_number": "PO-8821-ACME",
      "purchase_order_number": "PO-8821",
      "document_type_code": "380",
      "billing_context": "subscription",
      "description": "Annual SaaS platform licence — Enterprise tier",
      "terms": "Net 30. Late payments subject to 1.5 % monthly interest.",
      "accounting_currency": "USD",
      "accounting_grand_total": "13489.35",
      "accounting_items_total": "11241.00",
      "accounting_tax_total": "2248.35",
      "paid_amount": "5000.00",
      "balance_due": "7450.00",
      "last_payment_allocation_date": "2026-05-01T14:32:00.000Z",
      "override_version": 3,
      "shadow_from_receipt": false,
      "created_at": "2026-04-16T09:17:42.000Z",
      "updated_at": "2026-05-01T14:32:01.000Z",
      "deleted_at": null
    },
    "relationships": {
      "issuer": {
        "data": { "type": "company", "id": "a1b2c3d4-0001-4000-8000-111111111111" }
      },
      "receiver": {
        "data": { "type": "company", "id": "a1b2c3d4-0002-4000-8000-222222222222" }
      },
      "document": {
        "data": { "type": "document", "id": "d0c00000-0000-4000-8000-999999999999" }
      },
      "workspace": {
        "data": { "type": "workspace", "id": "w0000000-0000-4000-8000-000000000001" }
      },
      "source_workspace_connector": {
        "data": { "type": "workspace_connector", "id": "c0000000-0000-4000-8000-000000000001" }
      },
      "exchange_rate": {
        "data": { "type": "exchange_rate", "id": "e0000000-0000-4000-8000-000000000001" }
      },
      "subscription": {
        "data": null
      },
      "invoice_items": {
        "data": [
          { "type": "invoice_item", "id": "b1000000-0000-4000-8000-000000000001" }
        ]
      },
      "invoice_transactions": {
        "data": [
          { "type": "invoice_transaction", "id": "t2000000-0000-4000-8000-000000000001" }
        ]
      },
      "payment_means": {
        "data": [
          { "type": "invoice_payment_means", "id": "pm000000-0000-4000-8000-000000000001" }
        ]
      },
      "invoice_workspace_connectors": {
        "data": []
      }
    }
  }
}
```

<sub>Source: `apps/api/src/database/entities/Invoice.ts` · domain: financial-graph · tier: Main</sub>
