Making Requests with curl & wget
When you run servers, you constantly need to ask one question: “Is this thing actually responding?” Instead of opening a browser, two small command-line tools answer that for you. curl (short for “Client URL”) sends HTTP requests and shows you exactly what comes back, and wget (“Web Get”) downloads files reliably. Both are essential for debugging APIs, checking health endpoints, and pulling files onto a server you only reach over SSH. This page shows you how to use both on Ubuntu, with real commands and real output.
Installing curl and wget
On Ubuntu 22.04 and 24.04 LTS, curl is usually pre-installed and wget often is too. If either is missing, install them with apt (Ubuntu’s package manager):
sudo apt update
sudo apt install -y curl wget
Check the versions to confirm they are ready:
curl --version
wget --version
Output:
curl 8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3
GNU Wget 1.21.4 built on linux-gnu.
curl vs wget — when to use which
Both fetch things over HTTP (HyperText Transfer Protocol, the language browsers and APIs speak), but they are built for different jobs.
| Task | Use curl | Use wget |
|---|---|---|
| Test an API endpoint | Yes — shows headers, status, body | No |
| Send POST/PUT/DELETE with data | Yes (-X, -d) | Limited |
| Inspect response headers | Yes (-i, -v) | Awkward |
| Download a single file | Works (-O) | Yes — simpler |
| Download a whole site / recursive | No | Yes (-r) |
| Resume a broken download | Yes (-C -) | Yes (-c) by default |
| Print result to screen (pipe-friendly) | Yes (default) | No (saves to disk) |
Short rule: use curl to debug and talk to APIs; use wget to download files.
Testing endpoints with curl
The most common DevOps task is checking that a service is alive. Many apps expose a “health endpoint” (a special URL like /health that returns a simple OK when the app is working). Let’s hit one.
A basic request
curl http://localhost:8080/health
Output:
{"status":"UP"}
By default curl prints only the response body. That is great for piping into other tools, but it hides the status code and headers.
Show the response status and headers with -i
The -i flag (include) prints the response headers along with the body. The first line tells you the HTTP status code, which is how you know if the request truly succeeded.
curl -i http://localhost:8080/health
Output:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 15
Date: Mon, 15 Jun 2026 10:14:02 GMT
{"status":"UP"}
200 OK means success. Other codes you will see often: 404 (not found), 401 (not authorized), 500 (server error), 502/503 (the proxy in front of your app could not reach it).
Tip: To get only the status code for scripts and health checks, use
curl -s -o /dev/null -w "%{http_code}\n" URL. The-ssilences the progress bar,-o /dev/nullthrows away the body, and-wprints just the number. This is perfect inside a monitoring script.
See everything with -v
When something is broken and you do not know why, -v (verbose) shows the full conversation: the DNS lookup, the TLS handshake (the encryption setup for HTTPS), the request you sent, and the response.
curl -v https://api.example.com/health
Output:
* Trying 93.184.216.34:443...
* Connected to api.example.com (93.184.216.34) port 443
* TLS connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
> GET /health HTTP/2
> Host: api.example.com
> User-Agent: curl/8.5.0
> Accept: */*
< HTTP/2 200
< content-type: application/json
{"status":"UP"}
Lines starting with > are what curl sent; lines starting with < are what the server replied. This is invaluable for spotting expired certificates, wrong hostnames, or missing headers.
Sending data: -X, -H, and -d
To test more than a GET request, you combine three flags:
-Xsets the HTTP method (GET, POST, PUT, DELETE).-Hadds a request header (extra metadata, like the content type or an auth token).-dsends a request body (the data you are posting).
Here is a real POST that creates a user and sends a bearer token (a string that proves you are allowed to make the call):
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOi..." \
-d '{"name":"Asha","role":"admin"}'
Output:
{"id":42,"name":"Asha","role":"admin","created":true}
Note: when you use -d, curl automatically switches to POST, so -X POST is optional there. Keep it for clarity.
Security gotcha: avoid putting secrets like tokens directly on the command line — they get saved in your shell history (
~/.bash_history) and are visible to other users inps. Read them from an environment variable instead:-H "Authorization: Bearer $API_TOKEN".
Downloading files with wget
wget shines when you just want a file saved to disk. It shows a progress bar and retries automatically if the connection drops.
wget https://nodejs.org/dist/v22.0.0/node-v22.0.0-linux-x64.tar.xz
Output:
Resolving nodejs.org... 104.20.22.46
Connecting to nodejs.org|104.20.22.46|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 24117248 (23M) [application/x-xz]
Saving to: 'node-v22.0.0-linux-x64.tar.xz'
node-v22.0.0-linux 100%[===================>] 23.00M 8.42MB/s in 2.7s
2026-06-15 10:20:11 (8.42 MB/s) - saved
Useful wget options:
| Option | What it does |
|---|---|
-O name | Save with a specific filename |
-P /path | Save into a directory |
-c | Continue (resume) a partial download |
-q | Quiet mode (no output, good for scripts) |
--limit-rate=1m | Cap bandwidth to 1 MB/s |
If a big download gets interrupted, just rerun it with -c and wget picks up where it stopped:
wget -c https://nodejs.org/dist/v22.0.0/node-v22.0.0-linux-x64.tar.xz
You can do the same with curl using curl -L -O -C - URL, where -L follows redirects, -O keeps the remote filename, and -C - resumes.
Best Practices
- Use
curl -ior-vwhen debugging, butcurl -s(silent) inside scripts so logs stay clean. - For automated health checks, return only the status code with
-o /dev/null -w "%{http_code}"and treat anything that is not200as a failure. - Never paste API tokens or passwords directly into a command — load them from environment variables to keep them out of shell history.
- Always add
-Lto follow redirects; many download URLs respond with a301/302to the real file. - Prefer
wget -c(orcurl -C -) for large downloads over flaky connections so you never restart from zero. - On HTTPS, do not disable certificate checks (
curl -k) except for quick local testing — it removes the protection that stops attackers from impersonating the server.