Come inviare una richiesta POST con curl: guida completa

Come inviare una richiesta POST con curl: guida completa

Circa venti miliardi di installazioni di curl sono in esecuzione da qualche parte nel mondo in questo preciso istante. Questo numero proviene dal creatore dello strumento, Daniel Stenberg, che lo gestisce quasi da solo. curl è presente all'interno di router, automobili, satelliti, smart TV, server Linux che ospitano gran parte del web pubblico e ogni principale runtime LLM. Di tutti i verbi HTTP utilizzati da queste installazioni, POST è quello che svolge il lavoro più gravoso. Una richiesta POST con curl è il metodo che la maggior parte degli sviluppatori utilizza per testare, eseguire il debug o integrare un'API per la prima volta.

Il report "State of the API" di Postman del 2025 indica un tasso di adozione di REST pari al 93%. L'82% delle organizzazioni opera ormai almeno in parte con un approccio API-first. POST è il verbo che si utilizza ogni volta che si creano, inviano o trasmettono dati a un server. I carichi di lavoro legati all'intelligenza artificiale hanno ulteriormente accelerato questa tendenza. Il traffico API attribuito all'utilizzo dell'IA è cresciuto del 73% nel 2024 (Postman, 2024) e la documentazione di ogni fornitore di LLM (Leadership in Learning and Management) si apre ormai con un frammento di codice curl POST come "prima chiamata" canonica.

Questa guida illustra tutte le possibili configurazioni di una richiesta POST tramite curl, dalla richiesta minima su una singola riga fino a una chiamata funzionante a una vera API di pagamento in criptovalute. L'obiettivo è fornire un codice da copiare e incollare, non solo da leggere. Che si tratti di inviare dati a un server per la prima volta o di ricostruire un gestore di webhook alle 2 del mattino, i modelli descritti di seguito coprono tutto ciò di cui si ha effettivamente bisogno.

La tabella seguente è una versione abbreviata. Foglio riassuntivo con i flag e le relative funzioni, che illustra le opzioni della riga di comando di curl più utilizzate per l'invio di richieste POST. Ciascuna opzione viene analizzata in dettaglio nelle sezioni successive.

Bandiera Cosa fa Quando lo prendi
`-X POST`, `--request POST` Forza il metodo di richiesta HTTP a POST Metodo esplicito o verbi insoliti
`-d`, `--data` Invia i dati nel corpo della richiesta, imposta automaticamente POST Campi modulo, JSON inline, payload semplici
`--data-binary` Invia file o dati binari senza rimuovere i caratteri di nuova riga Caricamento di file, JSON di grandi dimensioni, dati binari grezzi
`--data-urlencode` Codifica URL del valore prima dell'invio Valori con spazi o caratteri speciali
`--json` Invia i dati con `Content-Type: application/json` e `Accept: application/json` curl 7.82.0 o versioni successive, API JSON
`-H`, `--header` Aggiunge un'intestazione HTTP personalizzata Tipo di contenuto, autorizzazione, chiavi API
`-F`, `--form` Invia dati multipart/form-data con campi modulo o file Caricamento di file, moduli in stile HTML
`-u`, `--user` Invia le credenziali di autenticazione HTTP Basic API legacy, autenticazione semplice tramite nome utente e password
`-i`, `--include` Include le intestazioni di risposta nell'output Analisi delle risposte del server
`-v`, `--verbose` Stampa la richiesta e la risposta complete, intestazioni incluse. Debug di una richiesta POST non riuscita

Comprensione della richiesta POST di curl e del metodo HTTP

Una richiesta POST di curl è una richiesta HTTP POST, inviata con il metodo POST e lanciata dalla riga di comando. Lo strumento curl stesso descrive il suo compito come "trasferimento di dati" attraverso oltre venti protocolli, di cui HTTP è solo uno. POST significa: ecco dei dati, elaborali. Il payload va nel corpo della richiesta, mai nell'URL. Questa caratteristica è il motivo per cui POST gestisce la creazione di risorse, l'invio di moduli e qualsiasi cosa contenga credenziali. GET inserisce i dati nella stringa di query, visibili a ogni proxy e a ogni cronologia del browser. POST no.

La maggior parte dei tutorial tralascia un piccolo ma utile dettaglio. Passando `-d`, curl passa automaticamente al metodo POST. L'opzione esplicita `-X POST`, che specifica un metodo di richiesta personalizzato da utilizzare, è facoltativa. Molti esempi la includono comunque perché la presenza di `-X POST` accanto al payload rende l'intento immediatamente evidente.

