← All Articles ยท ยท 10 min read

curl Command Examples for REST APIs (2025 Reference)

Practical curl command examples for testing REST APIs. Covers GET, POST, PUT, DELETE, authentication, headers, file uploads, response handling, and debugging flags.

curlrest-apiapi-testingcommand-linehttpdeveloper-tools

curl is the universal tool for interacting with HTTP APIs. It runs on every platform, requires no setup, and outputs raw responses you can inspect, pipe, and script. Once you know the core flags, you can test any REST API without opening Postman.

This is a practical reference โ€” organized by task, with real-world examples you can copy and adapt.


Essential Flags to Know First

-X METHOD       # HTTP method (GET is default)
-H "Header"     # Add a request header
-d "data"       # Request body (implies POST)
-s              # Silent mode (no progress meter)
-i              # Include response headers in output
-I              # Fetch only headers (HEAD request)
-v              # Verbose: show full request + response
-o file.json    # Save response to a file
-w "format"     # Write-out (print specific values after response)
-L              # Follow redirects
-k              # Skip SSL verification (dev only, never production)
--compressed    # Request and decompress gzip responses

GET Requests

Basic GET

curl https://api.github.com/users/octocat

Pretty-print JSON response

curl -s https://api.github.com/users/octocat | python3 -m json.tool

# Or with jq (better formatting + filtering)
curl -s https://api.github.com/users/octocat | jq .

Extract specific fields with jq

# Get just the name and public_repos
curl -s https://api.github.com/users/octocat | jq '{name: .name, repos: .public_repos}'

# Get all items from an array
curl -s https://api.github.com/orgs/github/repos | jq '.[].name'

Query parameters

# URL-encode query parameters manually
curl "https://api.github.com/search/repositories?q=language:javascript&sort=stars&order=desc"

# Or use --data-urlencode with GET
curl -G \
  --data-urlencode "q=language:javascript" \
  --data-urlencode "sort=stars" \
  https://api.github.com/search/repositories

POST Requests

JSON body

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"username": "alice", "email": "[email protected]"}' \
  https://api.example.com/users

Read body from a file

# Create payload.json, then:
curl -X POST \
  -H "Content-Type: application/json" \
  -d @payload.json \
  https://api.example.com/users

Form data (application/x-www-form-urlencoded)

curl -X POST \
  -d "username=alice&password=secret" \
  https://api.example.com/login

Multipart form (file upload)

curl -X POST \
  -F "file=@/path/to/image.png" \
  -F "description=Profile photo" \
  https://api.example.com/upload

Multi-file upload

curl -X POST \
  -F "files[][email protected]" \
  -F "files[][email protected]" \
  https://api.example.com/upload-batch

PUT and PATCH

# PUT: replace the entire resource
curl -X PUT \
  -H "Content-Type: application/json" \
  -d '{"id": 1, "name": "Alice Updated", "role": "admin"}' \
  https://api.example.com/users/1

# PATCH: update specific fields
curl -X PATCH \
  -H "Content-Type: application/json" \
  -d '{"role": "admin"}' \
  https://api.example.com/users/1

DELETE

# Simple delete
curl -X DELETE https://api.example.com/users/1

# Delete with confirmation body
curl -X DELETE \
  -H "Content-Type: application/json" \
  -d '{"confirm": true}' \
  https://api.example.com/users/1

Authentication

Bearer Token (JWT)

TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

curl -H "Authorization: Bearer $TOKEN" \
  https://api.example.com/protected/resource

Basic Auth

# curl handles base64 encoding automatically
curl -u alice:password123 https://api.example.com/resource

# Or send the header directly
curl -H "Authorization: Basic $(echo -n 'alice:password123' | base64)" \
  https://api.example.com/resource

API Key in Header

curl -H "X-API-Key: your-api-key-here" \
  https://api.example.com/resource

API Key in Query String

curl "https://api.example.com/resource?api_key=your-api-key-here"

OAuth2 โ€” Get a Token First

# Step 1: Get access token
TOKEN=$(curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"client_id": "YOUR_ID", "client_secret": "YOUR_SECRET", "grant_type": "client_credentials"}' \
  https://auth.example.com/oauth/token | jq -r '.access_token')

