# Sube documentos desde tus propios sistemas
Source: https://nordvec.com/es/docs/guides/how-to/push-documents#reemplazar-un-origen-de-datos-completo

## Reemplazar un origen de datos completo [#reemplazar-un-origen-de-datos-completo]

Cuando tu sistema puede listar todo lo que debe contener un origen de datos, envía el listado completo como una **sesión de subida**, y los documentos que ya no contiene se mueven a la papelera cuando la sesión se cierra. Las sesiones necesitan una clave API de indexación que tenga `index:delete` además de `index:write`, porque el cierre elimina documentos; la clave que abre una es la única que puede continuarla.

1. Envía la primera página con `"isFirstPage": true`. Es la página `0`.
2. Envía cada página siguiente con su `pageIndex` (`1`, `2`, ...), en cualquier orden.
   Una página enviada dos veces se cuenta una sola vez, por lo que un reintento siempre es seguro.
3. Envía la última página con `"isLastPage": true` y su `pageIndex`. Un listado
   que quepa en una sola página envía `isFirstPage` y `isLastPage` juntos. La
   última página puede no llevar documentos.

Todas las páginas usan el mismo `uploadId`, y cada respuesta incluye el progreso de la sesión en `upload`. La sesión solo se cierra cuando ha llegado cada página desde `0` hasta la última. Cerrarla mueve a la papelera cada documento en el origen de datos que ninguna página de la sesión nombró y que existía antes de que la sesión se abriera. Cualquier otro push al origen de datos mientras la sesión está activa mantiene el documento que nombra: un único push, un lote sin campos de sesión, una actualización de permisos y un reenvío de contenido sin cambios por igual. La papelera guarda lo que el cierre movió allí durante 30 días; enviar un documento de nuevo lo recupera, y lo mismo ocurre al restaurar toda la sesión (ver más abajo).

Una sesión que no recibe ninguna página durante 24 horas caduca y se cierra sin eliminar nada. Una página rechazada se responde con `409 Conflict`, no escribe nada, y su `data.reason` indica el motivo:

| `reason`                                               | Qué hacer                                                                                                                                                                                                                                                                                                                                 |
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upload_incomplete`                                    | Envía las páginas listadas en `missingPageIndexes` y, después, la última página de nuevo                                                                                                                                                                                                                                                  |
| `deletion_confirmation_required`                       | El cierre movería a la papelera más del 20% del origen de datos. Si es correcto, envía la última página de nuevo con `"confirmDeletions"` establecido en `wouldTombstone`                                                                                                                                                                 |
| `deletion_confirmation_too_large`                      | `confirmDeletions` es mayor que el número de documentos que el origen de datos contenía cuando se abrió la sesión. Envía el recuento que esperas eliminar                                                                                                                                                                                 |
| `upload_in_progress`                                   | Hay una sesión abierta en este origen de datos. Si es de tu clave, termínala, espera a que expire o empieza de nuevo con `"forceRestartUpload": true` en tu primera página. Si la abrió otra clave, `forceRestartUpload` la reemplaza solo una vez que no haya recibido ninguna página durante una hora, desde la hora en `restartableAt` |
| `upload_expired`, `upload_missing`, `upload_restarted` | La sesión ha desaparecido; empieza una nueva con un nuevo `uploadId`                                                                                                                                                                                                                                                                      |
| `upload_closed`, `upload_id_reused`                    | El `uploadId` está agotado; usa uno nuevo                                                                                                                                                                                                                                                                                                 |
| `page_index_required`                                  | Tu clave tiene una sesión abierta en este origen de datos; envía `pageIndex` con la página                                                                                                                                                                                                                                                |

Para reanudar después de un fallo, lee la sesión con `GET /documents/push/upload?tenantId=...&datasource=...&uploadId=...` (ámbito `index:status`). Su `missingPageIndexes` lista las páginas que aún faltan por enviar.

### Deshacer el cierre de una sesión [#deshacer-el-cierre-de-una-sesión]

Si una sesión eliminó documentos que no debería haber eliminado, por ejemplo porque el listado que envió estaba incompleto, restáuralos en una sola llamada:

```bash
curl https://nordvec.com/api/v1/documents/push/upload/restore \
  -H "Authorization: Bearer $NORDVEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tenantId": "YOUR_WORKSPACE_ID", "datasource": "confluence-export", "uploadId": "nightly-2026-09-28" }'
```

La clave que abrió la sesión puede restaurarla, y también puede hacerlo un administrador del espacio de trabajo que haya iniciado sesión en Nordvec, para una sesión abierta por cualquier clave. Todos los documentos que el cierre movió a la papelera vuelven con el contenido que tenían, y la respuesta cuenta cuántos: `restored` están activos de nuevo, `purged` ya habían sido eliminados definitivamente por la papelera, y `skipped` habían cambiado desde el cierre (se volvieron a enviar o se eliminaron de nuevo) y se dejaron como están. Restaurar una sesión dos veces responde con los mismos recuentos de la primera restauración y `"replayed": true`, y pone en cola cualquier documento restaurado que aún esté esperando a ser indexado, por lo que repetir una restauración que no respondió es seguro. Una sesión puede restaurarse hasta 35 días después de su cierre, y mientras la papelera aún conserve algún documento que eliminó. Una restauración rechazada se responde con `409 Conflict` y su `data.reason`:

| `reason`                 | Qué significa                                                                                                                                                                                                                            |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upload_not_closed`      | La sesión nunca se cerró, por lo que no eliminó nada                                                                                                                                                                                     |
| `upload_in_progress`     | Hay una sesión abierta en el origen de datos. Restaura una vez que se haya cerrado o expirado                                                                                                                                            |
| `restore_purged`         | Han pasado más de 30 días y la papelera ha eliminado todos los documentos. Vuelve a enviarlos                                                                                                                                            |
| `workspace_not_entitled` | El plan actual del espacio de trabajo no permite restaurar desde la papelera                                                                                                                                                             |
| `corpus_cap_exceeded`    | Restaurar los documentos superaría el límite de documentos del espacio de trabajo, por lo que ninguno se recuperó. `data.wouldRestore` es cuántos necesita y `data.headroom` cuántos caben. Libera espacio y, después, restaura de nuevo |