Spesso si fa confusione tra PUT e POST, quindi vale la pena fare chiarezza. PUT sostituisce una risorsa in una posizione nota. POST ne crea una nuova o invia dati da elaborare a un endpoint generico.

Richiesta POST con curl

Sintassi base della richiesta POST di curl e l'opzione -d nella pratica.

La richiesta POST minima per curl è di una sola riga:

```

curl -d "username=arya&age=16" https://api.example.com/users

```

Ecco fatto. Richiesta POST, corpo form-urlencoded, niente di complicato. L'opzione `-d` svolge una triplice funzione: inserisce il payload nel corpo della richiesta, inverte il metodo della richiesta in POST e aggiunge `Content-Type: application/x-www-form-urlencoded` come intestazione predefinita. Di solito incollo comunque il modulo leggermente più dettagliato, perché l'intento POST risulta più leggibile in una revisione del codice:

```

curl -X POST -d "username=arya&age=16" https://api.example.com/users

```

Gli stessi byte vengono trasmessi. Gli stessi argomenti della richiesta. Usate quello che il vostro team trova più facile da analizzare. Il flag `-d` è il principale strumento utilizzato per inviare dati a un server dalla riga di comando e gestisce il novanta percento di ciò che uno sviluppatore backend invia a curl: chiamate shell, test webhook, target Makefile, passaggi di GitHub Actions.

Tre varianti di `-d`. `--data-binary` mantiene intatti i byte; la versione standard di `-d` rimuove i caratteri di nuova riga e altera un payload binario. `--data-urlencode` codifica in percentuale: `--data-urlencode "name=I am Daniel"` viene visualizzato come `name=I%20am%20Daniel`. `--data-raw` è la soluzione di ripiego quando un valore inizia con `@` e curl non dovrebbe leggere un file. Più flag `-d` vengono uniti con `&`. Va bene per i moduli. Mai per JSON.

Un ultimo avvertimento: le virgolette. Le virgolette singole attorno al payload impediscono alla shell di interpretare il simbolo `$` o le barre rovesciate. Dimenticatele e vi ritroverete alle 2 del mattino a chiedervi perché metà dei dati inviati tramite POST sono mancanti.

Questi dettagli sono importanti perché curl è uno dei client HTTP più testati al mondo. La retrospettiva di Stenberg del dicembre 2025 ha contato otto release quell'anno. Nove CVE, tutte classificate come basse o medie. 2.179 casi di test attivi, 232 in più rispetto a dodici mesi prima. La release 8.11.1, dicembre 2024, ha corretto la CVE-2024-11053 (una perdita di credenziali netrc e redirect). La versione stabile attuale, a fine aprile 2026, è curl 8.20.0. Chiunque utilizzi una versione inferiore alla 7.82.0 non ha ancora il flag `--json` e deve ricorrere al vecchio schema a tre flag.

Invio di dati JSON con curl utilizzando --json o -H

Nel 2026, JSON sarà la lingua franca delle API REST. Esistono due modi per inviarlo tramite POST con curl. La scelta del metodo dipende interamente dalla versione di curl installata sul computer.

Schema classico a tre flag, funziona ovunque da CentOS 6 in poi:

```

curl -X POST \

-H "Content-Type: application/json" \

-d '{"title":"Tea","quantity":2}' \

https://api.example.com/orders

```

Stesura abbreviata moderna, disponibile dalla versione curl 7.82.0 (marzo 2022):

```

curl --json '{"title":"Tea","quantity":2}' https://api.example.com/orders

```

Il flag `--json` svolge tre funzioni: imposta `Content-Type: application/json`, imposta `Accept: application/json` e invia il corpo della richiesta. Inoltre, permette la composizione: se si passa `--json` più di una volta, i payload vengono concatenati. Utile quando si inviano blocchi JSON a un endpoint di streaming.

Per i payload JSON memorizzati in un file, anteporre `@` al percorso del file. L'invio di dati da un file diventa la prassi standard quando l'oggetto JSON è troppo grande per essere incollato direttamente nel testo, quando è gestito da un sistema di controllo versione o quando viene generato da un altro script.

