Saltar al contenido principal

Copiar una lista a un dataset

POST/v1/lists/{id}/copy-to-dataset

Para desarrolladores

Descripción​

Copia los contactos de una lista a un dataset que ya existe. Es la operación inversa de tomar la instantánea de un dataset: sirve para cargar en un dataset una base que ya tiene en un archivo, importándola primero como lista.

La copia es un trabajo en segundo plano: la respuesta llega antes de que se copie nada, y el avance se consulta en la URL del header Location (GET /v1/jobs/{id}). Cada contacto entra al dataset como cualquier otro, con la política de colisión del dataset y validado con las reglas vigentes de cada campo.

La copia es puntual: la lista no cambia y no quedan sincronizadas.

Los contactos llegan al dataset a su tasa de ingreso, la misma que comparten la API y los formularios (POST /v1/datasets/{id}/contacts). Mientras no llegan otros contactos, la copia usa la tasa completa. Cuando la API envía contactos al mismo dataset, la copia le cede el lugar: un contacto que llega por la API nunca espera por una copia.

Autenticación​

Authorizationbearer tokenheaderobligatorio
API key con los scopes list:read y dataset:write. Formato: Bearer <API_KEY>.
X-Instance-Slugstringheaderobligatorio
Identificador de su instancia. Ver Autenticación.

Request​

Path params:

idintegerobligatorio
Identificador de la lista.

Body (JSON):

dataset_idintegerobligatorio
Dataset al que se copian los contactos.
forceboolean
Copia la lista aunque ya se haya copiado a este dataset. Por defecto false.

Response​

201 CreatedDevuelve el trabajo en estado pending, con su URL en el header Location. Tiene los mismos campos que GET /v1/jobs/{id}.
idstring (UUID)siempre presente
Identificador del trabajo.
typestring, enum: `list_import | list_merge | list_snapshot | list_export | list_copy`siempre presente
Qué hace el trabajo: list_import importa un archivo en una lista, list_merge combina listas en una nueva, list_snapshot toma la instantánea de un dataset en una lista nueva, list_export exporta los datos de una lista a un CSV y list_copy copia los contactos de una lista a un dataset.
statusstring, enum: `pending | processing | completed | failed`siempre presente
pending mientras espera su turno, processing mientras se ejecuta, y completed o failed al terminar.
paramsobjectsiempre presente
Sobre qué trabaja. En los trabajos de listas, list_id e import_id: la lista que recibe los datos y su importación. En list_copy, list_id e import_id son la lista de origen y su importación, y se suman dataset_id (el dataset de destino) y rate_per_minute, el máximo de contactos por minuto de la copia: la tasa que tenía el dataset al pedirla, compartida con la API.
resultobject | null
El resultado del trabajo, según su tipo (type). En list_export, el archivo: row_count (filas), size_bytes (tamaño en bytes), expires_at (hasta cuándo se puede descargar) y, una vez borrado, purged_at. En list_copy, los conteos de la copia. Mientras la copia se ejecuta, muestra lo enviado hasta ese momento y next_row, la primera fila que falta enviar. En list_import, list_merge y list_snapshot es null: el resultado está en su importación (import_id de params).
row_count
Filas de la lista.
sent_row_count
Contactos que se enviaron al dataset.
duplicated_row_count
Filas de un contacto que la lista repite: entra una sola vez.
failed_row_count
Filas descartadas por un valor que falta o no cumple su regla (ver reasons).
reasons
Las filas descartadas, por motivo: required_missing (falta un valor que el dataset exige), invalid_value (un valor que no cumple la regla de su campo) o row_too_large (una fila demasiado grande para enviarla).
fields
Los mismos motivos, por columna.
dropped_columns
Columnas de la lista que el dataset no declara, y que por eso no se copiaron.
error_codestring | null
Código del error, si falló (ver Notas de GET /v1/jobs/{id}).
error_messagestring | null
Por qué falló, si falló (en inglés).
created_atstring (date-time)siempre presente
Cuándo se creó el trabajo (ISO 8601, UTC).
started_atstring (date-time) | null
Cuándo empezó su último intento.
finished_atstring (date-time) | null
Cuándo terminó, haya completado o fallado.

Errores​

CódigoCuándo
404La lista no existe o fue eliminada (list_not_found), o el dataset no existe (dataset_not_found).
409La lista todavía no tiene datos (list_has_no_data).
409A la lista le falta la columna que identifica a un contacto en el dataset (list_identity_field_missing).
409A la lista le falta una columna que el dataset exige (dataset_required_column_missing). El mensaje dice cuáles.
409Hay otra copia en curso en la instancia, hacia este dataset o hacia otro (list_copy_in_progress): las copias se ejecutan una a la vez. Ocurre aunque el pedido lleve force.
409La lista ya se copió a este dataset y el pedido no lleva force (list_already_copied).
503No se pudo dejar la copia en cola (service_unavailable). No queda nada creado: reintente.

Detalle completo en Respuestas de error.

Notas
  • Cuándo termina: cuando se enviaron todos los contactos; el dataset los guarda unos segundos después. Por eso result dice cuántos se enviaron, no cuántos eran nuevos ni cuántos ya estaban.
  • Columnas: se emparejan por campo. Una columna que el dataset no declara se descarta y aparece en dropped_columns. Para copiarla, agregue antes el campo al dataset desde el panel.
  • Contactos que ya están en el dataset: se resuelven con la política de colisión del dataset. Con replace, el contacto queda solo con lo que trae la lista, y se borran el teléfono o el código que la lista no traiga.
  • Contactos repetidos en la lista: entran una sola vez, con la última de sus filas que cumple las reglas.
  • Validación: los valores se validan de nuevo con las reglas vigentes de cada campo. Un valor que cumplía cuando se cargó la lista, pero ya no, descarta su fila.
  • Sin filtro: un contacto que se eliminó o bloqueó después de cargar la lista vuelve al dataset. Las bajas, los bloqueos y los consentimientos se aplican al enviar un correo, no al copiar.
  • Dataset inactivo: también recibe la copia.
  • Copia repetida: una segunda copia de la misma lista al mismo dataset se rechaza, para que un pedido repetido por error no la haga dos veces. Con force: true se copia de nuevo. Si un contacto cambió desde la copia anterior y el dataset está en update o replace, el contacto vuelve a tomar los valores de la lista.
  • Sin filas válidas: el trabajo termina failed con list_copy_no_valid_rows, y result igual trae los conteos. Una copia fallida no cuenta como hecha: se puede pedir otra sin force.
  • Duración: depende de la tasa del dataset. A 60.000 contactos por minuto, una lista de 500.000 filas tarda unos 9 minutos, y más si la API envía contactos al mismo dataset mientras tanto. No hay un límite de filas.
  • Interrupciones: la copia se ejecuta por tramos y guarda hasta dónde llegó. Si se interrumpe, sigue desde la primera fila que no envió.
  • Plazo: una copia tiene 24 horas desde que se pidió. Pasado ese plazo, el trabajo termina failed con job_expired, y result dice cuántos contactos alcanzó a enviar.
Request
curl -X POST "https://$API_HOST/v1/lists/12/copy-to-dataset" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Instance-Slug: $SLUG" \
-H "Content-Type: application/json" \
-d '{
"dataset_id": 4
}'
Response
{
"id": "01a17a3c-9d42-7b10-8e6f-2a3b4c5d6e7f",
"type": "list_copy",
"status": "pending",
"params": {
"list_id": 12,
"import_id": 31,
"dataset_id": 4,
"rate_per_minute": 60000
},
"result": null,
"error_code": null,
"error_message": null,
"created_at": "2026-10-26T12:00:00Z",
"started_at": null,
"finished_at": null
}