# Carica documenti dai tuoi sistemi
Source: https://nordvec.com/it/docs/guides/how-to/push-documents

Crea un'origine dati, carica i documenti al suo interno con una chiave API di indicizzazione, scegli chi può leggerli e mettila in pausa o eliminala quando la fonte cambia.



L'API push indicizza documenti provenienti da sistemi per cui Nordvec non dispone di un connettore: un export di una wiki interna, un archivio di ticket, un database di note. Tu invii il testo e chi può leggerlo; Nordvec lo memorizza nell'UE, lo indicizza e lo rende ricercabile e citabile come qualsiasi altro documento. Ogni documento inviato finisce in un'**origine dati**, un contenitore nominato nella tua area di lavoro che un amministratore dell'area di lavoro crea per primo. Un push che nomina un'origine dati inesistente o in pausa viene rifiutato.

## Crea un'origine dati [#crea-unorigine-dati]

Apri **Impostazioni area di lavoro > Origini dati** e scegli **Crea origine dati**. Possono farlo gli amministratori e i proprietari dell'area di lavoro; in un'area di lavoro personale, sei tu.

| Campo | Note                                                                                                                                                           |
| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Nome  | Ciò che le persone vedono nell'elenco delle impostazioni. Fino a 200 caratteri.                                                                                |
| Slug  | Ciò che ogni push nomina. Lettere minuscole, cifre, `-` e `_`, inizia con una lettera o una cifra, fino a 200 caratteri. Non può essere modificato in seguito. |

Lo slug `confluence-export` viene utilizzato negli esempi seguenti.

## Crea una chiave API di indicizzazione [#crea-una-chiave-api-di-indicizzazione]

I push si autenticano con una chiave API della classe **Indexing** che include l'ambito `index:write`; aggiungi `index:status` per tracciare l'indicizzazione e `index:delete` per rimuovere documenti o sostituire un'intera origine dati. Creane una sotto **Impostazioni area di lavoro > Chiavi API**; la chiave grezza inizia con `nv_eu_idx_` ed è mostrata una sola volta. Vedi [Authentication](/docs/guides/authentication). Ogni richiesta nomina anche il tuo id dell'area di lavoro come `tenantId`, l'id nell'indirizzo della tua area di lavoro nell'app (`/w/<workspace id>/...`), e deve essere l'area di lavoro a cui la chiave appartiene.

## Invia un documento [#invia-un-documento]

`/documents/push` crea il documento o lo aggiorna se un documento con lo stesso `id` esiste già nell'origine dati.

```bash
curl https://nordvec.com/api/v1/documents/push \
  -H "Authorization: Bearer $NORDVEC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: page-4711-2026-09-28" \
  -d '{
    "tenantId": "YOUR_WORKSPACE_ID",
    "document": {
      "id": "page-4711",
      "title": "Travel expense policy",
      "datasource": "confluence-export",
      "body": { "mimeType": "text/markdown", "content": "# Travel expenses\n..." },
      "permissions": {},
      "sourceUrl": "https://wiki.example.com/pages/4711",
      "type": "policy"
    }
  }'
```

```json
{ "documentId": "page-4711", "status": "queued", "updated": false }
```

* `id` è il tuo id stabile per il documento all'interno dell'origine dati. Inviare nuovamente lo stesso `id` lo aggiorna; il contenuto invariato è riconosciuto dal suo hash e non viene indicizzato due volte.
* `body.mimeType` è uno tra `text/plain`, `text/markdown`, `text/html`, `application/pdf`, o i tipi Word, Excel e PowerPoint (`.docx`, `.xlsx`, `.pptx`). Il contenuto binario è inviato codificato in base64.
* `sourceUrl` diventa il link "vai alla fonte" su ogni citazione del documento. Omettilo in un re-push per mantenere quello memorizzato, o invia `null` per cancellarlo.
* `type` imposta il `content_type` del documento, su cui la ricerca e l'elenco filtrano.

L'intero corpo della richiesta è limitato a 1 MB, quindi un file grande o un batch corposo risponde con `413`; suddividilo.