```

curl -X POST -H "Content-Type: application/json" -d @order.json https://api.example.com/orders

curl --json @order.json https://api.example.com/orders

```

Il secondo schema legge i dati da un file denominato `order.json` e li invia con tutte le intestazioni corrette. Per contenuti JSON di grandi dimensioni o potenzialmente binari, `--data-binary @file.json` è l'opzione più sicura. Non rimuove i caratteri di nuova riga, non interpreta i caratteri speciali e invia dati binari grezzi a un endpoint che si aspetta byte anziché campi modulo. Un terzo schema legge i dati dallo standard input tramite `-d @-`. Utile quando si reindirizza l'output di un altro comando direttamente a una richiesta POST con curl.

La tabella seguente associa i quattro formati JSON più comuni a un singolo endpoint:

Modello Comando Quando utilizzare
In linea, classico `-X POST -H "Content-Type: application/json" -d '{"k":"v"}'` Massima compatibilità con qualsiasi versione di curl.
In linea, moderno `--json '{"k":"v"}'` curl 7.82.0 o versioni successive, sintassi più pulita
Dal file, sicuro `-X POST -H "..." -d @payload.json` Il payload viene mantenuto nel sistema di controllo versione.
Da file, binario sicuro `-X POST -H "..." --data-binary @payload.json` File di grandi dimensioni, payload con interruzioni di riga

Questo aspetto è più importante di prima. Tutti i principali fornitori di LLM (OpenAI, Anthropic, Mistral, Google) aprono la documentazione delle loro API con un esempio di richiesta POST tramite curl che utilizza esattamente questa struttura. Il traffico generato dall'IA ha contribuito per il 73% al volume complessivo delle chiamate API nel 2024 (Postman). curl è ormai il riferimento canonico per "come si chiama questo endpoint".

Richiesta POST con curl

Content-Type, intestazioni e cosa presuppone curl

La maggior parte delle risposte "415 Unsupported Media Type" sono dovute alla mancanza di un'intestazione. Con `-d`, curl aggiunge silenziosamente alla richiesta `Content-Type: application/x-www-form-urlencoded`. Inviando un corpo JSON senza `-H "Content-Type: application/json"` o `--json`, si riceve un errore 415. Nessun avviso, solo il rifiuto.

Altri metadati vengono inviati insieme al corpo della richiesta: Content-Length, l'intestazione Authorization, X-Request-Id per il tracciamento. Gestire correttamente questi metadati è metà del lavoro di integrazione di un'API. L'oggetto JSON in sé è la parte più semplice.

L'opzione `-H` aggiunge intestazioni personalizzate. Ripetere l'operazione se necessario. I nomi delle intestazioni non fanno distinzione tra maiuscole e minuscole; i valori no. Il modo più rapido per eseguire il debug di una richiesta POST configurata in modo errato è eseguirla una volta con l'opzione `-v`, leggere la riga della richiesta e confrontarla con la documentazione dell'API. Otto volte su dieci il bug emerge in pochi secondi.

Altre due note. Content-Length viene impostato automaticamente da curl in base alla dimensione del corpo della richiesta; raramente è necessario sovrascriverlo. `Accept: application/json` indica al server di rispondere in JSON anziché in HTML. Aggiungi un altro `-H` per questo, oppure usa `--json`, che imposta Content-Type e Accept contemporaneamente.

Caricamento dei dati del modulo e dei file con curl POST -F

Per i dati dei moduli in stile HTML con file, il flag corretto è `-F`. Genera una richiesta `multipart/form-data`. Il tipo di contenuto è diverso da quello codificato in URL del modulo, che è quello predefinito con `-d`. Richiede un modello mentale diverso. I tutorial di un solo paragrafo confondono spesso i due concetti, causando veri e propri bug.

`-F` una volta per campo. Campo in formato semplice:

```

curl -F "name=Arya" https://api.example.com/submit

```

Caricamento di un file:

```

curl -F "file=@/path/to/image.png" https://api.example.com/upload

```

Il prefisso `@` indica a curl di leggere il file dal disco e di includerne il contenuto nel corpo della richiesta. curl rileva automaticamente il tipo MIME dal nome del file; è possibile sovrascriverlo esplicitamente quando necessario:

```

curl -F "[email protected];type=image/png" https://api.example.com/upload

```

L'utilizzo di più flag `-F` consente di raggruppare più campi o file in un'unica richiesta:

