Generar factura rectificativa
Emite una factura rectificativa (RD 1619/2012 art. 15) que corrige a una factura ya emitida. Devuelve 201 con la nueva factura: is_corrective: true, corrective apuntando a la original y un número derivado del de esta en la misma serie (F-2026-0042-REC1, -REC2… para rectificativas sucesivas).
Flujo: la original debe estar ya emitida (sent o paid) → la rectificativa nace ya emitida, nunca como borrador → cuando VeriFactu está activo su alta se transmite a la AEAT de forma asíncrona, así que un 201 no significa que la AEAT ya la haya aceptado. La original no se modifica nunca: conserva su número, su estado y su propio registro VeriFactu. Una rectificativa es un documento adicional, no una edición.
Total o parcial. correction_type: full es una sustitución (naturaleza VeriFactu S): las lines que envías son los importes finales correctos, y omitir lines por completo la convierte en una anulación total, donde cada línea original se copia negada y con el prefijo [ANULACION]. correction_type: partial es una rectificación por diferencias (naturaleza I): lines es obligatorio y cada una es un delta — típicamente negativo — con el prefijo [AJUSTE]. En una rectificación parcial una línea solo mueve stock si declara su propio product_id; en una sustitución el producto se hereda de la línea original del mismo índice.
Código R de la AEAT. Por defecto se deriva de correction_reason: error_fundado → R1, concurso → R2, incobrable → R3, el resto → R4; una rectificativa de una factura simplificada (F2) nace siempre R5 sea cual sea el motivo. correction_code sobrescribe esa derivación, pero se valida contra la matriz legal — original F2 → solo R5; original F1/F3 → solo R1–R4. Cualquier otra combinación devuelve 422 con los allowed_values legales.
Límites: las originales en draft, overdue, cancelled y annulled devuelven 422 (una factura overdue hay que cobrarla o anularla antes); una rectificativa no se puede rectificar a su vez — emite en su lugar una nueva rectificativa de la original. Lista todas las rectificativas de una factura con GET /v1/invoices/{id}/correctives.
En: header
Parámetros de ruta
Parámetros de cabecera
Clave opaca generada por el cliente (hasta 255 caracteres; se recomienda UUID v7) que hace seguros los reintentos: la primera respuesta se cachea y se reproduce en las repeticiones sin volver a ejecutar la mutación. Reutilizar una clave con un cuerpo distinto devuelve 409 idempotency_key_reused. Consulta la guía de Idempotency.
1 <= length <= 255Fija la versión de la API (YYYY-MM-DD, versionado por fecha estilo Stripe) para esta petición; omítelo para usar la versión fijada de la clave, o la última si no hay ninguna. Versión no soportada → 400 unsupported_api_version; malformada → 400 parameter_invalid_format. La versión efectiva se refleja en la cabecera de respuesta Factuarea-Version. Consulta la guía de Versioning.
dateOpera en nombre de una empresa hija (API key maestra de gestoría): pasa su id público (UUID v7) y la petición se ejecuta contra los datos de esa hija sin cambiar el scope, el tier ni el environment de la clave (omítelo para usar la propia empresa de la clave). UUID inválido → 400 parameter_invalid_uuid; id desconocido o no propio → 404 profile_not_found. Consulta la guía de Acting on behalf.
uuidCuerpo de la petición
application/json
Definiciones de TypeScript
Usa el tipo request body en TypeScript.
Cuerpo de la respuesta
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
import { Factuarea } from "@factuarea/sdk";const factuarea = new Factuarea({ apiKey: process.env.FACTUAREA_API_KEY! });const result = await factuarea.invoices.corrective("01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01", { // request body — see the schema below });{
"data": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a60",
"object": "invoice",
"number": "RECT-2026-00007",
"is_number_assigned": true,
"type": "R1",
"series": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8b04",
"code": "RECT-2026"
},
"client": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01",
"name": "Acme Soluciones SL"
},
"status": "issued",
"issued_on": "2026-03-22",
"due_on": "2026-04-21",
"subtotal": -500,
"taxes_total": -105,
"total": -605,
"total_disbursements": 0,
"total_to_pay": -605,
"currency": "EUR",
"notes": "Rectificativa por descuento comercial sobre FAC-2026-00010.",
"external_id": "ERP-RECT-2026-0007",
"lines": [
{
"object": "invoice_line",
"description": "Rectificación: descuento comercial 5 h consultoría",
"product": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8b03",
"name": "Consultoría técnica (hora)"
},
"quantity": 5,
"unit_price": -100,
"tax_rate": 21,
"retention_rate": 0,
"surcharge_rate": 0,
"discount_percent": 0,
"subtotal": -500,
"taxes": -105,
"total": -605,
"indirect_tax_regime": "iva",
"aeat_tax_code": "S1",
"line_type": "NORMAL"
}
],
"metadata": {
"order_id": "PO-2026-0010"
},
"tags": [
"rectificativa",
"cliente-vip"
],
"custom_fields": [
{
"field": "centro_coste",
"value": "CC-2026-001"
}
],
"operation_regime": "general",
"exemption_reason": null,
"legal_mentions": [],
"exclude_347": false,
"verifactu_status": "accepted",
"paid_amount": 0,
"pending_amount": -605,
"payments": {
"detail": [],
"total": 0,
"pending": -605
},
"is_corrective": true,
"corrective": {
"original_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a10",
"original_number": "FAC-2026-00010",
"original_date": "2026-02-01",
"correction_reason": "R1",
"correction_type": "por_sustitucion",
"correction_nature": "S",
"base_rectificada": -500,
"cuota_rectificada": -105,
"correction_aeat_type": "R1"
},
"payment": null,
"public_link": {
"object": "public_link",
"url": "https://app.factuarea.com/d/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a60",
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a60",
"enabled": true,
"expires_at": "2026-09-22T23:59:59Z",
"max_days": 120
},
"substituted_by": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a50",
"number": "FAC-2026-00050"
},
"recurring": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a08"
},
"paid_at": null,
"paid_on": null,
"sent_at": "2026-03-22T09:10:00Z",
"voided_at": null,
"void_reason": null,
"scheduled_for": null,
"scheduled_action": null,
"created_at": "2026-03-22T09:00:00Z",
"updated_at": "2026-03-22T09:10:00Z"
}
}{
"error": {
"type": "authentication_error",
"code": "missing_api_key",
"message": "No se ha proporcionado una API key válida en el header Authorization.",
"param": null,
"doc_url": "https://docs.factuarea.com/guides/errors#missing_api_key",
"request_id": "req_01HKQS5N8VR7QXJ9K3T6BWPMZA"
}
}{
"error": {
"type": "authorization_error",
"code": "insufficient_scope",
"message": "Esta API key no tiene el scope requerido para esta operación.",
"param": null,
"doc_url": "https://docs.factuarea.com/guides/errors#insufficient_scope",
"request_id": "req_01HKQS5NBC3P8M1KX4V7SLNHQD"
}
}{
"error": {
"type": "not_found_error",
"code": "resource_not_found",
"message": "El recurso solicitado no existe o pertenece a otra empresa.",
"param": null,
"doc_url": "https://docs.factuarea.com/guides/errors#resource_not_found",
"request_id": "req_01HKQS5NEQ6X1R4N9B0C5DWTPG"
}
}{
"error": {
"type": "idempotency_error",
"code": "idempotency_key_reused",
"message": "La cabecera `Idempotency-Key` ya se usó con un body distinto. Usa una clave nueva o reenvía exactamente el mismo body.",
"param": null,
"doc_url": "https://docs.factuarea.com/guides/errors#idempotency_key_reused",
"request_id": "req_01HKQS5NHT9A4U7R2E3F8GZWTJ"
}
}{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid",
"message": "El campo `name` es obligatorio y no puede estar vacío.",
"param": "name",
"doc_url": "https://docs.factuarea.com/guides/errors#parameter_invalid",
"request_id": "req_01HKQS5NGS8Z3T6Q1D2E7FYVSI"
}
}{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Has excedido el rate limit de 60 peticiones por minuto. Reintenta tras 30 segundos.",
"param": null,
"doc_url": "https://docs.factuarea.com/guides/errors#rate_limit_exceeded",
"request_id": "req_01HKQS5NKW1C6W9T4G5H0JBZVL"
}
}{
"error": {
"type": "api_error",
"code": "internal_error",
"message": "Ha ocurrido un error inesperado. Si persiste, contacta con soporte adjuntando el request_id.",
"param": null,
"doc_url": "https://docs.factuarea.com/guides/errors#internal_error",
"request_id": "req_01HKQS5NLX2D7X0U5H6J1KCAWM"
}
}