## Scegli chi può leggerlo [#scegli-chi-può-leggerlo]

`permissions` è obbligatorio in ogni push, quindi una decisione di condivisione non viene mai presa omettendo un campo. In un'origine dati visibile all'area di lavoro:

| `permissions`                             | Chi può leggere il documento                                           |
| ----------------------------------------- | ---------------------------------------------------------------------- |
| `{}`                                      | Ogni membro dell'area di lavoro                                        |
| `{ "allowedUsers": ["ana@example.com"] }` | Solo le persone elencate                                               |
| `{ "allowedGroups": ["GROUP_ID"] }`       | Membri di quei gruppi dell'area di lavoro, inclusi i gruppi nidificati |
| `{ "allowAllTenantMembers": false }`      | Rifiutato: un documento che nessuno può leggere è una cancellazione    |

Per cambiare chi può leggere un documento senza inviare nuovamente il suo contenuto, usa `POST /documents/push/permissions`. Rendere un documento già ristretto visibile a tutta l'area di lavoro richiede inoltre l'ambito `index:acl-widen`, quindi una sincronizzazione di routine non può annullare silenziosamente una restrizione impostata manualmente.

## Invia in batch [#invia-in-batch]

`/documents/push/bulk` accetta fino a 100 documenti per un'origine dati per chiamata. La risposta conta `accepted` e `rejected` e fornisce un risultato per documento, quindi un documento errato non fa fallire il batch. Il limite di 1 MB per il corpo si applica per chiamata, quindi suddividi i caricamenti di grandi dimensioni in più chiamate sotto lo stesso `uploadId`.

```bash
curl https://nordvec.com/api/v1/documents/push/bulk \
  -H "Authorization: Bearer $NORDVEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "YOUR_WORKSPACE_ID",
    "uploadId": "nightly-2026-09-28",
    "datasource": "confluence-export",
    "documents": [
      { "id": "page-4711", "title": "Travel expense policy", "datasource": "confluence-export",
        "body": { "mimeType": "text/plain", "content": "..." }, "permissions": {} }
    ]
  }'
```

## Sostituisci un'intera origine dati [#sostituisci-unintera-origine-dati]

Quando il tuo sistema può elencare tutto ciò che un'origine dati dovrebbe contenere, invia l'intero elenco come una **sessione di caricamento**, e i documenti che non contiene più vengono spostati nel cestino quando la sessione si chiude. Le sessioni richiedono una chiave API di indicizzazione che includa `index:delete` oltre a `index:write`, perché la chiusura rimuove i documenti; la chiave che ne apre una è l'unica che può continuarla.

1. Invia la prima pagina con `"isFirstPage": true`. È la pagina `0`.
2. Invia ogni pagina successiva con il suo `pageIndex` (`1`, `2`, ...), in qualsiasi ordine.
   Una pagina inviata due volte viene conteggiata una sola volta, quindi un nuovo tentativo è sempre sicuro.
3. Invia l'ultima pagina con `"isLastPage": true` e il suo `pageIndex`. Un elenco
   che rientra in una sola pagina invia `isFirstPage` e `isLastPage` insieme. L'ultima
   pagina può non contenere documenti.

Ogni pagina utilizza lo stesso `uploadId`, e ogni risposta riporta lo stato di avanzamento della sessione in `upload`. La sessione si chiude solo quando ogni pagina da `0` all'ultima è arrivata. Chiuderla sposta nel cestino ogni documento nell'origine dati che nessuna pagina della sessione ha nominato e che esisteva prima dell'apertura della sessione. Qualsiasi altro push all'origine dati mentre la sessione è in corso mantiene il documento che nomina: un singolo push, un batch senza campi di sessione, un aggiornamento dei permessi e un re-push di contenuto invariato allo stesso modo. Il cestino conserva ciò che la chiusura vi ha spostato per 30 giorni; inviare nuovamente un documento lo ripristina, così come il ripristino dell'intera sessione (vedi sotto).

