---
title: "List invoices"
method: GET
path: "/v1/invoices"
tags: ["Invoices"]
---

# List invoices

`GET /v1/invoices`

## Request

- Base URL: `https://api.frihet.io`
- URL: `https://api.frihet.io/v1/invoices`
- Auth: API key in header `X-API-Key`

Retrieve a paginated list of invoices with optional filters for status, date range, and search.

## Query parameters

- `limit` integer
- `offset` integer
- `cursor` string
- `status` 'draft' | 'sent' | 'partial' | 'paid' | 'overdue' | 'cancelled'
- `from` string, date
- `to` string, date
- `q` string
- `fields` string
- `clientId` string
- `seriesId` string

## Response `200`

A paginated list of invoices

- object
  - `data` Invoice[]
    - `id` string: Unique identifier
    - `createdAt` string, date-time: Creation timestamp
    - `updatedAt` string, date-time: Last update timestamp
    - `clientId` string: Client document ID. When provided, the API auto-snapshots `clientTaxId`, `clientAddress`, `clientLocation`, `clientName`, and `clientEmail` from the referenced client at create time (immutable post-create — VeriFactu RD 1007/2023). Caller-provided values for those fields override the snapshot.
    - `clientName` string, required: Client name (snapshot field — frozen at create)
    - `clientTaxId` string: Client tax ID / NIF / VAT (snapshot field — frozen at create). Auto-populated from clientId reference if not provided.
    - `clientAddress` string: Client billing address — single-line or structured. Snapshot field, frozen at create.
    - `clientLocation` 'peninsula' | 'canarias' | 'ceuta_melilla' | 'eu' | 'world': Fiscal zone — drives tax label rendering on PDF + tax math (IVA/IGIC/IPSI/Reverse charge/Exempt). Snapshot field, frozen at create. Auto-populated from clientId reference if absent.
    - `clientEmail` string, email: Client email (snapshot field — frozen at create).
    - `documentNumber` string: Auto-generated invoice number
    - `items` LineItem[], required
      - `description` string, required: Item description
      - `quantity` number, required: Quantity
      - `unitPrice` number, required: Price per unit
    - `issueDate` string, date: Issue date in ISO format
    - `dueDate` string, date: Due date in ISO format
    - `status` 'draft' | 'sent' | 'partial' | 'paid' | 'overdue' | 'cancelled'
    - `notes` string: Additional notes
    - `taxRate` number: Tax rate percentage. Combined with `clientLocation` to produce the label (IGIC for canarias, IPSI for ceuta_melilla, etc.).
    - `irpfRate` number: IRPF withholding rate percentage (Spain).
    - `discountRate` number: Invoice-level discount percentage.
    - `recurring` InvoiceRecurringConfig: Recurring invoice configuration. Set on a template invoice to auto-generate copies on schedule.
      - `enabled` boolean, required: Whether recurring generation is active
      - `frequency` 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly', required: How often to generate a new invoice
      - `nextDate` string, date, required: Next scheduled generation date (ISO YYYY-MM-DD)
      - `endDate` string, date: Stop generating after this date (optional)
      - `maxOccurrences` integer: Maximum number of invoices to generate (optional)
      - `autoSend` boolean: Automatically send generated invoices to the client
      - `occurrencesGenerated` integer: Number of invoices generated so far (server-managed, read-only)
      - `lastGeneratedId` string: ID of the last auto-generated invoice (server-managed, read-only)
    - `subtotal` number: Subtotal before tax
    - `tax` number: Tax amount
    - `total` number: Total amount including tax
    - `currency` string: Currency code
    - `verifactuHash` string: VeriFactu SHA-256 hash (Spanish tax compliance)
  - `total` integer: Total number of items matching the query
  - `limit` integer: Number of items per page
  - `offset` integer: Current offset
  - `nextCursor` string: Cursor for fetching the next page of results. Only present when there are more results available. Pass this value as the `cursor` query parameter in the next request. Base64url-encoded.
  - `truncated` boolean: Only present (and `true`) when the underlying search query saturated the internal 500-document cap. `total` therefore reports the size of the first 500 matches, not the full match count. Narrow the search query (taxId / fiscal id, exact email) to ensure you see every result.

## Other responses

- `400`: Bad request - invalid parameters or request body
- `401`: Authentication required or invalid API key
- `429`: Rate limit exceeded (100 requests per minute)
- `500`: Internal server error

---

[API](https://skmtc.dev/frihet/apis/frihet-api.md) · [All operations](https://skmtc.dev/frihet/apis/frihet-api/llms.txt) · [OpenAPI document](https://skmtc.dev/frihet/apis/frihet-api/revisions/3dd37f6a72d1?raw)
