Skip to content
LangStop

Tutorials

Keyboard Shortcuts

ActionShortcut
Toggle SidebarCtrl+B
Save TabCtrl+S
Close TabAlt+W
Switch to Tab 1Alt+Shift+1
Switch to Tab 2Alt+Shift+2
Switch to Tab 3Alt+Shift+3
Switch to Tab 4Alt+Shift+4
Switch to Tab 5Alt+Shift+5
Switch to Tab 6Alt+Shift+6
Switch to Tab 7Alt+Shift+7
Switch to Tab 8Alt+Shift+8
Switch to Tab 9Alt+Shift+9

How to Use Curl — Command Line HTTP Client Guide

What is Curl?

curl (Client URL) is a command-line tool and library for transferring data using various network protocols. Originally developed by Daniel Stenberg in 1997, curl has become the de facto standard for making HTTP requests from the terminal. It is installed by default on most Unix-based systems (Linux, macOS) and is available for Windows via WSL, PowerShell, or direct downloads.

Curl supports a wide range of protocols including HTTP, HTTPS, FTP, SFTP, SCP, LDAP, SMTP, POP3, and many more. It is widely used for API testing, automation scripts, CI/CD pipelines, and debugging network services.


Basic Syntax

The fundamental syntax of a curl command is:

curl [options] URL
  • [options] — One or more command-line flags that control the behavior (method, headers, data, etc.)
  • URL — The target Uniform Resource Locator

If no options are provided, curl performs a GET request and outputs the response body to the terminal:

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

GET Requests

The simplest curl command performs an HTTP GET request. The response body is printed to stdout:

curl https://jsonplaceholder.typicode.com/posts/1

You can combine GET requests with query parameters directly in the URL:

curl "https://api.example.com/users?page=2&limit=10"

View Response Headers

Use the -i flag to include the HTTP response headers in the output:

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

Send Custom Headers

Use -H to add custom HTTP headers to the request:

curl -H "Accept: application/json" https://api.example.com/users

Multiple headers can be supplied by repeating -H:

curl -H "Accept: application/json" -H "Authorization: Bearer token123" https://api.example.com/users

POST Requests with JSON Data

To send a POST request with a JSON payload, combine -X POST with the -d (data) flag and the Content-Type: application/json header:

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

Sending Data from a File

When the JSON payload is large, read it from a file using the @ prefix:

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

URL-Encoded Form Data

For sending form data (application/x-www-form-urlencoded), omit the Content-Type header — curl adds it automatically:

curl -X POST -d "name=Alice&email=alice@example.com" https://api.example.com/users

PUT and PATCH Requests

The -X flag supports any HTTP method:

# PUT — full replacement
curl -X PUT \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice Updated"}' \
  https://api.example.com/users/1
 
# PATCH — partial update
curl -X PATCH \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice Partial"}' \
  https://api.example.com/users/1

DELETE Requests

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

Query Parameters

Query parameters can be appended directly to the URL. For complex queries, use the -G flag with -d to let curl build the query string:

# Manual query string
curl "https://api.example.com/search?q=curl&page=1&sort=desc"
 
# Using -G and -d (curl builds the query string)
curl -G \
  -d "q=curl" \
  -d "page=1" \
  -d "sort=desc" \
  https://api.example.com/search

The -G approach handles URL encoding automatically, which is useful when parameters contain special characters.


File Uploads

Use the -F (form) flag to upload files as multipart/form-data:

curl -X POST \
  -F "file=@/path/to/document.pdf" \
  -F "description=Annual Report" \
  https://api.example.com/upload

Multiple File Uploads

curl -X POST \
  -F "images=@photo1.jpg" \
  -F "images=@photo2.jpg" \
  -F "images=@photo3.jpg" \
  https://api.example.com/gallery

Custom Filename in Upload

You can override the filename sent to the server:

curl -F "file=@local-file.pdf;filename=report-2026.pdf" https://api.example.com/upload

Follow Redirects (-L)

Many endpoints redirect to a different URL (HTTP 3xx responses). By default, curl does not follow redirects — it prints the redirect response. Use -L (or --location) to follow redirects automatically:

curl -L https://bit.ly/some-link

Curl follows up to 50 redirects by default. Limit the number with --max-redirs:

curl -L --max-redirs 5 https://example.com/redirect-chain

Save Output (-o)

By default, curl prints the response body to stdout. To save it to a file, use -o (lowercase) with a filename:

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

Use -O (uppercase) to save using the remote filename:

curl -O https://example.com/files/document.pdf

This is equivalent to downloading a file and preserving its original name.


Verbose Mode (-v)

The -v (verbose) flag prints detailed information about the request and response, including:

  • Connection details (DNS resolution, TCP handshake, TLS negotiation)
  • Request headers sent
  • Response headers received
  • SSL certificate information
curl -v https://api.example.com/users

Silent Mode

Conversely, -s (silent) suppresses the progress meter and error messages. Combine with -S to show errors only:

# Completely silent
curl -s https://api.example.com/users
 
# Silent but show errors
curl -sS https://api.example.com/users

Authentication (-u)

Curl supports HTTP Basic authentication with the -u flag:

curl -u username:password https://api.example.com/protected

To avoid exposing credentials in the process list, use a prompt by omitting the password:

curl -u username https://api.example.com/protected
# curl will prompt for the password interactively

Bearer Token Authentication

For Bearer tokens (commonly used with JWTs), use the Authorization header:

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

OAuth 2.0 — Client Credentials

curl -X POST \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=abc&client_secret=xyz" \
  https://auth.example.com/token

Common Flags Reference

