NC Logo UseToolSuite
Developer Tools

cURL for Developers: The Commands You'll Use Every Day

A practical cURL reference for developers — from basic GET requests to authentication, file uploads, and debugging. With code conversion examples for JavaScript, Python, and Go.

Necmeddin Cunedioglu Necmeddin Cunedioglu

Practice what you learn

cURL to Code Converter

Try it free →

Every API documentation page has the same thing: a cURL example. It’s the lingua franca of HTTP requests. Whether you’re testing a new endpoint, debugging a webhook, or demonstrating an API to a colleague, cURL is the tool you reach for first.

The problem is that cURL has over 380 command-line options. Nobody knows all of them. But there are about 15 that cover 95% of real-world use cases. Here’s the reference I wish I’d had when I started.

The Basics

Simple GET Request

curl https://api.example.com/users

That’s it. No flags needed for a basic GET. cURL outputs the response body to stdout.

See Response Headers

# Headers only (HEAD request)
curl -I https://api.example.com/users

# Headers AND body
curl -i https://api.example.com/users

# Verbose mode — see the full request/response exchange
curl -v https://api.example.com/users

The -v (verbose) flag is your best debugging tool. It shows the DNS resolution, TCP connection, TLS handshake, request headers, and response headers — everything you need to diagnose connection issues.

POST Request with JSON Body

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

Breaking it down:

  • -X POST — sets the HTTP method
  • -H — adds a request header
  • -d — sends data in the request body (also implies POST if no -X is specified)

PUT, PATCH, DELETE

# Update a resource
curl -X PUT https://api.example.com/users/123 \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice Updated"}'

# Partial update
curl -X PATCH https://api.example.com/users/123 \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice Patched"}'

# Delete a resource
curl -X DELETE https://api.example.com/users/123

Need this in your language? Our cURL to Code Converter transforms any cURL command into JavaScript (fetch), Python (requests), Go, PHP, and Node.js — instantly.

Authentication

Bearer Token

curl https://api.example.com/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Basic Auth

# Using -u flag (cURL encodes to Base64 automatically)
curl -u username:password https://api.example.com/protected

# Equivalent manual header
curl -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" https://api.example.com/protected

API Key in Header

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

API Key in Query String

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

Note: Always quote URLs with query parameters. The & character has special meaning in the shell and will break your command if unquoted.

Working with Data

Send Form Data

# URL-encoded form (default for -d)
curl -X POST https://api.example.com/login \
  -d "username=alice&password=secret123"

# Multipart form (for file uploads)
curl -X POST https://api.example.com/upload \
  -F "file=@/path/to/document.pdf" \
  -F "description=My document"

The -F flag sends multipart/form-data — required for file uploads. The @ prefix tells cURL to read the file contents.

Read Request Body from a File

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

The @ prefix with -d reads the data from a file. Extremely useful for large payloads or payloads you use repeatedly.

Save Response to a File

# Save output to file
curl -o response.json https://api.example.com/data

# Save with the server's filename (from Content-Disposition)
curl -O https://example.com/files/report.pdf

# Download silently (no progress bar)
curl -s -o output.json https://api.example.com/data

Debugging Requests

Verbose Output

curl -v https://api.example.com/users 2>&1 | head -30

The verbose output uses > for request data and < for response data:

> GET /users HTTP/2
> Host: api.example.com
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/2 200
< content-type: application/json
< x-ratelimit-remaining: 98
< x-ratelimit-limit: 100

Timing Information

curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" https://api.example.com/users

Output:

DNS: 0.023s
Connect: 0.045s
TLS: 0.112s
Total: 0.234s

This is invaluable for diagnosing slow API calls. If DNS is slow, check your resolver. If TLS is slow, the certificate chain might be too long. If the total time is much longer than TLS, the server is slow to respond.

Only Show HTTP Status Code

curl -o /dev/null -s -w "%{http_code}" https://api.example.com/health

Perfect for health checks and monitoring scripts.

Common Patterns

