How to Use curl Command in Linux: The Essential Tool for Every Sysadmin

Robert Johnson

If you’ve ever needed to test an API, download a file from the command line, or debug a network issue at 3 AM, you’ve probably reached for curl. It’s one of those tools that seems simple at first, but once you understand what it can really do, it becomes indispensable.

I remember the first time I had to troubleshoot a failing webhook integration. The application logs were useless, and I needed to see exactly what was being sent over the wire. Five minutes with curl and I found the problem: a missing Content-Type header that the receiving API required. That one command saved hours of debugging.

In this guide, I’ll walk you through everything you need to know about the curl command – from basic downloads to advanced API testing. No fluff, just the examples you’ll actually use.

What is the curl Command in Linux?

curl (short for “Client URL”) is a command-line tool for transferring data using various network protocols. It supports HTTP, HTTPS, FTP, FTPS, SCP, SFTP, and about 20 other protocols. Think of it as a Swiss Army knife for network operations.

The beauty of curl is that it comes pre-installed on most modern Linux distributions, macOS, and even Windows 10/11. You don’t need to install anything – it’s already there, waiting for you to use it.

RackNerd Mobile Leaderboard Banner

Unlike tools that require a GUI, curl runs entirely in your terminal. This makes it perfect for automation, scripting, and troubleshooting on remote servers where you only have SSH access.

Basic curl Syntax and Common Options

The most basic curl command is dead simple:

curl https://example.com

This fetches the content from the URL and displays it in your terminal. But curl gets much more powerful when you start adding options. Here are the ones I use constantly:

  • -o filename – Save output to a specific file
  • -O – Save with the original filename from the URL
  • -L – Follow redirects (crucial for many websites)
  • -I – Fetch headers only, not the body
  • -v – Verbose mode, shows the entire request/response
  • -s – Silent mode, hides the progress bar
  • -X METHOD – Specify HTTP method (GET, POST, PUT, DELETE)
  • -H “Header: value” – Add custom headers
  • -d “data” – Send data in request body

The options can be combined in any order. You’ll see exactly how in the examples below.

Downloading Files with curl

One of the most common uses for curl is downloading files. Here’s how to do it properly.

Download and Save with Original Filename

curl -O https://example.com/large-file.tar.gz

The -O flag tells curl to save the file using its original name from the URL. This is perfect when you’re grabbing a specific release or package.

Download and Rename the File

curl -o myfile.tar.gz https://example.com/v2.1.3/release.tar.gz

Use lowercase -o when you want to specify your own filename. I use this all the time when downloading different versions of software and need to keep the filenames organized.

Download Multiple Files

curl -O https://example.com/file1.zip -O https://example.com/file2.zip

You can chain multiple -O flags to download several files in one command. Saves typing the same command over and over.

Resume a Partial Download

curl -C - -O https://example.com/huge-file.iso

The -C - option automatically continues a download that was interrupted. This has saved me countless times when downloading large ISOs over unreliable connections.

Pro Tip: Always use the -L flag when downloading from URLs that might redirect. Many download links use redirects, and without this flag, curl will just show you an HTML redirect page instead of the actual file. I learned this the hard way.

Using curl for API Testing

This is where curl really shines. If you work with APIs, curl is faster than firing up Postman and perfect for quick tests or automation.

Making a Simple GET Request

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

By default, curl makes GET requests. The response will be printed to your terminal. For JSON responses, you might want to pipe it through grep or use jq for formatting.

Adding Custom Headers

curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
     -H "Accept: application/json" \
     https://api.example.com/protected/resource

The -H flag adds headers to your request. You can use it multiple times to add as many headers as you need. I use this constantly for authentication tokens and content negotiation.

Making a POST Request with JSON Data

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

This is probably the most common API operation you’ll do with curl. The -X POST sets the HTTP method, -H sets the content type, and -d sends the data. According to Stack Overflow discussions, this is the standard approach used by thousands of developers.

Sending Form Data

curl -X POST https://example.com/login \
     -d "username=admin" \
     -d "password=secret123"

When you use -d without specifying a Content-Type, curl automatically sets it to application/x-www-form-urlencoded. This mimics how HTML forms submit data.

Uploading Files

curl -X POST https://api.example.com/upload \
     -H "Authorization: Bearer TOKEN" \
     -F "file=@/path/to/document.pdf" \
     -F "description=Important document"

The -F flag is for multipart form uploads. The @ symbol tells curl to read the file from your filesystem. I use this whenever I need to test file upload endpoints.

Debugging and Troubleshooting with curl

curl is my go-to tool when something’s broken and I need to see what’s actually happening on the network.

Viewing Full Request and Response Details

curl -v https://api.example.com/endpoint

Verbose mode shows you everything: the TLS handshake, request headers, response headers, and the response body. When an API integration is failing, this is always my first step.

Getting Just the Response Headers

curl -I https://example.com

The -I flag fetches only headers, not the body. Perfect for checking HTTP status codes, content types, or cache headers without downloading the entire response.

Testing Response Time

curl -w "Total time: %{time_total}s\n" -o /dev/null -s https://example.com

The -w flag lets you format the output with timing information. This command discards the response body (-o /dev/null), runs silently (-s), and shows just the total time. Great for quick performance checks.

Following Redirects

curl -L https://bit.ly/some-short-url

The -L flag tells curl to follow HTTP redirects. Without it, you’ll just see the redirect response instead of the final destination. I always include this when working with shortened URLs or APIs that redirect.

Advanced curl Techniques You’ll Actually Use

Testing Webhooks Locally

curl -X POST http://localhost:3000/webhook \
     -H "Content-Type: application/json" \
     -H "X-Webhook-Secret: test123" \
     -d '{"event": "user.created", "user_id": 42}'

When you’re developing webhook handlers, curl is perfect for sending test payloads. Much faster than triggering the real event in a production system.

Checking Which Ports Are Responding

curl -v telnet://localhost:3306

You can use curl with the telnet protocol to check if a port is open and responding. This is handy when you’re troubleshooting database connections or checking open ports on remote servers.

Limiting Transfer Speed

curl --limit-rate 100K -O https://example.com/large-file.iso

The --limit-rate option caps the download speed. Useful when you’re downloading on a production server and don’t want to saturate the network link.

Setting Custom Timeouts

curl --connect-timeout 10 --max-time 30 https://slow-api.example.com

The --connect-timeout limits how long curl waits to establish a connection, and --max-time sets the maximum time for the entire operation. I always use timeouts in scripts to prevent them from hanging indefinitely.

Ignoring SSL Certificate Errors

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

Use this cautiously. The -k flag bypasses SSL certificate verification. It’s useful for testing against development servers with self-signed certificates, but never use it in production scripts. It defeats the entire purpose of HTTPS.

curl vs wget: When to Use Which

People often ask me whether they should use curl or wget. Here’s my take after using both for years:

Use curl when:

  • You’re testing APIs or need to send custom HTTP methods
  • You need to add custom headers or authentication
  • You want to see detailed request/response information
  • You’re working with multiple protocols beyond HTTP/FTP

Use wget when:

  • You’re downloading entire websites recursively
  • You need robust automatic retry on network failures
  • You want simpler syntax for basic downloads

According to the curl vs wget comparison by curl’s creator, the tools were designed with different philosophies. curl is a library with a command-line tool, while wget is purely a command-line downloader.

Personally, I reach for curl 90% of the time because of its flexibility with APIs and protocols.

Common curl Errors and How to Fix Them

Here are the errors I see most often and how to solve them.

curl: (6) Could not resolve host

This means DNS resolution failed. Check your network connection and DNS settings. You can test DNS resolution separately with ping or dig.

curl: (7) Failed to connect to host

The host is unreachable or the service isn’t running on that port. Verify the URL is correct and check your network interface is up.

curl: (28) Operation timed out

The connection took too long. This could be a network issue, a slow server, or a firewall blocking the connection. Try increasing the timeout or check your network path with traceroute.

curl: (35) SSL connect error

Usually indicates SSL/TLS handshake problems. This can happen with outdated OpenSSL libraries or misconfigured servers. Try updating curl or use -v to see exactly where the handshake fails.

curl: (60) SSL certificate problem

The remote certificate couldn’t be verified. If it’s a legitimate issue with the server’s certificate, contact the server admin. If it’s a development server with a self-signed cert, you can use -k to bypass verification (not recommended for production).

Using curl in Bash Scripts

curl is incredibly powerful in automation scripts. Here’s a real-world example I use for monitoring:

#!/bin/bash

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

if [ "$RESPONSE" -eq 200 ]; then
    echo "Service is healthy"
    exit 0
else
    echo "Service returned HTTP $RESPONSE"
    exit 1
fi

This script checks an API health endpoint and exits with an appropriate code. I run it via cron to monitor services and get alerted if something goes down.

The -s flag silences progress output, -o /dev/null discards the response body, and -w "%{http_code}" outputs just the HTTP status code.

Real-World curl Examples from the Trenches

Let me share a few scenarios where curl has saved my bacon.

Testing Rate Limiting

for i in {1..100}; do
    curl -s -o /dev/null -w "Request $i: %{http_code}\n" \
        https://api.example.com/endpoint
    sleep 0.1
done

I used this to verify that our API’s rate limiting was working correctly. It sends 100 requests and shows the HTTP status for each one. Around request 60, I started seeing 429 (Too Many Requests) responses, confirming the rate limit kicked in.

Checking API Endpoint Availability

curl -I https://api.example.com/v2/users

Before deploying a new application that depends on a third-party API, I always check that the endpoint exists and returns the expected headers. The -I flag shows headers without downloading the full response.

Debugging Authentication Issues

curl -v -H "Authorization: Bearer TOKEN_HERE" \
    https://api.example.com/protected 2>&1 | grep -i auth

When authentication wasn’t working, I used verbose mode and grepped for “auth” to see exactly what headers were being sent and received. Turned out the API expected “Bearer” with a capital B, and I had “bearer” in lowercase.

Learning More About curl

curl has an incredible amount of functionality that I haven’t covered here. The official curl tutorial is comprehensive and maintained by the curl team. For API-specific testing techniques, the Baeldung guide to REST API testing with curl has excellent examples.

You can also access curl’s built-in manual anytime with man curl or curl --help. I still reference the man page regularly when I need to remember a specific flag.

Why curl Should Be in Your Toolbox

If you’re managing Linux systems or working with APIs, curl is non-negotiable. It’s fast, it’s everywhere, and it does exactly what you tell it to do. Whether you’re downloading files, testing endpoints, or debugging network issues, curl gives you visibility and control that GUI tools can’t match.

The best way to learn curl is to use it. Start with simple downloads, then move to API testing. Once you understand the basic options, you’ll find yourself reaching for it constantly. I’ve been using Linux professionally for over a decade, and curl is still one of the tools I use every single day.

Next time you need to interact with a web service from the command line, give curl a try. You might be surprised how much you can accomplish with a single command.