---
title: "Cancel recurring invoice"
method: POST
path: "/companies/{company}/recurring-invoices/{recurring_invoice}/cancel"
tags: ["Recurring Invoices"]
---

# Cancel recurring invoice

`POST /companies/{company}/recurring-invoices/{recurring_invoice}/cancel`

## Request

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

Cancel a recurring invoice. Unlike `pause`, this is a terminal, irreversible state: a cancelled recurring invoice can never be resumed or reactivated. Previously generated invoices are unaffected.

## Path parameters

- `company` string, uuid, required
- `recurring_invoice` string, uuid, required

## Headers

- `Idempotency-Key` string, required
- `Factuarea-Version` string, date

## Response `200`

- object
  - `data` RecurringInvoice, required: A recurring invoice template that auto-generates invoices on a fixed cadence.
    - `id` string, required
    - `object` 'recurring_invoice', required
    - `client` ClientRef, required
      - `id` string, nullable, required
      - `name` string, nullable, required
    - `series` SeriesRef, required
      - `id` string, nullable, required
      - `code` string, nullable, required
    - `status` string, required: Recurring schedule status (active, paused, completed, cancelled).
    - `price_list_id` string, nullable, required: UUID of the price list selected for generated invoices.
    - `price_list_name` string, nullable, required: Price-list name snapshot stored by the recurrence.
    - `frequency` string, required: Cadence (weekly, monthly, quarterly, yearly, etc.).
    - `name` string, required: Descriptive name of the recurrence.
    - `description` string, nullable, required: Free-text description of the recurrence.
    - `notes` string, nullable, required: Internal notes carried over to the generated invoices.
    - `email_to` string, email, nullable, required: Recipient of the automatic dispatch of generated invoices. `null` if not configured.
    - `send_automatically` boolean, required: Compatibility field DERIVED from `generation_mode`: `true` if and only if `generation_mode` is `issue_and_send` (each generated invoice is issued and emailed to `email_to`). On write, without an explicit `generation_mode`, `true` still means `issue_and_send` and `false` means `draft`; when both are sent and contradict each other the request is rejected with 422.
    - `generation_mode` 'draft' | 'issue' | 'issue_and_send', required: What each run of the recurrence does with the invoice it generates: `draft` leaves it as a draft (no definitive number); `issue` issues it (definitive number, VeriFactu record, stock movements) without emailing it, so it stays `is_sent = false`; `issue_and_send` issues it and emails it to the configured recipients, and it is marked as sent once the mail server accepts the email (if the delivery fails the invoice stays issued and not sent). Available in every API version. `send_automatically` is derived from it.
    - `days_before_due` integer, required: Payment term days (Net X) applied to the due date of each generated invoice.
    - `max_occurrences` integer, nullable, required: Maximum number of invoices to generate before completing the recurrence. `null` = no limit.
    - `occurrences_count` integer, required: Number of invoices already generated by this recurrence.
    - `remaining_occurrences` integer, nullable, required: Invoices remaining until `max_occurrences` is reached. `null` when there is no limit.
    - `holiday_handling` string, required: Adjustment policy when the run date falls on a holiday/weekend (e.g. `none`, `next_business_day`, `previous_business_day`).
    - `start_on` string, date, required
    - `end_on` string, date, nullable, required
    - `next_run_at` string, required: When the next invoice will be generated.
    - `last_run_at` string, nullable, required: When the last invoice was generated, if any.
    - `cancelled_at` string, date-time, nullable, required: When the recurrence was cancelled (irreversible terminal state). `null` if not cancelled.
    - `subtotal` string, required
    - `taxes_total` string, required: NET aggregate of the header taxes: `total_vat + total_surcharge - total_retention`. It is the amount that, added to `subtotal`, yields `total` (`total === subtotal + taxes_total`), so it must NOT be combined with `total_retention`: subtracting the withholding again on top of the aggregate produces a false total. It is NOT the VAT figure of the Spanish Modelo 303 - read `total_vat` for that. These amounts are a PREVIEW aggregated from the template lines (the recurrence persists no header totals), rounded per line exactly as the invoice it will issue stores them.
    - `total_vat` string, required: Output VAT (IVA repercutido) the recurrence will accrue: sum of the VAT of its template lines. This is the figure a Spanish Modelo 303 declares, and it is NOT recoverable from `taxes_total`, which nets the withholding out.
    - `total_retention` string, required: Withholding (retencion de IRPF) the recurrence will apply: sum of the withholding of its template lines, as a POSITIVE amount that SUBTRACTS from the total. This is the figure a Spanish Modelo 130/111 declares. It is ALREADY netted out inside `taxes_total`, so do not subtract it again.
    - `total_surcharge` string, required: Equivalence surcharge (recargo de equivalencia) of the template lines. It ADDS to the total exactly like VAT does, and is ALREADY included inside `taxes_total`.
    - `total` string, required: Total the recurrence will invoice. Two equivalent ways to reconstruct it from the published amounts, and only these two: the EXPLICIT one, identical in the six document families - `total = subtotal + total_vat + total_surcharge - total_retention` - or the AGGREGATE one, specific to the sales-side families - `total = subtotal + taxes_total`. NEVER reconstruct it as `subtotal + taxes_total - total_retention`: `taxes_total` ALREADY has the withholding netted out, so that combination subtracts it twice.
    - `currency` string, required
    - `lines` RecurringInvoiceLine[], required
      - `object` 'recurring_invoice_line', required
      - `description` string, nullable, required
      - `additional_description` string, nullable: Optional secondary description rendered below the line concept on generated invoice PDFs.
      - `quantity` number, required
      - `unit_price` string, required: Unit price as a decimal STRING with 4 decimals (e.g. `"100.0000"`), the scale the template accepts: reading a line and sending it back never changes its price.
      - `tax_rate` number, required
      - `retention` number, required: IRPF withholding percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
      - `surcharge` number, required: Equivalence surcharge (recargo de equivalencia) percentage applied to the line (0–100). Default 0. Its amount is already aggregated into `taxes`.
      - `discount_percent` number, required: Discount percentage applied to the line (0-100) BEFORE any tax, exactly as the domain and the invoice this recurrence will issue apply it. `subtotal` is already net of it, so `unit_price` multiplied by `quantity` does NOT equal `subtotal` on a discounted line. Default 0.
      - `subtotal` string, required
      - `taxes` string, required
      - `total` string, required
      - `exemption_reason` string, nullable, required: LIVA exemption / non-subjection cause of the line (subset of the E and N codes). `null` if not informed.
      - `regime_key` string, nullable, required: VeriFactu regime key (`ClaveRegimen`, AEAT list L8.1) of the line. `null` if not informed.
      - `retention_rate_id` string, nullable, required: Public identifier (UUID v7) of the catalog tax applied as IRPF withholding to the line. Opaque: it does not take part in the `taxes`/`total` computation (the formula uses the flat `retention` percentage). `null` if not informed.
      - `surcharge_rate_id` string, nullable, required: Public identifier (UUID v7) of the catalog tax applied as equivalence surcharge to the line. Opaque: it does not take part in the `taxes`/`total` computation (the formula uses the flat `surcharge` percentage). `null` if not informed.
      - `indirect_tax_regime` 'iva' | 'igic' | 'ipsi' | 'null', nullable: Indirect tax regime override of the recurring template line: `iva`/`igic`/`ipsi` when set per-document (precedence override>zone), otherwise `null`. Writable on create/update; propagated to each generated invoice. The template must be homogeneous (a single non-null regime across all lines, 422 otherwise).
      - `product_id` string, nullable, required
      - `product_name` string, nullable, required
      - `item_kind` string, nullable, required
      - `variant_id` string, nullable, required
      - `variant_name` string, nullable, required
      - `presentation_id` string, nullable, required
      - `presentation_name` string, nullable, required
      - `presentation_mode` 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_list_id` string, nullable, required
      - `price_list_name` string, nullable, required
      - `price_source` string, nullable, required
      - `price_unit_code` 'C62' | 'KGM' | 'GRM' | 'LTR' | 'MLT' | 'MTR' | 'MTK' | 'HUR' | 'DAY' | 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required
      - `counted_quantity` string, nullable, required: Pieces the customer asked for on a variable-weight line sold by count (decimal string, scale 4, greater than 0), e.g. `"4.0000"` for four pieces weighing `quantity` kg in total. Informational: the line is charged and the stock is discounted by `quantity` (the real weight), never by the pieces. `null` on any other line. Only accepted on a `variable_measure` presentation whose unit is a count unit.
      - `counted_unit` 'H87' | 'XPK' | 'XBX' | 'XDS' | 'XBG' | 'XBO' | 'XDJ' | 'XCA' | 'XTB' | 'XCI' | 'XJY' | 'XEN' | 'XCS' | 'null', nullable, required: UN/ECE code of the count unit of `counted_quantity` (`H87` piece, `XPK` pack…). `null` exactly when `counted_quantity` is `null`.
      - `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.
    - `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`.
    - `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).
    - `auto_delivery` object, required: Rich auto-delivery configuration (superset of the scalar `email_to`): the generated invoices are emailed to `recipients` (with optional `cc`) using `subject`/`body`. `recipients`/`cc` are empty lists and `subject`/`body` are `null` when nothing is configured.
      - `send_automatically` boolean, required: Compatibility field DERIVED from `generation_mode`: `true` if and only if `generation_mode` is `issue_and_send`, in which case each generated invoice is emailed to `recipients`.
      - `recipients` string[], required: Primary recipients of the automatic dispatch. Empty list if not configured.
      - `cc` string[], required: Carbon-copy recipients. Empty list if not configured.
      - `subject` string, nullable, required: Custom email subject. `null` to use the default.
      - `body` string, nullable, required: Custom email body. `null` to use the default.
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required

## 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.
- `422`: Validation failed, or the recurring invoice cannot undergo the requested state transition (e.g. resuming a recurrence that is not paused). The `error.param` field identifies which input is invalid, if any.
- `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)
