Factuarea APIDevelopers

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:

  1. Mientras es un borrador eliges una plantilla (o dejas que se herede). Todavía no se congela nada.
  2. Al emitirlo o entregarlo Factuarea conserva la presentación que se usó. A partir de ahí el original ya no se puede editar.
  3. 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ónPara qué sirveScope
GET /v1/companies/{company}/{resource}/{id}/presentationLeer el estado actual. Devuelve un ETag.{resource}:read
PATCH /v1/companies/{company}/{resource}/{id}/presentationElegir o quitar la plantilla de un borrador.{resource}:write
GET /v1/companies/{company}/{resource}/{id}/presentation-historyListar las presentaciones conservadas, paginadas con page y per_page (25 por defecto, hasta 100).{resource}:read
POST /v1/companies/{company}/{resource}/{id}/presentation-revisionsAñadir una revisión a un documento que ya no es un borrador.{resource}:write
GET /v1/companies/{company}/series/{series}/pdf-templateLeer la plantilla preferida de una serie. Devuelve un ETag.series:read
PATCH /v1/companies/{company}/series/{series}/pdf-templateFijarla 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:

CampoSignificado
selectionLo 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_versionContador CAS de la elección manual. Empieza en 1. Devuélvelo como expected_version (o expected_selection_version) cuando cambies la plantilla.
captured_presentationLa 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_versionContador CAS del historial conservado. Es el expected_version de una revisión.
can_select, can_reviseSi ahora se permite el PATCH o una revisión. Son el contrato: no los deduzcas del estado del documento.
selection_availabilityselectable es false con un reason (por ejemplo template_archived) cuando la plantilla heredada o elegida ya no se puede usar.
warningsAvisos 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_changedtrue 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_sourcenull 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íasResultado
Nada (omites pdf_template_id)Al crear, la plantilla se hereda; al actualizar, se conserva la elección actual.
"pdf_template_id": nullAl 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:

  1. 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.
  2. La plantilla de la serie en la que se numera el documento.
  3. La preferencia del cliente (contacto) para ese tipo de documento y propósito.
  4. El valor por defecto de la empresa para ese tipo de documento y propósito.
  5. El valor por defecto de la empresa.
  6. 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}/series acepta pdf_template_id, y PATCH /v1/companies/{company}/series/{series} acepta pdf_template_id con pdf_template_expected_version (obligatorio siempre que esté el selector, incluso si es null o no cambia). La respuesta de la serie devuelve pdf_template_id y pdf_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: false y del aviso inherited_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, 403 series_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):

CampoDe dónde sale el valor
expected_selection_versionselection_version del estado de la presentación.
expected_source_tokensource_token del artefacto de la vista previa.
expected_preview_context_fingerprintexpected_preview_context_fingerprint del artefacto de la vista previa.
expected_template_revision_idtemplate_revision_id del artefacto de la vista previa (null cuando no se aplica ninguna plantilla de la biblioteca).
expected_commercial_identity_revision_idcommercial_identity_revision_id del artefacto de la vista previa (null cuando no hay marca).
purposeEl propósito que previsualizaste: en facturas complete, simplified, corrective o simplified_corrective; complete en el resto de documentos.
formata4, 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ónForma
POST /v1/companies/{company}/invoices/{id}/issue, POST /v1/companies/{company}/invoices/{id}/sendLos 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}/sendUn 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 albaranespresentation_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, null para heredar o un UUID.
  • Opcionalmente purpose y format. El idioma es siempre el del padre.
  • source_policy: captured conserva los datos legales exactamente como se conservaron; current_legal actualiza los campos de identificación del emisor y del destinatario con los datos actuales. El legal_source_changed del 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
  }'
CampoNotas
parent_idEl captured_presentation.id del estado: la revisión de la que partes.
expected_versionEl pointer_version del estado. Es el CAS del historial.
reasonObligatorio, de 1 a 500 caracteres. Se guarda con la revisión.
expected_source_token, expected_preview_context_fingerprintDel 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_idDel 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ónSe envía comoFalla conSignificadoQué hacer
Etiqueta de representaciónCabecera If-Match412 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_version409 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.
ContextoLos expected_* de la precondición o de la revisión409 pdf_presentation_context_changedEl documento, la plantilla o la marca cambiaron después de la vista previa.Pide una vista previa nueva y confirma otra vez.
AusenteNada428 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 ETag fuerte de esa misma URL (GET/PATCH de .../presentation o .../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 es expected_version en el cuerpo (422 si envías la cabecera).
  • Los errores usan el envoltorio habitual. Ramifica según code; param señala la protección (if_match, expected_version, expected_preview_context_fingerprint). El conflicto de serie añade details.current_version y details.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

HTTPcodeCuándo
404pdf_presentation_not_foundparent_id no es una presentación de ese documento.
404invoice_not_found, quote_not_found, proforma_not_found, delivery_note_not_found, series_not_foundEl documento o la serie no existe o pertenece a otra empresa.
410pdf_signature_personal_data_forgottenLa presentación perdió sus datos personales (borrado por privacidad); no se puede revisar.
412pdf_presentation_etag_mismatchIf-Match no coincide con la representación actual.
409pdf_presentation_conflictexpected_version está obsoleto.
409pdf_presentation_context_changedEl contexto de la vista previa ya no coincide.
409pdf_legal_source_changedLos datos legales del documento cambiaron después de la presentación que ibas a entregar. Revisa con source_policy: "current_legal".
422pdf_presentation_invalidClave inválida o desconocida (param), un documento que no admite esta acción (param: "presentation") o un If-Match mal formado.
422pdf_presentation_not_readyLa presentación con revisiones no está activa para la empresa.
428pdf_presentation_precondition_requiredFalta expected_version, If-Match o la precondición donde es obligatoria.
403insufficient_scopeA la clave le falta el scope de la tabla de arriba.
403series_template_access_deniedEl emisor no tiene autoridad sobre las series para esta operación.

Relacionado

En esta página

¿Te echamos una mano?Contactar con soporte