# Step 2: Use it
curl -H "Authorization: Bearer $TOKEN" \
  https://api.example.com/resource

Working with Headers

View response headers

# Include headers in output
curl -i https://api.example.com/resource

# Headers only
curl -I https://api.example.com/resource

# Verbose (shows request headers too)
curl -v https://api.example.com/resource

Custom headers

curl -H "Accept: application/json" \
  -H "Accept-Language: en-US" \
  -H "X-Request-ID: $(uuidgen)" \
  https://api.example.com/resource

Capture specific header values

# Get the Content-Type header value
curl -sI https://api.example.com | grep -i content-type

# Get the status code only
curl -s -o /dev/null -w "%{http_code}" https://api.example.com/resource

Response Handling

Save to file

curl -o response.json https://api.example.com/data

Check HTTP status code

STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://api.example.com/health)
echo "Status: $STATUS"

# Use in scripts
if [ "$STATUS" -ne 200 ]; then
  echo "API is down!"
  exit 1
fi

Measure response time

curl -s -o /dev/null -w "
DNS lookup:    %{time_namelookup}s
TCP connect:   %{time_connect}s
TLS handshake: %{time_appconnect}s
TTFB:          %{time_starttransfer}s
Total:         %{time_total}s
" https://api.example.com/resource

Follow redirects

curl -L https://bit.ly/shortened-url

Scripting with curl

Loop through API pages

#!/bin/bash
PAGE=1
while true; do
  RESPONSE=$(curl -s "https://api.example.com/items?page=$PAGE&limit=100")
  ITEMS=$(echo "$RESPONSE" | jq '.items | length')

  echo "$RESPONSE" >> all_items.json

  if [ "$ITEMS" -lt 100 ]; then
    break
  fi
  ((PAGE++))
done

Health check script

#!/bin/bash
ENDPOINTS=(
  "https://api.example.com/health"
  "https://api.example.com/users"
  "https://api.example.com/products"
)

for URL in "${ENDPOINTS[@]}"; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$URL")
  if [ "$STATUS" = "200" ]; then
    echo "โœ“ $URL"
  else
    echo "โœ— $URL (HTTP $STATUS)"
  fi
done

Retry on failure

curl --retry 3 \
  --retry-delay 2 \
  --retry-on-http-error 429,503 \
  https://api.example.com/resource

Debugging

Full verbose output

# Show everything: headers, TLS info, timing
curl -v https://api.example.com/resource

# Save verbose output to stderr (separate from response)
curl -v -o response.json https://api.example.com/resource 2>debug.log

Simulate a browser request

curl -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
  -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \
  -H "Accept-Language: en-US,en;q=0.5" \
  -H "Connection: keep-alive" \
  https://www.example.com

Handle compressed responses

curl --compressed https://api.example.com/data
# curl will send Accept-Encoding: gzip, deflate and decompress automatically

Skip SSL for dev environments

# Only use this for local development, never production
curl -k https://localhost:8443/api/test

Quick Reference Card

TaskCommand
GET JSONcurl -s URL | jq .
POST JSONcurl -X POST -H "Content-Type: application/json" -d '{}' URL
Bearer authcurl -H "Authorization: Bearer TOKEN" URL
Upload filecurl -F "file=@path" URL
Follow redirectcurl -L URL
Status code onlycurl -s -o /dev/null -w "%{http_code}" URL
Save responsecurl -o output.json URL
Verbose debugcurl -v URL
Retry on failurecurl --retry 3 URL
Response timecurl -w "%{time_total}" URL

Beyond curl: Visual API Testing

For complex API workflows, authentication flows, or when you need to share requests with teammates, a visual tool complements curl:


Download the Developer Productivity Bundle

The Developer Productivity Bundle includes a collection of curl one-liners, API health check scripts, and automation templates for common API tasks โ€” ready to drop into your workflow.

Free Newsletter

Level Up Your Dev Workflow

Get new tools, guides, and productivity tips delivered to your inbox.

Plus: grab the free Developer Productivity Checklist when you subscribe.

Found this guide useful? Check out our free developer tools.