Copiar una lista a un dataset
/v1/lists/{id}/copy-to-datasetPara 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:readydataset: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
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_importimporta un archivo en una lista,list_mergecombina listas en una nueva,list_snapshottoma la instantánea de un dataset en una lista nueva,list_exportexporta los datos de una lista a un CSV ylist_copycopia los contactos de una lista a un dataset. statusstring, enum: `pending | processing | completed | failed`siempre presentependingmientras espera su turno,processingmientras se ejecuta, ycompletedofailedal terminar.paramsobjectsiempre presente- Sobre qué trabaja. En los trabajos de listas,
list_ideimport_id: la lista que recibe los datos y su importación. Enlist_copy,list_ideimport_idson la lista de origen y su importación, y se sumandataset_id(el dataset de destino) yrate_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). Enlist_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. Enlist_copy, los conteos de la copia. Mientras la copia se ejecuta, muestra lo enviado hasta ese momento ynext_row, la primera fila que falta enviar. Enlist_import,list_mergeylist_snapshotesnull: el resultado está en su importación (import_iddeparams).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) orow_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ódigo | Cuándo |
|---|---|
| 404 | La lista no existe o fue eliminada (list_not_found), o el dataset no existe (dataset_not_found). |
| 409 | La lista todavía no tiene datos (list_has_no_data). |
| 409 | A la lista le falta la columna que identifica a un contacto en el dataset (list_identity_field_missing). |
| 409 | A la lista le falta una columna que el dataset exige (dataset_required_column_missing). El mensaje dice cuáles. |
| 409 | Hay 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. |
| 409 | La lista ya se copió a este dataset y el pedido no lleva force (list_already_copied). |
| 503 | No se pudo dejar la copia en cola (service_unavailable). No queda nada creado: reintente. |
Detalle completo en Respuestas de error.
- Cuándo termina: cuando se enviaron todos los contactos; el dataset los guarda unos segundos después. Por eso
resultdice 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: truese copia de nuevo. Si un contacto cambió desde la copia anterior y el dataset está enupdateoreplace, el contacto vuelve a tomar los valores de la lista. - Sin filas válidas: el trabajo termina
failedconlist_copy_no_valid_rows, yresultigual trae los conteos. Una copia fallida no cuenta como hecha: se puede pedir otra sinforce. - 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
failedconjob_expired, yresultdice cuántos contactos alcanzó a enviar.
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
}'
{
"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
}