Passa al contenuto principale

Upload di file

Alcune operazioni API non ricevono direttamente il file binario nella chiamata principale. In questi casi il flusso corretto è sempre in tre passaggi:

  1. caricare prima il file con l'endpoint dedicato POST /api/v3/uploads;
  2. leggere l'upload_id restituito in risposta;
  3. usare quell'ID nella richiesta successiva, nel campo che rappresenta il documento da allegare.

In pratica, il file viene caricato una sola volta e poi richiamato tramite il suo identificativo numerico.

Oggi questo flusso si usa per i documenti delle richieste di cambio intestatario PEC, che usano i campi contract_upload_id, identity_document_upload_id e order_module_upload_id per riferirsi ai documenti già caricati.

Come funziona il flusso​

Quando una chiamata richiede un documento, non devi inserire il contenuto del file dentro il JSON della richiesta finale. Devi invece:

  • caricare il file con l'endpoint di upload;
  • conservare l'ID restituito;
  • passare quell'ID nel campo previsto dalla chiamata applicativa.

Questo approccio ha due vantaggi:

  • separa il caricamento del file dalla logica della richiesta principale;
  • permette all'API di trattare i documenti come risorse già registrate, identificate in modo univoco.

1. Caricare il file​

Il primo passaggio è chiamare POST /api/v3/uploads, che richiede lo scope upload:write.

La richiesta è in formato multipart/form-data, con il file nel campo file. Il file deve rispettare questi limiti:

  • dimensione massima di 5 MB;
  • estensione tra pdf, p7m, jpg, jpeg, png, txt, doc, docx, xls e xlsx;
  • contenuto coerente con l'estensione: ad esempio, un file .pdf deve essere davvero un PDF.

Un file che non rispetta questi limiti viene rifiutato con 400 Bad Request.

Esempio​

L'esempio seguente invia un file all'endpoint dedicato e ottiene in risposta il suo identificativo.

curl --request POST \
--url 'https://api.shellrent.com/api/v3/uploads' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \

Esempio di risposta​

Se il caricamento va a buon fine, la risposta è 201 Created:

{
"error": 0,
"message": null,
"data": {
"upload_id": 987654,
"mimetype": "application/pdf",
"filename": "8f1f0e5d7c2a4b3e.pdf",
"original_filename": "modulo-ordine.pdf",
"file_extension": "pdf",
"upload_date": "2026-10-19T08:30:00Z"
},
"meta": null
}

In questa risposta:

  • upload_id è l'identificativo da usare nelle chiamate successive;
  • filename è il nome con cui il file è stato salvato;
  • original_filename è il nome del file che hai inviato;
  • mimetype e file_extension descrivono il tipo di file;
  • upload_date è la data e ora del caricamento, in UTC.

Il valore davvero importante, per i passaggi successivi, è upload_id.

2. Usare l'ID del file in una richiesta successiva​

Dopo l'upload, il file non va più reinviato. Nella chiamata applicativa devi passare il suo ID numerico.

Esempio: cambio intestatario di una casella PEC​

La richiesta di cambio intestatario di una casella PEC, POST /api/v3/pec-mailboxes/{pec_id}/owner-changes, richiede lo scope pec:write e tre documenti:

  • contract_upload_id: il contratto;
  • identity_document_upload_id: il documento d'identità;
  • order_module_upload_id: il modulo d'ordine.

Insieme ai documenti si indica, con owner_id, il profilo del nuovo intestatario.

Dopo aver caricato i tre file con POST /api/v3/uploads, la richiesta ha questa forma:

curl --request POST \
--url 'https://api.shellrent.com/api/v3/pec-mailboxes/12345/owner-changes' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"owner_id": 321,
"contract_upload_id": 987654,
"identity_document_upload_id": 987655,
"order_module_upload_id": 987656
}'

In questo esempio:

  • i file sono già stati caricati in precedenza;
  • 987654, 987655 e 987656 sono gli ID restituiti da POST /api/v3/uploads;
  • la richiesta finale passa solo quegli ID, non il contenuto dei file.

Lo stesso schema vale per il cambio intestatario di un dominio PEC, con POST /api/v3/pec-domains/{pec_domain_id}/owner-changes.

Gli ID devono riferirsi a file caricati dal tuo account, con qualsiasi client: un ID inesistente o di un altro account viene rifiutato con 400 Bad Request, con un messaggio che indica il campo non valido.

Esempio con gli SDK​

Con l'SDK PHP:

use Shellrent\Sdk\Model\PecMailboxOwnerChangeCreateRequest;

$upload = function (string $path) use ($client): int {
return $client->account()->uploadFile(new \SplFileObject($path))->getData()->getUploadId();
};

$ownerChange = $client->pec()->createPecMailboxOwnerChange(12345, new PecMailboxOwnerChangeCreateRequest([
'owner_id' => 321,
'contract_upload_id' => $upload('contratto.pdf'),
'identity_document_upload_id' => $upload('documento-identita.pdf'),
'order_module_upload_id' => $upload('modulo-ordine.pdf'),
]));

Con l'SDK Python:

from pathlib import Path

from shellrent_sdk import unwrap
from shellrent_sdk.client.api.account import upload_file
from shellrent_sdk.client.api.pec import create_pec_mailbox_owner_change
from shellrent_sdk.client.models import PecMailboxOwnerChangeCreateRequest, UploadFileBody
from shellrent_sdk.client.types import File


def upload(path: str) -> int:
with Path(path).open("rb") as payload:
body = UploadFileBody(file=File(payload=payload, file_name=Path(path).name))
return unwrap(upload_file.sync_detailed(client=client, body=body)).data.upload_id


owner_change = unwrap(create_pec_mailbox_owner_change.sync_detailed(
12345,
client=client,
body=PecMailboxOwnerChangeCreateRequest(
owner_id=321,
contract_upload_id=upload("contratto.pdf"),
identity_document_upload_id=upload("documento-identita.pdf"),
order_module_upload_id=upload("modulo-ordine.pdf"),
),
))

Buone pratiche​

Per evitare errori, è consigliabile:

  • verificare dimensione ed estensione dei file prima di caricarli;
  • completare prima tutti gli upload necessari;
  • salvare gli upload_id restituiti;
  • usare nomi file chiari, così da riconoscere più facilmente i documenti caricati;
  • verificare sempre di associare il file corretto al campo corretto della richiesta finale.

In sintesi​

Quando una API richiede un documento:

  • carica prima il file con POST /api/v3/uploads, con lo scope upload:write;
  • recupera l'upload_id dalla risposta;
  • usa quell'ID nella chiamata successiva.

È questo il pattern da seguire ogni volta che un endpoint richiede un file tramite un campo dedicato come *_upload_id.