Una sessione che non riceve pagine per 24 ore scade e si chiude senza rimuovere nulla. Una pagina rifiutata riceve una risposta con `409 Conflict`, non scrive nulla, e il suo `data.reason` spiega il motivo:

| `reason`                                               | Cosa fare                                                                                                                                                                                                                                                                                                                                          |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upload_incomplete`                                    | Invia le pagine elencate in `missingPageIndexes`, poi invia di nuovo l'ultima pagina                                                                                                                                                                                                                                                               |
| `deletion_confirmation_required`                       | La chiusura sposterebbe nel cestino più del 20% dell'origine dati. Se è corretto, invia di nuovo l'ultima pagina con `"confirmDeletions"` impostato su `wouldTombstone`                                                                                                                                                                            |
| `deletion_confirmation_too_large`                      | `confirmDeletions` è maggiore del numero di documenti che l'origine dati conteneva quando la sessione è stata aperta. Invia il conteggio che prevedi di rimuovere                                                                                                                                                                                  |
| `upload_in_progress`                                   | Una sessione è aperta su questa origine dati. Se è la chiave della tua sessione, completala, attendi che scada o ricomincia con `"forceRestartUpload": true` sulla prima pagina. Se un'altra chiave l'ha aperta, `forceRestartUpload` la sostituisce solo una volta che non ha ricevuto pagine per un'ora, dal momento indicato in `restartableAt` |
| `upload_expired`, `upload_missing`, `upload_restarted` | La sessione è terminata; inizia una nuova sessione con un nuovo `uploadId`                                                                                                                                                                                                                                                                         |
| `upload_closed`, `upload_id_reused`                    | La `uploadId` è esaurita; usa una nuova                                                                                                                                                                                                                                                                                                            |
| `page_index_required`                                  | La tua chiave ha una sessione aperta su questa origine dati; invia `pageIndex` con la pagina                                                                                                                                                                                                                                                       |

Per riprendere dopo un crash, leggi la sessione con `GET /documents/push/upload?tenantId=...&datasource=...&uploadId=...` (ambito `index:status`). Il suo `missingPageIndexes` elenca le pagine ancora da inviare.

### Annulla la chiusura di una sessione [#annulla-la-chiusura-di-una-sessione]

Se una sessione ha rimosso documenti che non avrebbe dovuto, ad esempio perché l'elenco inviato era incompleto, ripristinali con una singola chiamata:

```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 chiave che ha aperto la sessione può ripristinarla, così come può farlo un amministratore dell'area di lavoro connesso a Nordvec, per una sessione aperta da qualsiasi chiave. Ogni documento che la chiusura ha spostato nel cestino torna con il contenuto che aveva, e la risposta ne conta il numero: `restored` sono di nuovo attivi, `purged` erano già stati eliminati definitivamente dal cestino, e `skipped` erano cambiati dalla chiusura (ri-pubblicati o rimossi di nuovo) e sono stati lasciati così com'erano. Ripristinare una sessione due volte risponde con i conteggi del primo ripristino e `"replayed": true`, e mette in coda ogni documento ripristinato ancora in attesa di essere indicizzato, quindi ripetere un ripristino che non ha risposto è sicuro. Una sessione può essere ripristinata entro 35 giorni dalla sua chiusura, e per tutto il tempo in cui il cestino contiene ancora almeno un documento che ha rimosso. Un ripristino rifiutato viene risposto con `409 Conflict` e il suo `data.reason`:

| `reason`                 | Cosa significa                                                                                                                                                                                                                        |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upload_not_closed`      | La sessione non è mai stata chiusa, quindi non ha rimosso nulla                                                                                                                                                                       |
| `upload_in_progress`     | Una sessione è aperta sull'origine dati. Ripristina una volta che si è chiusa o è scaduta                                                                                                                                             |
| `restore_purged`         | Sono passati più di 30 giorni e il cestino ha eliminato tutti i documenti. Inviarli nuovamente                                                                                                                                        |
| `workspace_not_entitled` | Il piano dell'area di lavoro non consente attualmente il ripristino dal cestino                                                                                                                                                       |
| `corpus_cap_exceeded`    | Riportare i documenti supererebbe il limite di documenti dell'area di lavoro, quindi nessuno è stato ripristinato. `data.wouldRestore` è quanti ne servono e `data.headroom` quanti ne stanno. Libera spazio, poi ripristina di nuovo |

## Traccia l'acquisizione [#traccia-lacquisizione]

Un push risponde non appena il documento viene messo in coda. Chiedi il suo stato di avanzamento con `GET /documents/push/status` (ambito `index:status`), filtrato per origine dati o id del documento. Un documento passa da `queued` attraverso `processing` a `completed`, o a `failed` con un `error`.

## Quando un push viene rifiutato [#quando-un-push-viene-rifiutato]

Un push che nomina un'origine dati sconosciuta o in pausa viene risposto con `422 Unprocessable Content`. Il messaggio nomina lo slug e rimanda a **Impostazioni area di lavoro > Origini dati** nella tua area di lavoro, e l'errore in `data` spiega il motivo e cosa fare:

```json
{
  "defined": true,
  "code": "UNPROCESSABLE_CONTENT",
  "status": 422,
  "message": "Datasource \"confluence-export\" is paused and accepts no documents. A workspace admin resumes it under Workspace settings > Datasources: https://nordvec.com/w/YOUR_WORKSPACE_ID/workspace/settings?tab=datasources",
  "data": {
    "why": "The datasource \"confluence-export\" is paused",
    "fix": "Resume it at https://nordvec.com/w/YOUR_WORKSPACE_ID/workspace/settings?tab=datasources, then retry the push",
    "link": "https://nordvec.com/docs/guides/how-to/push-documents"
  }
}
```

Non riprovare automaticamente questi: hanno successo solo dopo che un amministratore crea o riprende l'origine dati.

## Rimuovi un documento [#rimuovi-un-documento]

`POST /documents/push/delete` (ambito `index:delete`) rimuove un documento inviato tramite il suo `datasource` e `id`. I documenti che smetti di inviare non vengono rimossi automaticamente: elimina ciascuno di quelli che ritiri, oppure invia l'intero elenco dell'origine dati come sessione di caricamento, come descritto sopra.

## Metti in pausa, riprendi ed elimina [#metti-in-pausa-riprendi-ed-elimina]

* **Metti in pausa** rifiuta ogni ulteriore push nell'origine dati. I suoi documenti rimangono ricercabili. Un push già in fase di scrittura quando metti in pausa viene completato.
* **Riprendi** accetta nuovamente i push.
* **Elimina** rimuove l'origine dati e ogni documento inviato ad essa, insieme al loro indice di ricerca. Il tuo sistema mantiene la sua copia, quindi inviarli nuovamente dopo aver ricreato l'origine dati li ripristina. Un'eliminazione non può essere annullata.

Se un altro amministratore ha modificato l'origine dati dopo che hai caricato l'elenco, l'azione viene rifiutata e l'elenco si ricarica, così puoi decidere nuovamente in base a ciò che c'è ora. Ogni creazione, messa in pausa, ripresa ed eliminazione viene registrata nel registro di audit dell'area di lavoro.

<Callout>
  L'elenco delle impostazioni mostra a chi è visibile ogni origine dati. Chi può leggere un documento inviato è deciso dal `permissions` inviato con esso; creare, mettere in pausa o eliminare un'origine dati non amplia mai l'accesso a nulla.
</Callout>

<Callout>
  Le scritture push sono idempotenti: ripeti lo stesso `Idempotency-Key` in ogni tentativo di una scrittura, e un duplicato viene risposto dal primo tentativo invece di essere applicato due volte. Vedi [Errori e limiti di frequenza](/docs/guides/errors-and-rate-limits).
</Callout>

## Passaggi successivi [#passaggi-successivi]

<Cards>
  <Card title="Elenca e recupera documenti" href="/docs/guides/how-to/list-documents" />

  <Card title="Filtra e affina la ricerca" href="/docs/guides/how-to/filter-search" />

  <Card title="Riferimento API" href="/docs/api" />
</Cards>