```

curl -F "title=Vacanze" -F "[email protected]" -F "[email protected]" https://api.example.com/album

```

Per il contenuto grezzo del file senza il wrapper multipart, un'esigenza comune quando si invia un file JSON o un blob binario a un endpoint di streaming, utilizzare invece `--data-binary @file.bin`. In questo modo i byte del file vengono inviati come corpo della richiesta così come sono, con qualsiasi Content-Type impostato esplicitamente.

Autenticazione in curl POST: chiavi basic, bearer e API

Nel 2026, quasi tutte le API REST saranno coperte da tre forme di autenticazione. Autenticazione di base (nome utente più password, codificati in base64 in un'intestazione):

```

curl -u "myuser:mypass" -X POST -d "..." https://api.example.com/login

```

I token Bearer, utilizzati dalla maggior parte delle API moderne, comprese tutte le credenziali emesse tramite OAuth, sono presenti in un'intestazione Authorization personalizzata:

```

curl -H "Authorization: Bearer $TOKEN" --json '{"q":"hello"}' https://api.example.com/query

```

Le chiavi API si trovano in genere in un'intestazione specifica del servizio:

```

curl -H "X-API-Key: $PLISIO_KEY" --json @invoice.json https://api.plisio.net/api/v1/invoices/new

```

Le credenziali vengono ricavate da una variabile d'ambiente o da un gestore di segreti, mai inserite direttamente nel codice. Perché? Il rapporto "State of Secrets Sprawl" di GitGuardian del 2025 ha rilevato 23,8 milioni di nuovi segreti trapelati su GitHub pubblico nel corso del 2024, con un aumento del 25% rispetto al 2023. Oltre il 90% di questi segreti è rimasto valido per cinque giorni dopo la divulgazione. Le credenziali inserite direttamente negli script curl sono una delle principali cause di queste fughe di dati. La sezione sulla sicurezza riportata di seguito descrive il flusso di lavoro.

Esempio pratico di richiesta POST con curl: API di pagamento Plisio

La documentazione di riferimento senza un esempio concreto è pura teoria. La richiesta POST tramite curl riportata di seguito genera una fattura di pagamento in criptovaluta attraverso l'API REST di Plisio. Plisio applica una commissione fissa dello 0,5%; i processori di carte di credito in genere applicano una commissione del 2-4%. Plisio supporta oltre trenta criptovalute e offre integrazioni per diciannove piattaforme di e-commerce.

Perché le API per le criptovalute sono un ottimo strumento di esercitazione. Nel 2025, le stablecoin hanno movimentato circa 28 trilioni di dollari in volume economico reale. Chainalysis ha stimato una crescita del 133% CAGR dal 2023. Il mercato dei gateway di pagamento in criptovalute si aggirava intorno ai 2 miliardi di dollari nel 2025, con una previsione di raggiungere i 2,39 miliardi di dollari nel 2026 (secondo The Business Research Company). BitPay, Coinbase Commerce, Plisio: sceglietene uno qualsiasi. Il primo passo per l'integrazione con qualsiasi gateway moderno è quasi sempre una richiesta POST tramite curl.

La procedura minima per creare una nuova fattura:

```

curl -X POST https://api.plisio.net/api/v1/invoices/new

-H "Content-Type: application/json" \

-H "Autorizzazione: Portatore $PLISIO_API_KEY" \

-d '{

"source_currency": "USD",

"source_amount": 49.99,

"order_number": "INV-1042",

"currency": "BTC",

"email": "[email protected]",

"order_name": "Annual subscription"

}'

```

Una chiamata andata a buon fine restituisce HTTP 201. Il corpo della risposta è un oggetto JSON: un ID fattura generato, un `invoice_url` a cui il cliente effettua il pagamento, un indirizzo del portafoglio di destinazione e un timestamp di scadenza. È possibile elaborarlo con `jq` per estrarre il campo desiderato.

```

... | jq '.data.invoice_url'

```

Questo è lo schema completo. Cambiando l'endpoint e il payload, la struttura si adatta perfettamente a un pagamento BitPay, a un checkout di Coinbase Commerce o a un intento di pagamento Stripe. I flag non cambiano; cambia solo il JSON.

Debug di una richiesta POST curl: -v, --trace, errori

Un POST fallito è un vero rompicapo per il debugger. Riprovare alla cieca è la mossa peggiore. Quattro opzioni da riga di comando coprono la maggior parte delle necessità.

`-v` stampa la riga della richiesta, ogni intestazione della richiesta e lo stato della risposta. Questa è la prima opzione da utilizzare. `--trace-ascii -` è più potente: stampa l'intera conversazione, incluso il corpo di una richiesta POST, sull'output standard. Usa `curl -i` per includere le intestazioni della risposta prima del corpo. E `-w "%{http_code}\n"` scrive solo il codice di stato HTTP, utile quando si eseguono script per i controlli di integrazione continua (CI) su un'API.

Ecco i codici di stato che vedrai più spesso: 400: il server ha analizzato la tua richiesta ma ha rifiutato il payload. 401: intestazione di autenticazione mancante o non valida. 415: Content-Type errato. 500: il server si è bloccato a causa del tuo input. Ognuno di questi esclude uno specifico livello, il che equivale a dimezzare il valore dell'utilizzo dell'opzione `-v` al primo errore.

Sicurezza delle richieste POST di curl: chiavi API, segreti e fughe di dati

Ogni riferimento omette questa sezione. Ogni analisi post-incidente la menziona. Dicembre 2024: la violazione del Dipartimento del Tesoro degli Stati Uniti è stata ricondotta a una chiave API di BeyondTrust trapelata. Esattamente il tipo di credenziale che si trova all'interno delle intestazioni `-H "Authorization: Bearer ..."` negli script di produzione.

La difesa non è appariscente. Leggete i token dalle variabili d'ambiente. Archiviateli in un gestore di segreti come AWS Secrets Manager, HashiCorp Vault o la CLI di 1Password. Mantenete attivo un hook pre-commit con `gitleaks` o `trufflehog`. Ruotate ogni token che sia mai stato presente nella cronologia della shell. Niente di tutto ciò è entusiasmante. Ma funziona. Applicarlo a ogni richiesta POST di curl che inviate è l'abitudine più importante che uno sviluppatore backend possa acquisire nel 2026.

Qualsiasi domanda?

Due modalità. Caricamento multipart (formato HTML): `curl -F "file=@/path/to/file.png" https://api.example.com/upload`. Binario raw, senza wrapper: `curl --data-binary @file.bin -H "Content-Type: application/octet-stream" https://api.example.com/raw`. Il simbolo `@` indica a curl di leggere dal disco.

curl 7.82.0 (marzo 2022) e versioni successive: `curl --json `{"key":"value"}` https://api.example.com`. Nelle versioni precedenti, schema a tre flag: `curl -X POST -H "Content-Type: application/json" -d `{"key":"value"}` https://api.example.com`. JSON già presente in un file? Anteporre `@`: `--json @payload.json` o `-d @payload.json`.

Non definirei nessuno dei due "migliore". curl vince ovunque una shell abbia la meglio su un`interfaccia grafica: chiamate singole, processi di integrazione continua (CI), qualsiasi cosa si possa raggiungere tramite SSH. Postman vince per le raccolte salvate, il confronto affiancato e i flussi di lavoro di team. Li tengo entrambi a disposizione.

Apri la shell, incolla `curl -X POST -d "field=value" https://api.example.com/endpoint` e premi Invio. L`endpoint richiede JSON? Aggiungi `-H "Content-Type: application/json"` oppure usa `--json` se utilizzi curl 7.82.0 o versioni successive. L`output verrà stampato su stdout, pronto per `jq`.

GET, da solo. POST entra in gioco nel secondo caso in cui `-d`, `--data`, `--data-binary`, `--data-urlencode`, `-F` o `--json` vengono inseriti nel comando. Qualsiasi altra opzione (PATCH, DELETE, PROPFIND) richiede `-X` perché nessuna di queste ha un flag di "scorciatoia".

Ecco cosa si ottiene eseguendo `curl -X POST` (o qualsiasi altro comando per l`invio di dati) in un terminale. Il verbo indica al server "prendi questi dati ed esegui un`azione". Lo utilizzo per testare un endpoint REST, riprodurre un webhook che non ha funzionato in produzione o testare una funzione Lambda subito dopo il deployment.

Ready to Get Started?

Create an account and start accepting payments – no contracts or KYC required. Or, contact us to design a custom package for your business.

Make first step

Always know what you pay

Integrated per-transaction pricing with no hidden fees

Start your integration

Set up Plisio swiftly in just 10 minutes.