Vas a lograr subir un archivo CSV de deudores y deudas a una cartera existente, por la API, y seguir el estado de esa carga hasta que termine.
Cargar una cartera por la API requiere una clave con el scope write (ver Autenticación). Sin ese scope, los dos primeros pasos de este flujo responden 403 forbidden.

El flujo, en tres pasos

1

Pedir una URL de subida

POST /v1/portfolios/:id/imports/upload-url con el nombre del archivo. Devuelve una URL prefirmada de S3, válida por una hora.
2

Subir el CSV con un PUT server-to-server

Hacé un PUT directo a uploadUrl con el contenido del archivo, con Content-Type: text/csv (el mismo que devolvió el paso anterior).
El bucket no acepta CORS de terceros: este PUT tiene que salir de tu backend, nunca del navegador de un cliente. Un PUT hecho desde JavaScript en el navegador va a fallar por CORS, no por permisos.
3

Encolar la importación

POST /v1/portfolios/:id/imports con el s3Key que te dio el primer paso. Responde 202: la importación corre de forma asíncrona.
s3Key tiene que ser exactamente el que devolvió el paso 1 — uno de otro origen responde 400 validation_error.
4

Pollear el estado

GET /v1/imports/:id con el id de la respuesta anterior, hasta que status sea completed, partial o failed.
status es uno de queued, processing, completed, partial (terminó con algunas filas rechazadas) o failed. errorDetails trae el detalle de las filas rechazadas cuando lo hay.

Formato del CSV

El delimitador se detecta automáticamente (;, , o tabulador).

Columnas mínimas

Sólo estas tres son obligatorias en cada fila: Además, cada fila necesita al menos una de debtor_first_name o debtor_full_name (nombre del deudor).

Columnas con default

Si no las incluís, Mozart completa estos valores por vos:

debt_external_id: pasalo tal cual, nunca lo inventes

Si tu sistema tiene un identificador propio para cada deuda, incluilo en debt_external_id — Mozart lo usa para reconocer esa deuda entre una carga y la siguiente. Si tu archivo no trae esa columna para una fila, dejala vacía en vez de completarla con un valor propio: en los modos update y reconcile, una fila sin debt_external_id se trata como “esta deuda no tiene identidad de archivo” y Mozart la administra a su manera entre cargas. Mandar un valor inventado en su lugar rompe ese mecanismo — la próxima carga ya no puede distinguir esa fila de una con identidad real.

Modos de conflicto (conflictResolution)

Cuando la cartera ya tiene deudores, conflictResolution define qué hacer con lo que ya existe:
reconcile tiene un guard: si el archivo reconoce muy pocas deudas contra lo que la cartera ya tiene guardado (y la cartera es lo bastante grande como para que eso sea señal de un archivo equivocado, no de una cartera chica que rotó entera), la importación se rechaza en vez de marcar casi toda la cartera como pagada.

Estados en español y portugués

Si tu archivo trae una columna de estado (del deudor o de la deuda) con etiquetas en español o portugués —activo, pagando, promesa de pago, incobrable, pagado, vencido, etc.— Mozart las reconoce y las traduce al estado interno correspondiente automáticamente.

Siguiente paso

Seguí con Pagos para registrar y leer pagos por la API.