---
title: "Force-create VeriFactu record for invoice"
method: POST
path: "/companies/{company}/invoices/{invoice}/verifactu"
tags: ["VeriFactu"]
---

# Force-create VeriFactu record for invoice

`POST /companies/{company}/invoices/{invoice}/verifactu`

## Request

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

Creates the VeriFactu alta record for an already-issued invoice and enqueues AEAT transmission. Use when automatic creation on send was skipped.

## Path parameters

- `company` string, uuid, required
- `invoice` string, uuid, required

## Headers

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

## Response `201`

The newly created VeriFactu record. Transmission to AEAT is asynchronous.

- object
  - `data` VeriFactuRecord, required: A VeriFactu (Spanish AEAT SIF) record (alta/anulación) associated with an invoice. Includes the hash chain (`huella`), AEAT CSV and transmission status for reconciliation.
    - `id` string, required: UUID v7 of the VeriFactu record.
    - `object` 'verifactu_record', required
    - `type` string, required: Record type: `alta` (registration) or `anulacion` (cancellation).
    - `invoice_type` string, required: AEAT invoice type (F1, F2, F3, R1-R5, …).
    - `invoice_number` string, required: Number of the associated invoice.
    - `date` string, required: Record date.
    - `amount` string, required: Total amount of the associated invoice.
    - `status` string, required: Transmission status (pending, submitted, accepted, rejected, error).
    - `huella` string, required: Chained SHA-256 fingerprint of the record (VeriFactu fingerprint).
    - `aeat_submission_id` string, nullable, required: Submission identifier assigned by AEAT (column `aeat_submission_id`). `null` until AEAT returns it. Never the internal PK of the record.
    - `aeat_csv` string, nullable, required: Secure Verification Code (Código Seguro de Verificación) returned by AEAT on acceptance. `null` until AEAT assigns it.
    - `environment` string, required: AEAT environment (`sandbox` / `production`).
    - `transmitted_at` string, date-time, nullable, required: ISO 8601 date of the last transmission that reached AEAT. `null` in PENDING/REJECTED/ERROR states.
    - `is_simplificada` boolean, required: Whether the invoice is simplified (F2).
    - `is_substitute_for_simplified` boolean, required: Whether it substitutes one or more simplified invoices (F3).
    - `created_at` string, date-time, required
    - `aeat_error_code` string, nullable, required: Error code of the last AEAT rejection or failure (for example `1110` or `4112`), the internal code of a record that is stopped (`MISSING_CERTIFICATE`, `MISSING_REPRESENTATION`, `SYSTEM_CERTIFICATE_UNAVAILABLE`), `SCHEMA_INVALID` on a `rejected` record that was never sent because it does not meet the AEAT XML schema (fix it with a subsanation), or the warning code of a record accepted with errors; `null` when there is none. Without it you cannot tell a `4112` (presenter not enabled by AEAT) from a network failure.
    - `is_blocked` boolean, required: Whether the record is BLOCKED: it is in `error` with NO automatic retry, so it does not go out again until someone reactivates it (fix the cause, then `POST /v1/companies/{company}/verifactu/records/retry-blocked`, or `POST /v1/companies/{company}/verifactu/records/{record}/retry` one by one), and it holds back the rest of the chain of the company. `false` for a record that retries by itself, with a backoff of at most one hour (art. 16.4 of Order HAC/1177/2024).
    - `block_reason` 'MISSING_CERTIFICATE' | 'MISSING_REPRESENTATION' | 'SYSTEM_CERTIFICATE_UNAVAILABLE' | 'PRESENTER_NOT_ENABLED' | 'SUBMISSION_REJECTED' | 'null', nullable, required: Why the remission of the record is stopped, or `null`. `MISSING_CERTIFICATE`: your company has no usable certificate (missing, expired, revoked or for another tax ID). `MISSING_REPRESENTATION`: the remission mode is a third-party one and there is no current representation of the kind it asks for. `PRESENTER_NOT_ENABLED`: AEAT says the presenter is not enabled (`4112` or `3003`). `SUBMISSION_REJECTED`: AEAT rejected the submission for a client-side fault. These four need an action from you and make `is_blocked` true. `SYSTEM_CERTIFICATE_UNAVAILABLE`: the certificate of Factuarea that remits in the third-party modes is not available; it is on our side, does NOT block (`is_blocked` stays `false`) and the record retries by itself.
    - `can_subsanar` boolean, required: Whether the record admits `POST /v1/companies/{company}/verifactu/records/{record}/subsanar`: an `alta` that is ACCEPTED (or accepted with errors) or REJECTED by AEAT and is the last one of its invoice, which has not been annulled. It is the very rule that endpoint applies, so `true` guarantees it will not refuse the record by its state; whether there is something to correct and whether it changes a field of the hash (`requires_annulment`) is only known when you subsanar.
    - `aeat_warning_requires_subsanation` boolean, nullable, required: For a record AEAT accepted with errors (`status` `accepted` with an `aeat_error_code`), whether AEAT requires a subsanation of that admissible error: every `2xxx` code does except `2004` (FechaHoraHusoGenRegistro) and `2009` (ClaveRegimen with IPSI), which AEAT exempts (AEAT «Validaciones» v1.2.2, §4.3.1). `false` for a warning that is not an AEAT code (`duplicate_annulled`: review the invoice instead). `null` when the record is not accepted with a warning.

## 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.
- `409`: The request conflicts with data that already exists or with a request running at the same time. `resource_locked` with `subcode` `chain_position_conflict`: another process was generating VeriFactu billing records for the company at the same time and this one could not take its place in the chain after several attempts. Nothing was written; send the request again. `resource_conflict`: another request was reserving identifiers for the same kind of record at that moment and this one could not complete its reservation. Nothing was written; send the request again after a few seconds.
- `422`: Validation failed, or the invoice cannot undergo the requested state transition (e.g. marking an already-paid invoice as paid, or editing an issued invoice — use a corrective instead). The `error.param` field identifies which input is invalid, if any. Issuing or annulling an invoice can also be rejected with `verifactu_not_eligible`: either a field of the invoice does not fit its billing record, or — only when the company has VeriFactu enabled in NO VERI*FACTU mode — it has no usable signing certificate (`error.subcode: signing_certificate_unavailable`; `error.param` is `certificate`, `representation` or `system_certificate`, depending on what is missing); in both cases the invoice stays exactly as it was.
- `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)