Follow Redirects

# Follow up to 10 redirects (default)
curl -L https://example.com/short-link

# Follow redirects and show each step
curl -L -v https://example.com/short-link

Without -L, cURL returns the 301/302 response instead of following the redirect. This catches people constantly.

Set a Timeout

# Connection timeout (10 seconds to establish connection)
curl --connect-timeout 10 https://api.example.com/data

# Total operation timeout (30 seconds including transfer)
curl --max-time 30 https://api.example.com/data

# Both (recommended for scripts)
curl --connect-timeout 10 --max-time 30 https://api.example.com/data

Always set timeouts in scripts. A cURL command without a timeout will hang indefinitely if the server stops responding.

Send Cookies

# Send a specific cookie
curl -b "session=abc123; theme=dark" https://example.com/dashboard

# Save cookies to a file
curl -c cookies.txt https://example.com/login

# Send cookies from a file
curl -b cookies.txt https://example.com/dashboard

Ignore SSL Certificate Errors

curl -k https://self-signed.example.com/api

The -k flag skips SSL verification. Use this only for local development or testing with self-signed certificates. Never use it in production scripts — it defeats the purpose of TLS.

Custom User-Agent

curl -A "MyApp/1.0" https://api.example.com/data

# Some APIs require a specific user-agent
curl -A "Mozilla/5.0 (compatible; MyBot/1.0)" https://example.com/robots.txt

Converting cURL to Code

Every developer eventually needs to turn a cURL command into actual code. Here’s what the same request looks like across languages:

cURL:

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

JavaScript (fetch):

const response = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123',
  },
  body: JSON.stringify({
    name: 'Alice',
    email: 'alice@example.com',
  }),
});

Python (requests):

import requests

response = requests.post(
    'https://api.example.com/users',
    headers={
        'Content-Type': 'application/json',
        'Authorization': 'Bearer token123',
    },
    json={
        'name': 'Alice',
        'email': 'alice@example.com',
    },
)

Go:

payload := strings.NewReader(`{"name": "Alice", "email": "alice@example.com"}`)
req, err := http.NewRequest("POST", "https://api.example.com/users", payload)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer token123")

client := &http.Client{}
resp, err := client.Do(req)

Converting manually is tedious and error-prone. The cURL to Code Converter handles edge cases like multipart bodies, special characters in headers, and authentication flags automatically.

cURL in Scripts: Best Practices

Always Quote Variables

# WRONG — breaks if TOKEN contains special characters
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/data

# CORRECT
curl -H "Authorization: Bearer ${TOKEN}" https://api.example.com/data

Check the Exit Code

if curl -s -f -o /dev/null https://api.example.com/health; then
  echo "API is healthy"
else
  echo "API is down (exit code: $?)"
fi

The -f flag makes cURL return a non-zero exit code on HTTP errors (4xx, 5xx), which is essential for script error handling.

Retry Failed Requests

curl --retry 3 --retry-delay 5 --retry-max-time 60 https://api.example.com/data

cURL has built-in retry logic. Use it instead of writing a bash retry loop.

Quick Reference

FlagPurposeExample
-XSet HTTP method-X POST
-HAdd header-H "Content-Type: application/json"
-dSend body data-d '{"key": "value"}'
-FSend form/file-F "file=@photo.jpg"
-uBasic auth-u user:pass
-iShow response headers
-vVerbose output
-sSilent (no progress)
-oSave to file-o output.json
-LFollow redirects
-kSkip SSL verify
-bSend cookies-b "session=abc"
-wCustom output format-w "%{http_code}"

Further Reading


Got a cURL command you need in another language? The cURL to Code Converter handles JavaScript, Python, Go, PHP, and Node.js instantly. And if you’re debugging the response headers, run them through the HTTP Header Analyzer for a security assessment.

Necmeddin Cunedioglu
Necmeddin Cunedioglu Author

Software developer and the creator of UseToolSuite. I write about the tools and techniques I use daily as a developer — practical guides based on real experience, not theory.