Presentación de documentos
Elige la plantilla PDF de una factura, un presupuesto, una proforma o un albarán, consulta lo que cada documento conservó, revísalo tras emitirlo y recupérate de los errores de ETag, CAS y precondición.
La presentación de un documento es el aspecto de su PDF: qué plantilla, qué marca, qué formato de papel. La presentación nunca cambia el contenido fiscal del documento. Lo acompaña en tres momentos:
- Mientras es un borrador eliges una plantilla (o dejas que se herede). Todavía no se congela nada.
- Al emitirlo o entregarlo Factuarea conserva la presentación que se usó. A partir de ahí el original ya no se puede editar.
- Después puedes añadir una revisión de presentación: una nueva presentación conservada, derivada de la anterior y con un motivo. El historial es de solo añadir.
Esta guía cubre los cuatro recursos que la exponen (invoices, quotes,
proformas y delivery_notes), la plantilla de una serie, la
precondición que piden las operaciones de entrega y cómo
recuperarte de cada conflicto. Para construir las plantillas consulta
Plantillas de documentos, y para generar un PDF antes
de comprometer nada, Vistas previas de plantillas.
Las operaciones
Cada recurso expone las mismas cuatro operaciones. {id} es el UUID del documento y
el recurso es invoices, quotes, proformas o delivery-notes. Todas las rutas
de esta guía cuelgan de /v1/companies/{company}/…: {company} es el id
(UUID v7) del NIF con el que operas, y en los ejemplos curl es $COMPANY_ID.
Alcanzar un NIF explica cómo resolverlo.
| Operación | Para qué sirve | Scope |
|---|---|---|
GET /v1/companies/{company}/{resource}/{id}/presentation | Leer el estado actual. Devuelve un ETag. | {resource}:read |
PATCH /v1/companies/{company}/{resource}/{id}/presentation | Elegir o quitar la plantilla de un borrador. | {resource}:write |
GET /v1/companies/{company}/{resource}/{id}/presentation-history | Listar las presentaciones conservadas, paginadas con page y per_page (25 por defecto, hasta 100). | {resource}:read |
POST /v1/companies/{company}/{resource}/{id}/presentation-revisions | Añadir una revisión a un documento que ya no es un borrador. | {resource}:write |
GET /v1/companies/{company}/series/{series}/pdf-template | Leer la plantilla preferida de una serie. Devuelve un ETag. | series:read |
PATCH /v1/companies/{company}/series/{series}/pdf-template | Fijarla o quitarla. | series:write |
{resource}:read y {resource}:write son los scopes que el documento ya tenía:
invoices:write para facturas, delivery_notes:write para albaranes, etc. La
presentación no añade scopes a las operaciones del documento. La
vista previa que alimenta una revisión necesita
además pdfs:read y pdf_templates:read. El servidor MCP expone las mismas
operaciones como get_invoice_presentation, assign_invoice_presentation,
list_invoice_presentations y revise_invoice_presentation (y sus equivalentes
quote, proforma y delivery_note), con los scopes de arriba.
Las escrituras aceptan un Idempotency-Key como cualquier otra escritura de la v1;
consulta Idempotencia. Ninguna de estas operaciones genera un
PDF: mueven metadatos y no consumen presupuesto de PDF.
Las escrituras sobre los recursos de presentación (PATCH y presentation-revisions) responden 422 pdf_presentation_not_ready mientras
la presentación con revisiones no esté activa para tu empresa. El estado te lo
avisa de antemano: render_activation es legacy y can_select y can_revise son
false. Las lecturas siguen funcionando, y también el PDF que ya descargas.
Lee el estado
curl -i https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197c4a0-6b1e-7d52-8f3a-2c9d4e1b7a60/presentation \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"HTTP/1.1 200 OK
ETag: "9f2c1b7e0a4d5c8e3b6a1f0d2c9e4b7a5d8c3f6e1a0b9d2c7e4f5a8b1c3d6e90"{
"data": {
"id": null,
"manual_template_id": null,
"selection_version": 1,
"pointer_version": 1,
"binding_version": 1,
"render_activation": "revisioned",
"can_select": true,
"can_revise": false,
"capture_matches_source": null,
"selection": {
"document_type": "invoice",
"document_id": "0197c4a0-6b1e-7d52-8f3a-2c9d4e1b7a60",
"origin": "series",
"template_id": "0197c4a1-02aa-7c31-9e5b-6d2f8a4c1b73",
"revision_id": "0197c4a1-02ab-7e08-8a14-3b7c9d5e2f40",
"presentation_id": null,
"selection_version": 1,
"base_preset": "modern",
"layout_version": "1",
"locale": "es",
"selection_mode": "inherit",
"purpose": "complete",
"format": "a4",
"contact_id": null,
"commercial_identity_id": null,
"commercial_identity_revision_id": null,
"commercial_identity_version": null,
"preview_context_fingerprint": "5d8c3f6e1a0b9d2c7e4f5a8b1c3d6e909f2c1b7e0a4d5c8e3b6a1f0d2c9e4b7a",
"warnings": []
},
"captured_presentation": null,
"selection_candidate": null,
"selection_availability": { "selectable": true, "reason": null, "requires_confirmation": false },
"warnings": [],
"legal_source_changed": false
}
}El estado tiene exactamente quince campos. Los que te interesan:
| Campo | Significado |
|---|---|
selection | Lo que usaría el documento ahora y por qué: origin es manual, series, contact_default, document_type_default, company_default o legacy (consulta la precedencia). selection_mode es manual solo cuando has elegido una plantilla en el documento. |
selection_version | Contador CAS de la elección manual. Empieza en 1. Devuélvelo como expected_version (o expected_selection_version) cuando cambies la plantilla. |
captured_presentation | La presentación conservada que está vigente, o null mientras no se haya capturado nada (un borrador). Su id es el parent_id de una revisión. |
pointer_version | Contador CAS del historial conservado. Es el expected_version de una revisión. |
can_select, can_revise | Si ahora se permite el PATCH o una revisión. Son el contrato: no los deduzcas del estado del documento. |
selection_availability | selectable es false con un reason (por ejemplo template_archived) cuando la plantilla heredada o elegida ya no se puede usar. |
warnings | Avisos como pdf_series_template_unavailable: la plantilla de la serie no se puede usar y se aplicó el nivel siguiente. Cada uno lleva requires_confirmation. |
legal_source_changed | true cuando los datos legales del emisor o del destinatario cambiaron tras la captura, de modo que una revisión con source_policy: "current_legal" sería distinta. |
capture_matches_source | null en un borrador; en el resto, si la presentación conservada sigue reflejando el documento. |
Un documento que nunca se ha tocado tiene un estado virtual: id es null y las
versiones valen 1. Leer nunca crea nada.
Elige una plantilla en un borrador
Un borrador recibe su plantilla de dos maneras. Ambas usan el mismo selector,
pdf_template_id:
| Envías | Resultado |
|---|---|
Nada (omites pdf_template_id) | Al crear, la plantilla se hereda; al actualizar, se conserva la elección actual. |
"pdf_template_id": null | Al crear, se hereda. Al actualizar o con PATCH, quita la elección manual y vuelve a heredar. |
"pdf_template_id": "<uuid>" | Elección manual: esa plantilla gana a todos los niveles heredados. |
pdf_template_uuid es la grafía de la aplicación interna y la API pública no la
acepta: solo importa cuando la presentación con revisiones está activada para la
empresa, donde enviarla, o enviar los dos selectores, responde 422; en caso contrario
se ignora.
Al crear (POST /v1/companies/{company}/invoices, /quotes, /proformas, /delivery-notes y las
operaciones rectificativas de facturas) envía pdf_template_id. Todavía no hay una
versión con la que comparar, así que expected_selection_version se rechaza cuando POST /v1/companies/{company}/invoices crea una factura y en las operaciones rectificativas. En /quotes, /proformas y /delivery-notes solo importa cuando el POST resuelve un external_id existente (un upsert): entonces es el CAS de la selección y viaja con pdf_template_id.
Al actualizar (PATCH /v1/companies/{company}/invoices/{id} y sus hermanos) la plantilla y su versión
viajan juntas: pdf_template_id y expected_selection_version deben estar las dos
presentes o las dos ausentes. Si falta una, la respuesta es 422 sobre
expected_selection_version.
curl -X PATCH https://api.factuarea.com/v1/companies/$COMPANY_ID/quotes/0197c4b2-91de-7a40-b6c3-5e8f1d2a9c04 \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"pdf_template_id": "0197c4a1-02aa-7c31-9e5b-6d2f8a4c1b73",
"expected_selection_version": 1
}'Con el recurso de presentación cambias solo la plantilla, sin tocar el resto del
documento. El cuerpo tiene una clave obligatoria, template_id (un null explícito
la quita), y una precondición: expected_version en el cuerpo, una cabecera
If-Match con el ETag que leíste, o ambas.
curl -X PATCH https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197c4a0-6b1e-7d52-8f3a-2c9d4e1b7a60/presentation \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Idempotency-Key: $(uuidgen)" \
-H 'If-Match: "9f2c1b7e0a4d5c8e3b6a1f0d2c9e4b7a5d8c3f6e1a0b9d2c7e4f5a8b1c3d6e90"' \
-H "Content-Type: application/json" \
-d '{
"template_id": "0197c4a1-02aa-7c31-9e5b-6d2f8a4c1b73",
"expected_version": 1
}'Responde 200 con el estado nuevo y su ETag nuevo. Elegir la plantilla que ya está
elegida no cambia nada y no mueve la versión. La plantilla debe estar disponible para
el documento (una tuya, publicada, no archivada y compatible: una plantilla de factura
para una factura, con un formato que encaje con el propósito del documento); si no,
no se guarda nada. Un documento que ya no es un borrador responde 422
pdf_presentation_invalid con param: "presentation": a partir de ahí usa una
revisión.
Precedencia y series
Un documento sin elección manual se resuelve por una escalera fija, y gana el primer nivel que tenga una plantilla disponible:
- La selección manual del documento. Es exclusiva: si esa plantilla deja de estar disponible recibes un error explícito, no cae al siguiente nivel.
- La plantilla de la serie en la que se numera el documento.
- La preferencia del cliente (contacto) para ese tipo de documento y propósito.
- El valor por defecto de la empresa para ese tipo de documento y propósito.
- El valor por defecto de la empresa.
- Los ajustes de PDF que la empresa ya tenía (legacy), que siempre existen.
Un nivel heredado que no se puede usar (plantilla archivada, plan sin la
funcionalidad) se salta y se informa como aviso en warnings, de modo que el
documento sigue generándose. Los niveles de cliente y de empresa se configuran con las
operaciones de biblioteca de Plantillas de documentos.
La plantilla de una serie
Una serie guarda una plantilla opcional y una versión propia, independiente de los datos de la serie:
curl https://api.factuarea.com/v1/companies/$COMPANY_ID/series/0197c4c3-17f0-7b92-a1d4-8e6b3c5f2a18/pdf-template \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"{
"data": {
"id": "0197c4c3-17f0-7b92-a1d4-8e6b3c5f2a18",
"object": "series_pdf_template",
"pdf_template_id": null,
"version": 1,
"document_type": "invoice",
"purpose": "complete",
"is_series_archived": false,
"template_state": null,
"supported_formats": ["a4", "ticket_80", "ticket_58"],
"availability": { "selectable": true, "reason": null },
"warnings": []
}
}Haz un PATCH con pdf_template_id (omítelo para conservar, null para heredar, un
UUID para asignar) y la precondición, expected_version y/o If-Match:
curl -X PATCH https://api.factuarea.com/v1/companies/$COMPANY_ID/series/0197c4c3-17f0-7b92-a1d4-8e6b3c5f2a18/pdf-template \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"pdf_template_id": "0197c4a1-02aa-7c31-9e5b-6d2f8a4c1b73",
"expected_version": 1
}'- Asignar una plantilla nunca cambia la máscara de numeración, el contador ni ningún documento ya emitido. La preferencia es solo un valor por defecto para los documentos nuevos.
- También viaja en la propia escritura de la serie:
POST /v1/companies/{company}/seriesaceptapdf_template_id, yPATCH /v1/companies/{company}/series/{series}aceptapdf_template_idconpdf_template_expected_version(obligatorio siempre que esté el selector, incluso si esnullo no cambia). La respuesta de la serie devuelvepdf_template_idypdf_template_version. Consulta Series. - Facturas, presupuestos, proformas y albaranes solo pueden usar una plantilla si es
compatible con el propósito de la serie. Presupuestos, proformas y albaranes usan A4 y
el propósito
complete. - Si la plantilla guardada deja de poder seleccionarse (cambió el plan, se archivó la
plantilla) la preferencia se conserva, la lectura informa de
availability.selectable: falsey del avisoinherited_candidate_unavailable, y los documentos nuevos caen al nivel siguiente. Quitarla siempre está permitido. - Editar la plantilla de la serie exige la autoridad vigente del emisor sobre las
series: un administrador o un usuario sin la restricción de ajustes de series. Si no,
403series_template_access_denied.
La precondición de entrega
En cuanto un documento sale del borrador se conserva su presentación, así que las
operaciones que lo emiten o lo entregan te piden confirmar lo que viste: la
precondición. Cuando la presentación con revisiones está activa para tu empresa y la
petición no lleva precondición, la operación responde
428 pdf_presentation_precondition_required y no ocurre nada.
Qué contiene
Siete campos, todos obligatorios a la vez (dos de ellos admiten null, pero nunca
pueden faltar):
| Campo | De dónde sale el valor |
|---|---|
expected_selection_version | selection_version del estado de la presentación. |
expected_source_token | source_token del artefacto de la vista previa. |
expected_preview_context_fingerprint | expected_preview_context_fingerprint del artefacto de la vista previa. |
expected_template_revision_id | template_revision_id del artefacto de la vista previa (null cuando no se aplica ninguna plantilla de la biblioteca). |
expected_commercial_identity_revision_id | commercial_identity_revision_id del artefacto de la vista previa (null cuando no hay marca). |
purpose | El propósito que previsualizaste: en facturas complete, simplified, corrective o simplified_corrective; complete en el resto de documentos. |
format | a4, ticket_80 o ticket_58; solo a4 en presupuestos, proformas y albaranes. |
Obtén el artefacto con una vista previa del borrador
guardado: POST /v1/companies/{company}/pdf-template-previews con source: { "kind": "persisted_draft", "document_id": "<uuid>" }. La vista previa no congela nada: muestra lo que sería el
documento ahora mismo y devuelve los valores que hay que confirmar. Si el borrador
cambia después (líneas, cliente, serie, plantilla), esos valores quedan obsoletos y el
paso siguiente falla a propósito.
Dónde va
| Operación | Forma |
|---|---|
POST /v1/companies/{company}/invoices/{id}/issue, POST /v1/companies/{company}/invoices/{id}/send | Los siete campos planos, en el nivel superior del cuerpo. |
POST /v1/companies/{company}/quotes/{id}/send, .../accept; POST /v1/companies/{company}/proformas/{id}/send, .../accept; POST /v1/companies/{company}/delivery-notes/{id}/send | Un objeto presentation_precondition con los siete campos. |
POST /v1/companies/{company}/invoices/bulk-send, .../bulk-status; bulk-send y bulk-status de presupuestos, proformas y albaranes | presentation_preconditions: un mapa del UUID de cada documento que esté en ids a su propia precondición. Dos documentos no pueden compartir el token de origen. |
curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/quotes/0197c4b2-91de-7a40-b6c3-5e8f1d2a9c04/send \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"to": "compras@cliente.example",
"presentation_precondition": {
"expected_selection_version": 2,
"expected_source_token": "3b6a1f0d2c9e4b7a5d8c3f6e1a0b9d2c7e4f5a8b1c3d6e909f2c1b7e0a4d5c8e",
"expected_preview_context_fingerprint": "5d8c3f6e1a0b9d2c7e4f5a8b1c3d6e909f2c1b7e0a4d5c8e3b6a1f0d2c9e4b7a",
"expected_template_revision_id": "0197c4a1-02ab-7e08-8a14-3b7c9d5e2f40",
"expected_commercial_identity_revision_id": null,
"purpose": "complete",
"format": "a4"
}
}'Con la presentación con revisiones no activa, esos campos se ignoran, igual que
pdf_template_id y expected_selection_version al crear, actualizar y duplicar: la
petición se comporta exactamente como antes de la función y nunca responde
pdf_presentation_not_ready por ellos. Cuando está activa se validan.
Aceptar un presupuesto o una proforma. El objeto presentation_precondition
solo es obligatorio en la primera captura: cuando el documento aún no tiene captura
retenida (nunca se compartió) o su borrador se editó o cambió de plantilla después de
capturarse. Sin él, la petición responde 428 pdf_presentation_precondition_required
antes de escribir nada. Un documento que ya tiene captura retenida (en una proforma, la
de un envío como borrador) se acepta sin el objeto y esa captura sigue al número; cítala
con el campo opcional expected_presentation_uuid, que responde
409 pdf_presentation_conflict si ya no es la vigente. Aceptar un borrador lo numera y
captura lo que se revisó.
Las operaciones de conversión (POST /v1/companies/{company}/quotes/{quote}/convert,
POST /v1/companies/{company}/proformas/{proforma}/convert,
POST /v1/companies/{company}/delivery-notes/{delivery_note}/convert) no llevan precondición (tampoco POST /v1/companies/{company}/invoices/{invoice}/duplicate): enviarla responde 422 cuando la presentación con revisiones está activa y se ignora en caso contrario. La factura que crean es un
documento nuevo cuya plantilla se resuelve por precedencia. La aceptación
de un presupuesto o una proforma y el envío de un albarán también pueden indicar la
presentación que recibió el cliente con expected_presentation_uuid (el id de la
presentación conservada); el envío de un albarán admite además expected_publication_id, la publicación que recibió el cliente. En el cuerpo del envío de un albarán, template_id es la
plantilla de correo heredada y no tiene nada que ver con pdf_template_id.
En un lote
Una operación masiva no falla en bloque. Cada documento sin su entrada (o con una
obsoleta) se informa en failures[] con su propio error_code, aquí
pdf_presentation_precondition_required o pdf_presentation_context_changed, y los
demás siguen adelante. Consulta Operaciones masivas.
Revisa tras emitir
Cuando un documento se emite, se entrega o se acepta, su presentación conservada ya no se puede editar. Para cambiar el aspecto del PDF añades una revisión. Copia la presentación conservada anterior y cambia solo lo que pidas:
- La plantilla (
template_id): omítela para mantener la del padre,nullpara heredar o un UUID. - Opcionalmente
purposeyformat. El idioma es siempre el del padre. source_policy:capturedconserva los datos legales exactamente como se conservaron;current_legalactualiza los campos de identificación del emisor y del destinatario con los datos actuales. Ellegal_source_changeddel estado te dice cuándo importa.
Una revisión nunca vuelve a emitir el documento, nunca cambia numeración, importes ni el registro de VeriFactu, y nunca borra una presentación anterior.
Como crea evidencia conservada, exige una prueba de que miraste el resultado. Pide una
vista previa con source.kind: "presentation_revision",
el mismo document_id, parent_id, template_id, source_policy y expected_version,
y usa el artefacto que devuelva:
curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197c4a0-6b1e-7d52-8f3a-2c9d4e1b7a60/presentation-revisions \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"parent_id": "0197c4d4-3a21-7f16-9b8e-1c5d7a2e4f90",
"expected_version": 1,
"template_id": "0197c4a1-02aa-7c31-9e5b-6d2f8a4c1b73",
"source_policy": "captured",
"reason": "El cliente pide la plantilla corporativa para su archivo.",
"expected_source_token": "3b6a1f0d2c9e4b7a5d8c3f6e1a0b9d2c7e4f5a8b1c3d6e909f2c1b7e0a4d5c8e",
"expected_preview_context_fingerprint": "5d8c3f6e1a0b9d2c7e4f5a8b1c3d6e909f2c1b7e0a4d5c8e3b6a1f0d2c9e4b7a",
"expected_template_revision_id": "0197c4a1-02ab-7e08-8a14-3b7c9d5e2f40",
"expected_commercial_identity_revision_id": null
}'| Campo | Notas |
|---|---|
parent_id | El captured_presentation.id del estado: la revisión de la que partes. |
expected_version | El pointer_version del estado. Es el CAS del historial. |
reason | Obligatorio, de 1 a 500 caracteres. Se guarda con la revisión. |
expected_source_token, expected_preview_context_fingerprint | Del artefacto de la vista previa (source_token, expected_preview_context_fingerprint). Exactamente 64 caracteres hexadecimales en minúscula. |
expected_template_revision_id, expected_commercial_identity_revision_id | Del artefacto de la vista previa. Se envían los dos junto con la plantilla, o se omiten los dos; expected_template_revision_id debe ser null cuando template_id es null. |
Responde 201 con la nueva presentación conservada y el estado actualizado:
{
"data": {
"presentation": {
"id": "0197c4d5-8e02-7a63-8c1f-4b9d2e6a3f15",
"number": 2,
"parent_id": "0197c4d4-3a21-7f16-9b8e-1c5d7a2e4f90",
"kind": "derived",
"derivation_kind": "visual_revision",
"created_at": "2026-10-14T09:42:17.000000Z",
"reason": "El cliente pide la plantilla corporativa para su archivo.",
"template_id": "0197c4a1-02aa-7c31-9e5b-6d2f8a4c1b73",
"revision_id": "0197c4a1-02ab-7e08-8a14-3b7c9d5e2f40",
"origin": "manual",
"locale": "es",
"purpose": "complete",
"format": "a4",
"source_kind": "captured",
"availability": "captured",
"unavailable_reason": null
},
"state": { "id": "0197c4d5-8e02-7a63-8c1f-4b9d2e6a3f15", "pointer_version": 2 }
}
}(state es el objeto completo del estado; aquí aparece abreviado.)
El historial lista los mismos resúmenes, con meta.total:
curl "https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197c4a0-6b1e-7d52-8f3a-2c9d4e1b7a60/presentation-history?per_page=10" \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"kind es original, derived o legacy_observed (un documento anterior a las
presentaciones conservadas: observado, nunca inventado). derivation_kind indica cómo
se hizo una derivada: visual_revision, legal_snapshot_refresh, legal_qr o
signature_capture. availability es captured mientras la instantánea se puede leer;
si los datos de la firma de un albarán se borraron por privacidad, los metadatos se
conservan y availability pasa a unavailable con unavailable_reason: "privacy_erased".
Revisar a partir de esa presentación responde 410
pdf_signature_personal_data_forgotten.
Una revisión es evidencia sobre la presentación; no significa que los bytes del PDF ya existan. La descarga y la generación de documentos se explican en Vistas previas de plantillas.
ETag, If-Match y recuperación
La presentación usa tres protecciones. Responden a preguntas distintas, así que el cliente debe saber cuál ha fallado:
| Protección | Se envía como | Falla con | Significado | Qué hacer |
|---|---|---|---|---|
| Etiqueta de representación | Cabecera If-Match | 412 pdf_presentation_etag_mismatch (serie: series_template_precondition_failed) | El recurso que leíste no es el actual. | Haz un GET, mira qué cambió y reintenta con el ETag nuevo. |
| Versión (CAS) | expected_version o expected_selection_version | 409 pdf_presentation_conflict (serie: series_template_version_conflict) | Alguien cambió la elección o el historial después de que lo leyeras. | Haz un GET y vuelve a aplicar tu intención sobre la versión nueva. |
| Contexto | Los expected_* de la precondición o de la revisión | 409 pdf_presentation_context_changed | El documento, la plantilla o la marca cambiaron después de la vista previa. | Pide una vista previa nueva y confirma otra vez. |
| Ausente | Nada | 428 pdf_presentation_precondition_required (serie: series_template_precondition_required) | Una protección es obligatoria y no enviaste ninguna. | Envía la versión, el ETag o la precondición. |
Reglas que valen para todos los PATCH:
- La etiqueta es el
ETagfuerte de esa misma URL (GET/PATCHde.../presentationo.../pdf-template), nunca la etiqueta del documento, de un PDF ni de otro recurso. Un validador débil (W/"...") no coincide nunca. - Si envías las dos, primero se evalúa la etiqueta (
412) y después la versión (409). - La operación de revisión no acepta
If-Match; su protección esexpected_versionen el cuerpo (422si envías la cabecera). - Los errores usan el envoltorio habitual. Ramifica según
code;paramseñala la protección (if_match,expected_version,expected_preview_context_fingerprint). El conflicto de serie añadedetails.current_versionydetails.recovery: "reload_or_keep_local".
{
"error": {
"type": "conflict_error",
"code": "pdf_presentation_conflict",
"message": "La presentación documental ha cambiado. Actualiza los datos antes de volver a guardar.",
"param": "expected_version",
"request_id": "req_01JBVH7K9Y4N3CDQ2EHJB1AGSV",
"doc_url": "https://docs.factuarea.com/guides/errors#pdf_presentation_conflict"
}
}Errores
| HTTP | code | Cuándo |
|---|---|---|
| 404 | pdf_presentation_not_found | parent_id no es una presentación de ese documento. |
| 404 | invoice_not_found, quote_not_found, proforma_not_found, delivery_note_not_found, series_not_found | El documento o la serie no existe o pertenece a otra empresa. |
| 410 | pdf_signature_personal_data_forgotten | La presentación perdió sus datos personales (borrado por privacidad); no se puede revisar. |
| 412 | pdf_presentation_etag_mismatch | If-Match no coincide con la representación actual. |
| 409 | pdf_presentation_conflict | expected_version está obsoleto. |
| 409 | pdf_presentation_context_changed | El contexto de la vista previa ya no coincide. |
| 409 | pdf_legal_source_changed | Los datos legales del documento cambiaron después de la presentación que ibas a entregar. Revisa con source_policy: "current_legal". |
| 422 | pdf_presentation_invalid | Clave inválida o desconocida (param), un documento que no admite esta acción (param: "presentation") o un If-Match mal formado. |
| 422 | pdf_presentation_not_ready | La presentación con revisiones no está activa para la empresa. |
| 428 | pdf_presentation_precondition_required | Falta expected_version, If-Match o la precondición donde es obligatoria. |
| 403 | insufficient_scope | A la clave le falta el scope de la tabla de arriba. |
| 403 | series_template_access_denied | El emisor no tiene autoridad sobre las series para esta operación. |
Relacionado
- Plantillas de documentos: construye y gestiona las plantillas y las marcas.
- Vistas previas de plantillas: la vista previa que produce los valores de una precondición.
- Datos de negocio de la factura: los datos estructurados que un documento lleva a cada presentación.
- Envío de documentos: correo, enlaces públicos y el resto de canales de entrega.
- Operaciones masivas e Idempotencia.