Resultados de importación, reintentos de tareas y campos nuevos
La importación de contactos informa de filas actualizadas, avisos y del motivo de cada fila omitida; la de tareas se reintenta sin duplicar; las facturas exponen origin; presupuestos y proformas exponen operation_regime.
5 de octubre de 2026
Esta versión cambia el contrato de las operaciones de importación y añade campos de lectura a facturas, presupuestos y proformas. No hay ninguna operación nueva: todas las que aparecen abajo ya existían y se ha actualizado su respuesta o su comportamiento. La lista de operaciones está al final de la página.
Seguimiento de la importación de contactos
GET /v1/contacts/imports/{id},
POST /v1/contacts/import y
POST /v1/contacts/import/preview
(y las tools MCP get_contact_import, import_contacts y preview_contacts_import)
informan de más cosas sobre lo que hizo una importación.
| Campo | Significado |
|---|---|
updated_count | Filas que actualizaron un contacto existente. added_count ya no las incluye: total_rows = added_count + updated_count + skipped_count + failed_count + unprocessed_count. |
warnings_count | Avisos que produjo la importación. No forma parte de esa suma. |
outcome_kind | changes_applied, nothing_changed, partial o failed. completed no significa que algo cambiara: nothing_changed es una importación que terminó sin crear ni actualizar nada, así que no la presentes como un éxito. partial tiene filas aplicadas y filas fallidas; failed tiene filas fallidas y ninguna aplicada. |
skip_reasons | Filas omitidas contadas por reason. |
first_diagnostics | Hasta 20 diagnósticos agrupados (code, field, severity, message, count, first_row). |
outcomes_truncated | true cuando outcomes contiene las 500 primeras filas y la importación tiene más. |
reason (por fila) | Por qué una fila se omitió, falló o dejó el contacto sin cambios (already_exists, no_changes, merge_review_required, update_not_allowed, identity_conflict, validation_failed…); null cuando la fila se aplicó. |
La vista previa y la respuesta de la importación síncrona añaden los mismos
updated_count, warnings_count, skip_reasons y reason por fila, además de la
acción y el contador skip: filas que no cambian nada porque son idénticas al
contacto existente (no_changes) o apuntan a un contacto archivado
(update_not_allowed). La vista previa también informa de las filas
merge_candidate (ver merge más abajo).
La respuesta síncrona de POST /v1/contacts/import (y la tool import_contacts) lleva también outcome_kind, con los mismos valores que el recurso de seguimiento. Es null en la vista previa, en dry_run y en las importaciones en cola (202), y toma su valor cuando termina la ejecución.
Qué hace conflict_strategy
conflict_strategy decide qué pasa cuando una fila coincide con un contacto
existente por tax_id o external_id:
| Valor | Comportamiento |
|---|---|
reject (por defecto) | Cualquier coincidencia es un conflicto, salvo que la fila solo añada un rol que el contacto aún no tiene. |
update | Aplica los campos que traen valor. Una celda vacía nunca borra un campo. |
merge | No aplica nada y marca la fila para revisión manual: result=skipped, reason=merge_review_required. |
Una importación nunca cambia el tax_id ni el external_id de un contacto
existente y nunca reactiva uno archivado.
Mapeo y columnas
Un mapeo que apunta a una columna que el fichero no tiene se rechaza ahora con
422 mapping_header_not_found y param: mapping. Vuelve a leer las cabeceras y
envía un mapeo cuyas claves coincidan exactamente. El código está en el
catálogo de errores.
El importador acepta cuatro columnas nuevas: iban y bic (una cuenta bancaria que
se añade a las que el contacto ya tiene: de cobro para un cliente, de pago para un
proveedor), customer_default_price_list_name (nombre de una tarifa existente, en
lugar de su UUID) y supplier_default_tax_code (código de un impuesto existente, en
lugar de su UUID).
Un porcentaje de retención negativo (customer_retention_rate, supplier_retention_rate; la convención heredada de cliente, por ejemplo -15) se guarda en positivo (15) y la fila recibe el aviso RETENTION_SIGN_NORMALIZED en sus diagnósticos.
Plantilla de importación
GET /v1/contacts/import/template
admite ahora format=csv|xlsx. csv es el valor por defecto y devuelve un fichero
UTF-8 con BOM y solo las cabeceras, separadas por punto y coma. xlsx devuelve un
libro con las hojas Datos, Instrucciones, Ejemplos y Valores permitidos. La respuesta es un adjunto
(plantilla-contactos.csv o plantilla-contactos.xlsx, con Content-Disposition). Sigue
requiriendo contacts:read y no contiene datos de la empresa.
Reintentos de la importación de tareas
POST /v1/projects/{project}/tasks/import
y la tool MCP import_project_tasks ya se pueden reintentar sin duplicar tareas:
- Repetir la llamada con la misma clave y el mismo documento devuelve el informe de la primera llamada y no crea nada.
- Reutilizar la clave con otro documento responde
409idempotency_key_reused. - Una clave nueva, o ninguna clave en MCP, crea una copia nueva de las tareas. En MCP
el argumento
idempotency_keyes opcional; por HTTP la cabeceraIdempotency-Keysigue siendo obligatoria.
El informe añade warnings_total, el número de avisos que produjo la importación, y
warnings_truncated, true cuando se dejaron fuera algunos. En warnings solo se
conservan los 200 primeros avisos.
Campos de lectura nuevos
| Recurso | Campo | Significado |
|---|---|---|
| Factura (v1 y MCP) | origin | native para una factura emitida en Factuarea, historical_import para una factura histórica registrada por importación: número literal del fichero, sin contador de serie y sin registro VeriFactu. |
| Presupuesto | reference | Número de origen del documento, por ejemplo el que tenía en un sistema anterior cuando se importó. null si no está definido. |
| Presupuesto y proforma | operation_regime | Régimen de operación de IVA: general, intracomunitaria, importacion_exportacion o isp. |
El reason de un movimiento de stock admite también initial.