Back to Tools

cURL POST JSON — Copy-Ready Examples for Any API

Every cURL pattern you need: auth, headers, form data, files, PUT, DELETE, and verbose debugging

cURL is the universal tool for testing REST APIs, debugging HTTP requests, and automating API calls from the command line. This guide provides copy-ready cURL commands for every common scenario — JSON bodies, authentication, file uploads, and more.

Tip: cURL is pre-installed on macOS, Linux, and Windows 10+. Open Terminal (macOS/Linux) or Command Prompt/PowerShell (Windows) and paste any command below.

1. Basic cURL POST with JSON Body

The simplest POST request with a JSON body. The -X POST flag sets the method and -d sends the body.

curl -X POST https://api.example.com/users \
  -d '{"name":"Alice","email":"alice@example.com"}'

2. Add Content-Type: application/json Header

Always include the Content-Type header so the server knows to parse the body as JSON. Without it, many APIs reject or misparse the request body.

curl -X POST https://api.example.com/users \
  -H 'Content-Type: application/json' \
  -d '{"name":"Alice","email":"alice@example.com","role":"admin"}'

3. Add Authorization Bearer Token

Most modern APIs require a Bearer token in the Authorization header. Replace YOUR_TOKEN with your actual JWT or OAuth token.

curl -X POST https://api.example.com/protected/resource \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR...' \
  -d '{"action":"create","data":{"title":"New Item"}}'

4. Add Multiple Custom Headers

Add as many headers as you need using multiple -H flags. Common headers include Accept, X-Request-Id, and custom app headers.

curl -X POST https://api.example.com/orders \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Accept: application/json' \
  -H 'X-Request-Id: req-12345' \
  -H 'X-App-Version: 2.1.0' \
  -d '{"product_id":"abc-123","quantity":2}'

5. POST with API Key Header

APIs that use API keys (OpenAI, Stripe, etc.) typically accept them in a custom header like X-API-Key or sometimes in the Authorization header. Check your API docs for the exact header name.

# Generic X-API-Key header
curl -X POST https://api.example.com/data \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: sk_live_abc123def456' \
  -d '{"query":"hello world"}'

# OpenAI-style API key
curl -X POST https://api.openai.com/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer sk-proj-...' \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"Hello"}]}'

6. POST Form Data (URL-encoded)

Some APIs (especially OAuth endpoints) accept application/x-www-form-urlencoded bodies instead of JSON. Use --data-urlencode for proper encoding of special characters.

# Standard URL-encoded form data
curl -X POST https://api.example.com/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials&client_id=abc&client_secret=xyz'

# --data-urlencode encodes special characters safely
curl -X POST https://api.example.com/search \
  --data-urlencode 'query=hello world & more' \
  --data-urlencode 'category=news'

7. POST Multipart/form-data (File Upload)

Use -F for multipart form data, which is required for file uploads. cURL automatically sets the Content-Type: multipart/form-data header.

# Upload a single file
curl -X POST https://api.example.com/upload \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -F 'file=@/path/to/document.pdf' \
  -F 'folder=reports'

# Upload with custom content type for the file
curl -X POST https://api.example.com/images \
  -F 'image=@/path/to/photo.jpg;type=image/jpeg' \
  -F 'title=Profile Photo' \
  -F 'public=true'

# Upload multiple files
curl -X POST https://api.example.com/batch \
  -F 'files[]=@file1.txt' \
  -F 'files[]=@file2.txt'

8. PUT Request Example

Use -X PUT to update an existing resource. PUT replaces the entire resource; PATCH updates only specified fields.

# PUT — replace the full resource
curl -X PUT https://api.example.com/users/123 \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{"name":"Alice Updated","email":"alice@example.com","role":"admin"}'

# PATCH — update only specific fields
curl -X PATCH https://api.example.com/users/123 \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{"name":"Alice Updated"}'

9. DELETE Request with Auth

DELETE requests typically send no body. Include authentication headers and, if the API requires it, the resource identifier in the URL path.

# DELETE a resource by ID
curl -X DELETE https://api.example.com/users/123 \
  -H 'Authorization: Bearer YOUR_TOKEN'

# DELETE with a body (uncommon but supported by some APIs)
curl -X DELETE https://api.example.com/bulk \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{"ids":["123","456","789"]}'

10. Verbose Mode for Debugging

Add -v to see the full request and response headers, including TLS handshake details. Use -i for just the response headers inline with the body.

# Full verbose — shows request headers, TLS, and response headers
curl -v -X POST https://api.example.com/data \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{"key":"value"}'

# Include response headers in output (-i)
curl -i -X GET https://api.example.com/users/123 \
  -H 'Authorization: Bearer YOUR_TOKEN'

# Silent mode — suppress progress (useful in scripts)
curl -s -X POST https://api.example.com/data \
  -H 'Content-Type: application/json' \
  -d '{"key":"value"}' | jq .

# Save response body to file
curl -X GET https://api.example.com/export \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -o response.json

cURL Flags Quick Reference

FlagPurposeExample
-XSet HTTP method-X POST
-HAdd request header-H 'Content-Type: application/json'
-dSend request body (reads @ as file path)-d '{"key":"val"}'
--data-rawSend body literally (@ not treated as file)--data-raw '{"key":"@value"}'
-FMultipart form data / file upload-F file=@photo.jpg
--data-urlencodeURL-encode form field values--data-urlencode 'q=hello world'
-vVerbose — full request/response headers-v
-iInclude response headers in output-i
-sSilent — suppress progress meter-s
-oWrite response body to file-o output.json
--compressedRequest compressed response (gzip)--compressed

Convert any cURL to Python requests instantly

Paste any cURL command and get an equivalent Python requests snippet with all headers, auth, and body preserved. No signup required.

Open cURL to Python →

Convert browser requests to cURL

Capture any browser network request from the DevTools HAR export and convert it to a ready-to-run cURL command.

Open HAR to cURL →

Frequently Asked Questions

How do I send JSON data with cURL?

Use -d with the JSON string and set the Content-Type header: curl -X POST URL -H 'Content-Type: application/json' -d '{"key":"value"}'

How do I add an Authorization header in cURL?

Add -H 'Authorization: Bearer YOUR_TOKEN' to the command. For API keys, use -H 'X-API-Key: YOUR_KEY' or whatever header name the API expects.

What is the difference between -d and --data-raw?

-d treats values starting with @ as file paths and reads the file content. --data-raw sends the value exactly as provided, treating @ as a literal character. For JSON payloads without @ symbols, they behave identically.

How do I send a file with cURL?

Use -F 'file=@/path/to/file' for multipart/form-data uploads. cURL automatically sets the Content-Type multipart header. For raw binary upload, use --data-binary @/path/to/file with an explicit Content-Type header.

How do I convert a cURL command to Python?

Use the free cURL to Python tool at unblockdevs.com/curl-to-python. Paste your cURL command and get an equivalent Python requests snippet instantly.

Related Tools