Flag Long Form Description Example
-X --request HTTP method -X POST
-d --data Request body data -d '{"key":"val"}'
-H --header Custom HTTP header -H "Content-Type: application/json"
-F --form Multipart form data -F "file=@photo.jpg"
-L --location Follow redirects -L https://bit.ly/abc
-o --output Write to file -o output.json
-O --remote-name Write using remote filename -O https://example.com/file.pdf
-v --verbose Detailed request/response info -v https://api.example.com
-s --silent Suppress progress/errors -s https://api.example.com
-S --show-error Show errors with -s -sS https://api.example.com
-u --user Basic auth credentials -u user:pass
-k --insecure Skip TLS verification -k https://self-signed.example.com
-i --include Include response headers -i https://api.example.com
-I --head Fetch headers only (HEAD) -I https://api.example.com
-c --cookie-jar Write cookies to file -c cookies.txt
-b --cookie Send cookies from file -b cookies.txt
--max-time Max seconds for transfer --max-time 30
--connect-timeout Max seconds for connection --connect-timeout 10
--retry Retry count on failure --retry 3
--retry-delay Seconds between retries --retry-delay 5
-A --user-agent User-Agent header -A "Mozilla/5.0"
-T --upload-file Upload file (PUT) -T file.txt https://example.com/
-z --time-cond Conditional download -z "2026-01-01"

SSL and Certificate Options

Skip TLS Verification (Testing Only)

For development environments with self-signed certificates:

curl -k https://self-signed.local/api

Specify Client Certificate

curl --cert client.pem --key client-key.pem https://api.example.com/secure

Specify CA Bundle

curl --cacert /path/to/ca-bundle.crt https://api.example.com

Cookie Handling

Save Cookies from a Response

curl -c cookies.txt https://example.com/login

Send Cookies with a Request

curl -b cookies.txt https://example.com/dashboard

Send a Specific Cookie

curl -b "sessionid=abc123; theme=dark" https://example.com/profile

Curl in Bash Scripts

Curl integrates seamlessly into shell scripts. Here are practical patterns:

Check HTTP Status Code

# Get only the HTTP status code
status=$(curl -s -o /dev/null -w "%{http_code}" https://api.example.com/health)
echo "Status: $status"
 
if [ "$status" -eq 200 ]; then
  echo "Service is healthy"
else
  echo "Service returned $status"
fi

Time a Request

# Print timing details
curl -s -w "\nTime: %{time_total}s\n" https://api.example.com/users

Available timing variables: time_namelookup, time_connect, time_appconnect, time_pretransfer, time_starttransfer, time_total.

API Health Check with Retries

#!/bin/bash
URL="https://api.example.com/health"
MAX_RETRIES=3
DELAY=2
 
for i in $(seq 1 $MAX_RETRIES); do
  response=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
  if [ "$response" -eq 200 ]; then
    echo "API is healthy"
    exit 0
  fi
  echo "Attempt $i failed with status $response. Retrying in ${DELAY}s..."
  sleep $DELAY
done
 
echo "API health check failed after $MAX_RETRIES attempts"
exit 1

Download Multiple Files

#!/bin/bash
URLS=(
  "https://example.com/files/doc1.pdf"
  "https://example.com/files/doc2.pdf"
  "https://example.com/files/doc3.pdf"
)
 
for url in "${URLS[@]}"; do
  curl -O "$url"
done

Troubleshooting Common Issues

Connection Refused

If the server is not running or the port is blocked:

curl: (7) Failed to connect to localhost port 3000: Connection refused

Check: Is the service running? Is the port correct? Firewall rules?

SSL Certificate Errors

curl: (60) SSL certificate problem: self-signed certificate

Fix: Use -k for testing, or add the CA certificate with --cacert.

Timeout

curl: (28) Connection timed out after 30001 milliseconds

Fix: Increase --connect-timeout or --max-time. Check network connectivity.

400 Bad Request

This usually indicates malformed request syntax. Check your headers, data format, and URL encoding. Use JSON Formatter to validate your payload.

401 Unauthorized

Authentication is missing or invalid. Verify your credentials and token. Use the JWT Encoder to examine your token.


Practical Examples

Example 1: Test a REST API Endpoint

# GET with auth and pretty output
curl -s \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Accept: application/json" \
  https://api.github.com/user | python3 -m json.tool

Example 2: Create a Resource with Validation

curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "title": "New Task",
    "description": "Learn curl",
    "priority": "high",
    "tags": ["tutorial", "cli"]
  }' \
  https://api.example.com/tasks | jq .

Example 3: Upload File with Metadata

curl -s -X POST \
  -F "file=@screenshot.png" \
  -F "title=Screenshot 2026" \
  -F "visibility=public" \
  https://api.example.com/uploads | jq .

Example 4: OAuth 2.0 Token Exchange

# Obtain access token
TOKEN=$(curl -s -X POST \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=abc123" \
  -d "redirect_uri=https://myapp.com/callback" \
  -d "client_id=myapp" \
  -d "client_secret=secret" \
  https://auth.example.com/token | jq -r '.access_token')
 
# Use the token
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/protected

Example 5: GraphQL Query

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"query": "{ users { id name email } }"}' \
  https://api.example.com/graphql

Curl vs Other HTTP Clients

Feature Curl HTTPie Postman Insomnia
Interface CLI CLI GUI GUI
Scriptable Yes Yes Limited Limited
Pre-installed Yes (Linux/macOS) No No No
CI/CD Friendly Yes Yes No No
Response Formatting Manual (pipe) Built-in Built-in Built-in
Session Management Manual Manual Built-in Built-in

For quick ad-hoc requests, curl is always available. For complex workflows with multiple environments and variables, GUI clients like Postman are useful, but curl remains the most portable and scriptable option.


Related LangStop Tools

Related Tools

Try these complementary developer tools: