1 · What Is cURL?

curl is a versatile command‑line tool (and libcurl library) for transferring data with URLs across 24+ protocols—including HTTP(S), FTP(S), SFTP, SCP, SMTP, POP3, IMAP, MQTT, GOPHER, and more. It is open‑source, cross‑platform, script‑friendly, and trusted in production environments from embedded devices to cloud servers. The project began in 1997 and continues to publish feature‑rich releases several times a year.

Note: The latest stable version is 8.13.0 (released 2 April 2025), introducing --upload-flags, extended --url file support, and several TLS improvements.

2 · Basic Syntax

$ curl [options] <URL>

The minimal invocation fetches the resource at <URL> and streams the response body to stdout. Common modifiers:

Tip: Combine flags concisely: -LO will follow redirects and write with the remote filename.

3 · HTTP Request Methods

Use -X or its long form --request to specify the verb:

# GET (default)
curl https://api.example.com/users

# POST JSON (using the modern --json helper)
curl --json '{"name":"Ada"}' https://api.example.com/users

# PUT a file
curl -T avatar.png -X PUT https://api.example.com/users/42/avatar

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

--json implicitly sets -H "Content-Type: application/json" and --data; it was added in version 7.82.0.

4 · Sending Data ( Forms, Raw, Files )

4.1 · URL‑Encoded Forms

curl --data "user=ada&token=123" https://example.com/login

4.2 · Multipart Forms (file upload)

curl -F "file=@report.pdf" -F "comment=FYI" https://example.com/upload

4.3 · Raw Bodies

# Plain text
curl --data-binary @message.txt https://hooks.example.com/ingest

# JSON (short form shown earlier)
curl -H "Content-Type: application/json" \
     --data '{"x":1,"y":2}' https://api.example.com/points

Note: Use --data-raw to send data exactly as given, without extra URL‑encoding. The switch was introduced in 8.0.0 to supersede --data quirks.

5 · Custom Headers & Cookies

5.1 · Add or Override Headers

curl -H "Accept: application/xml" \
     -H "X-Token: $TOKEN" \
     https://api.example.com/feed

5.2 · Cookie Jar

# Store cookies after first request
curl -c cookies.txt https://shop.example.com

# Reuse cookies later
curl -b cookies.txt https://shop.example.com/cart

6 · Authentication Techniques

7 · TLS / SSL Controls

cURL builds can use OpenSSL, WolfSSL, GnuTLS, Schannel, or  Rustls. Recent releases added first‑class TLS 1.3 early data support via --tls-earlydata (8.11.0) and extended cipher suite selection with --ciphers (8.13.0).

# Insecure (skip CA validation) — for testing only!
curl -k https://self‑signed.badssl.com/

# Specify CA bundle
curl --cacert /etc/ssl/certs/my-ca.pem https://secure.example.com

8 · Downloading and Resuming

# Mirror an entire site structure
curl --remote-name --remote-time --output-dir ./site \
     --create-dirs --continue-at - --parallel \
     --url https://example.com/{index.html,assets/*.css}

Tip: Combine --continue-at - with --parallel (added in 7.66) for fast, resumable batch downloads.

9 · Rate‑Limiting & Timeouts

# Cancel if connection > 5 s or transfer > 2 min
curl --connect-timeout 5 --max-time 120 https://large.example.com

# Cap download to 1 MiB/s
curl --limit-rate 1M -O https://example.com/huge.iso

10 · Proxy Support

# HTTP proxy
curl -x http://proxy.local:8080 https://example.org

# SOCKS5 with DNS tunnelling
curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org

11 · Debugging Transfers

# Human‑readable progress and headers
curl -v https://api.example.com

# Full byte‑level trace
curl --trace-ascii debug.log https://api.example.com/data

For scripts, use --write-out with  variables such as %{http_code} and  %{size_download} to capture metrics.

12 · Multiple URLs & Parallelism

# Parallel download via command file
printf '%s\n' "https://a.com" "https://b.com" > list.txt
curl --parallel --url file://list.txt

Version 8.13 extends --url so the parameter can be a file that lists URLs—no -K/@ indirection needed.

13 · Scripting Patterns (Bash)

#!/usr/bin/env bash
set -euo pipefail

API=https://api.example.com
DATA=$(curl -s "$API/token")

curl --fail --retry 3 --retry-all-errors \
     -H "Authorization: Bearer $DATA" \
     -o result.json "$API/report"

Note: In bash/zsh you may enable curl completion by copying  scripts/zsh.pl from the source tree.

14 · Quick Tour of libcurl

#include <curl/curl.h>

int main(void){
    CURL *easy = curl_easy_init();
    if(!easy) return 1;

    curl_easy_setopt(easy, CURLOPT_URL, "https://example.com");
    curl_easy_setopt(easy, CURLOPT_FOLLOWLOCATION, 1L);

    CURLcode rc = curl_easy_perform(easy);
    if(rc != CURLE_OK) fprintf(stderr, "%s\n", curl_easy_strerror(rc));

    curl_easy_cleanup(easy);
}

Bindings exist for C++, Python (pycurl),  PHP (curl extension), Go (cgo),  Rust (curl-rust), Swift  (CCurl), and many other languages.

15 · Best Practices & Security Tips

16 · Troubleshooting Checklist

17 · Further Reading & Docs