---
title: "List pending expenses"
method: GET
path: "/companies/{company}/purchase-invoices/pending"
tags: ["Purchase Invoices"]
---

# List pending expenses

`GET /companies/{company}/purchase-invoices/pending`

## Request

- Base URL: `https://api.factuarea.com/v1`
- URL: `https://api.factuarea.com/v1/companies/{company}/purchase-invoices/pending`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Return expenses in pending payment status, paginated.

## Path parameters

- `company` string, uuid, required

## Query parameters

- `per_page` string
- `limit` string
- `cursor` string

## Headers

- `Factuarea-Version` string, date

## Response `200`

- object: Cursor-paginated list envelope shared by every v1 listing endpoint. `data` holds the page items; `has_more` signals whether another page exists; `next_cursor` is the cursor to pass back for the following page. Treat it as strictly opaque: send it through verbatim, never parse it and never assume a format — it is not the same across listings, and each listing documents its own cursor parameter. Concrete listings narrow `data` to their resource type via `allOf`.
  - `data` object[], required: Items on the current page.
    - `id` string, required
    - `object` 'purchase_invoice', required
    - `external_invoice_number` string, nullable, required: The number assigned by the supplier on their invoice. `null` for a simplified expense ticket (`is_simplified`) with no supplier number.
    - `is_simplified` boolean, required: Whether this is a simplified supplier invoice (expense ticket). When `true`, `supplier` and `external_invoice_number` may be `null`.
    - `external_id` string, nullable, required: External integration key (ERP/CRM/e-commerce) mapping this document to a record in a third-party system. Free-format, unique per company, filterable via `?external_id=`. `null` when not set. Persistent synchronization key, independent of the request-level `Idempotency-Key`.
    - `internal_code` string, nullable, required: Optional internal code assigned by the company for its own classification.
    - `supplier` SupplierRef, required
      - `id` string, nullable, required
      - `name` string, nullable, required
    - `status` string, required
    - `issued_on` string, date, required
    - `received_on` string, date, nullable, required: Reception date of the invoice, or `null`.
    - `due_on` string, date, nullable, required
    - `subtotal` string, required
    - `taxes_total` string, required: VAT BORNE (IVA soportado) of this expense, WITHOUT surcharge and WITHOUT withholding. Careful: on the sales-side documents (invoice, delivery note, quote, proforma) the SAME field name carries the NET aggregate `total_vat + total_surcharge − total_retention` instead. Header invariant here (except for self-assessed `operation_class` `intracomunitaria` and `isp`, see `total`): `total === subtotal + taxes_total + total_surcharge − total_retention`. Read `total_vat` for a VAT figure whose meaning does not depend on the document family.
    - `total_vat` string, required: Same VAT amount as `taxes_total`, published under the name the concept carries in the other four document families, so that the explicit identity `total === subtotal + total_vat + total_surcharge − total_retention` holds across all five without knowing which resource produced the body.
    - `total_retention` string, required: Aggregated IRPF withholding of the lines (Σ retention_amount). Header invariant: `total === subtotal + taxes_total + total_surcharge − total_retention`.
    - `total_surcharge` string, required: Aggregated equivalence surcharge of the lines (Σ surcharge_amount). It adds to the total exactly like VAT does, so it is part of the header invariant above.
    - `total` string, required: Total of the expense. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the five document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the one specific to this family, where `taxes_total` is the VAT alone - `total = subtotal + taxes_total + total_surcharge - total_retention`. Note that the aggregate shortcut of the sales-side families (`subtotal + taxes_total`) does NOT apply here: the same field name carries a different meaning on each side. Exception: when `operation_class` is `intracomunitaria` or `isp` the VAT is self-assessed (the supplier does not charge it), so it is NOT part of the total: `total = subtotal - total_retention + total_surcharge`, and `total_vat` / `taxes_total` still publish the self-assessed VAT amount.
    - `currency` string, required
    - `paid_amount` string, required: Amount already paid against this expense (derived from the payment ledger). Satisfies the invariant `paid_amount + pending_amount === total`.
    - `pending_amount` string, required: Outstanding balance pending payment for this expense (derived from the payment ledger).
    - `payment_status` 'pending' | 'partially_paid' | 'paid' | 'overdue', required: Derived payment status, NOT a persisted domain state (the model keeps 4 statuses). `overdue` derives from `pending` + `due_date < today` and prevails in presentation.
    - `paid_recorded_at` string, date-time, nullable, required: Instant (ISO 8601 with offset) at which the payment that settled the purchase invoice was RECORDED in the ledger. `null` while it is not paid. Not the declared date: see `paid_date`.
    - `paid_date` string, date, nullable, required: Declared payment date (YYYY-MM-DD). `null` while the purchase invoice is not paid. The input field of `mark-paid` and `payments` keeps the name `paid_on`.
    - `payment_method` string, nullable, required
    - `payment_terms_days` integer, nullable, required: Payment term days agreed with the supplier, or `null`.
    - `bank_account` unknown, required
    - `expense_account` string, nullable, required: Associated expense ledger account, or `null`.
    - `expense_category_id` string, nullable, required: UUID v7 of the associated expense category, or `null`.
    - `deductible_percentage` number, float, nullable, required: Deductible percentage of the input VAT (0–100), or `null` when not set.
    - `operation_class` 'corriente' | 'bien_inversion' | 'importacion' | 'intracomunitaria' | 'isp', required: Operation class for the input VAT of Modelo 303. Defaults to `corriente`. `isp` (domestic reverse charge, Art. 84.Uno.2 LIVA) and `intracomunitaria` are self-assessed: the buyer declares both the output VAT and the deductible input VAT.
    - `exclude_347` boolean, required: Declarative per-document flag: whether this expense is excluded from the annual Modelo 347 report.
    - `tax_period` string, nullable, required: Fiscal allocation period (format `YYYY-MM` or `YYYY-QN`), or `null`.
    - `is_reverse_charge` boolean, required: Indicates whether the invoice is subject to reverse charge.
    - `tags` string[], required: Free classification tags (lowercase slugs `[a-z0-9-]`, ≤ 40 chars each, ≤ 30 tags). Filterable via `?tags[in]=tag1,tag2` (JSON_CONTAINS, OR semantics). Empty `[]` when there are none.
    - `custom_fields` CustomField[], required: Ordered list of typed custom fields `[{field, value}]` (≤ 50). Distinct from `metadata` (a free key→value map): use `custom_fields` for structured, display-oriented integration metadata. Empty `[]` when there are none.
      - `field` string, required: Field key (non-empty, ≤ 60 chars).
      - `value` string, required: Field value (≤ 500 chars).
    - `internal_notes` string, nullable, required: Internal notes not visible to the supplier, or `null`.
    - `attachment` PurchaseInvoiceAttachment, required: File attached to the expense (PDF or image). `null` when there is no attachment.
      - `filename` string, required: Original name of the uploaded file.
      - `mime_type` string, required: MIME type of the file (e.g. `application/pdf`).
      - `size_bytes` integer, required: File size in bytes.
      - `download_url` string, required: Relative download URL of the attachment (`/v1/companies/{company}/purchase-invoices/{purchase_invoice}/file`).
    - `lines` PurchaseInvoiceLine[], required
      - `object` 'purchase_invoice_line', required
      - `source_line_index` integer, nullable: Zero-based ordinal of the line within this expense, in the stable read order. Send it back on create/update to keep a line matched to its historical counterpart (measures, units and frozen cost are preserved when the physical selection and the supplier do not change). It is NOT a primary key and it grants no access to any other document.
      - `description` string, nullable, required
      - `additional_description` string, nullable, required: Optional secondary description rendered below the line concept on document PDFs.
      - `quantity` union, required: Billed quantity. A measured purchase line (one carrying `purchase_measurement`) returns it as a 4-decimal STRING so no precision is lost; a legacy line keeps the numeric type it has always published.
        - number
        - string
      - `unit_price` string, required: Cost per billed unit, always a decimal STRING with the 4-decimal scale of its column (e.g. `"7.4000"`, `"100.0000"`), on measured (carrying `purchase_measurement`), legacy and manual lines alike: it is returned exactly as it was accepted and stored, so reading a line and sending it back never changes its cost. Derived amounts keep 2 decimals.
      - `discount_percent` number: Discount percentage applied to the line (0-100) BEFORE any tax. `subtotal` is already net of it, so `unit_price` multiplied by `quantity` does NOT equal `subtotal` on a discounted line. Default 0.
      - `confirmed_base_quantity` string, nullable: Real measured quantity in the base unit, as a decimal string, for a variable-measure presentation (weighed goods). `null` when the line does not require one. It is reconstructed from the stored base quantity, never recomputed against the live catalog.
      - `purchase_measurement` object, nullable: Measured-purchase block. `null` on a legacy or manual line, which keeps its previous `quantity` × `unit_price` semantics. On write only `package_quantity` and `cost_basis` are accepted; the remaining fields are DERIVED by the server and are never taken from the client.
        - `package_quantity` string, nullable, required: Physical number of packages/presentations received, as a decimal string (e.g. `"3.0000"` boxes). `null` when the purchase is not counted in packages — it means neither one nor zero.
        - `billing_quantity` string, required: Derived. Billed quantity expressed in `billing_unit_code` (e.g. `"6.0000"` kg for three 2 kg boxes).
        - `billing_unit_code` string, required: Derived. UN/ECE code of the unit the cost applies to (`KGM`, `LTR`, `C62`, …).
        - `billing_conversion_factor` string, required: Derived. Factor, at scale 6, between the billing unit and the base unit of the product.
        - `unit_cost` string, required: Derived. Cost per billing unit, as a decimal string (e.g. `"7.4000"` per kg). A confirmed `"0.0000"` is a free line, not an unknown cost.
        - `cost_basis` 'offer_unit' | 'base_unit' | 'presentation_unit', required: Which unit the cost is quoted in: the supplier offer unit (requires an applicable offer), the product base unit (factor 1, manual cost) or a fixed presentation (manual cost per presentation).
      - `tax_rate` number, required
      - `retention_rate` number, required: IRPF withholding percentage applied to the supplier (0–100). Default 0.
      - `surcharge_rate` number, required: Equivalence surcharge (recargo de equivalencia) percentage paid to the retail supplier (0–100). Default 0. Only the legal VAT-surcharge pairs are accepted (21→5.2, 10→1.4, 4→0.5).
      - `subtotal` string, required
      - `taxes` string, required
      - `retention_amount` string, required: Withholding amount of the line (`subtotal * retention_rate / 100`). The line total follows `subtotal + taxes − retention_amount + surcharge_amount`.
      - `surcharge_amount` string, required: Equivalence surcharge amount of the line (`subtotal * surcharge_rate / 100`). Default 0.
      - `vat_deductible` boolean, required: Whether the line VAT is deductible. It does not change the amount paid, but a `false` line is excluded from the deductible input VAT of Modelo 303 (boxes [28]-[37]).
      - `total` string, required
      - `exemption_reason` string, nullable: LIVA exemption cause (E1–E6) or non-subjection cause (N1/N2) declared for this line, or null when the line does not declare one.
      - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime override of the supplier line: `iva`/`igic`/`ipsi` when set per-document (precedence override>zone), otherwise `null`. Writable on create/update; the document must be homogeneous (a single non-null regime across all lines, 422 otherwise).
      - `product` ProductRef, required
        - `id` string, required
        - `name` string, nullable, required
      - `variant` object, nullable, required
        - `id` string, required
        - `name` string, nullable, required
      - `presentation` object, nullable, required
        - `id` string, required
        - `name` string, nullable, required
        - `mode` string, nullable, required
      - `supplier_offer_id` string, nullable, required
      - `item_kind` string, nullable, required
      - `commercial_unit_code` string, nullable, required
      - `base_unit_code` string, nullable, required
      - `conversion_factor` string, nullable, required
      - `base_quantity` string, nullable, required
      - `price_source` string, nullable, required
      - `price_unit_code` string, nullable, required
      - `configuration` object, nullable, required: Commercial combination frozen on the line, or `null` when the line was not sold or bought through one (legacy product, manual line).
        - `id` string, required
        - `name` string, nullable, required
        - `signature` string, nullable, required
      - `options` object[], required: Configurable options frozen on the line, in printing order. Always an array, `[]` included.
        - `group` object, required
          - `id` string, required
          - `name` string, nullable, required
        - `value` object, required
          - `id` string, required
          - `name` string, nullable, required
        - `price_adjustment` string, nullable, required: Adjustment of the chosen value per commercial unit. `null` means the value does not change the price — NOT the same as adjusting by `0`.
        - `applied` boolean, required: Whether that amount was actually ADDED to the unit price. `false` when an exact price (price-list entry, combination price or a manually typed unit price) already absorbed it.
      - `price_semantics` 'per_base_unit' | 'per_commercial_unit' | 'null', nullable, required: Monetary semantics of the frozen price: `per_base_unit` (converted once by the presentation factor) or `per_commercial_unit` (never converted). `null` when the line carries no catalog price context.
      - `price_adjustment_total` string, nullable, required: Sum of the adjustments of the chosen option values, as a decimal string.
      - `option_adjustments_absorbed` boolean, nullable, required: TRI-STATE, and `null` is NOT `false`. `true`: the frozen price already includes the option adjustments. `false`: they were added on top. `null`: it could not be determined.
    - `metadata` Metadata, nullable, required: A free map of up to 50 key→value pairs for storing arbitrary structured data (values are strings up to 500 characters). Unlike `custom_fields` — an ordered list of typed `{field, value}` pairs with display semantics, present on the six document resources — `metadata` is an unordered map for opaque integration data; a document may carry both. The master resources (Client, Supplier) have no `custom_fields`, so their `metadata` doubles as the custom-fields store. **Reserved keys (read-only).** When the system auto-issues an invoice from a payment correlation (Stripe/GoCardless/MONEI), it writes `stripe_subscription_id`, `stripe_invoice_id`, `billing_reason`, `period_start` and `period_end` into that invoice metadata automatically. Do not set or overwrite them by hand — the platform owns them and a manual value may be replaced when the correlation runs.
    - `notes` string, nullable, required
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
  - `has_more` boolean, required: Whether more pages are available after this one.
  - `next_cursor` string, nullable, required: Opaque cursor for the next page, or `null` when `has_more` is `false`. The example below shows the shape used by most listings; others return a different one, so pass the value back verbatim instead of validating it.

## Other responses

- `400`: `parameter_unknown` with `subcode` `retired_active_profile_header`: the retired `X-Active-Profile` header was sent; the company goes in the path. `parameter_invalid_format` on `Factuarea-Version`: the header is not a `YYYY-MM-DD` date. `unsupported_api_version`: the `Factuarea-Version` date is not a supported version.
- `401`: Missing or invalid API key.
- `403`: The request is authenticated but not allowed: the API key lacks the required scope (`insufficient_scope`), the plan does not include the public API or this feature (`addon_not_active`, `feature_not_available_in_plan`), or the module is not available with a test key (`module_not_available_in_sandbox`).
- `404`: The requested resource does not exist or belongs to another company. `profile_not_found`: the company in the path does not exist, is not in the API key scope or belongs to the other environment (live or test).
- `429`: Rate limit exceeded. Retry after the duration in `Retry-After`.
- `500`: Unexpected server error.

---

[API](https://skmtc.dev/factuarea/apis/factuarea-public-api.md) · [All operations](https://skmtc.dev/factuarea/apis/factuarea-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/factuarea/apis/factuarea-public-api/revisions/718e77934422?raw)
