---
title: "curl Flags Cheatsheet"
slug: "curl-flags"
category: "cheatsheets"
tags: ["cheatsheets", "curl", "http", "cli", "reference", "networking"]
status: "stable"
last_updated: 2026-05-14
summary: "curl flags for request method, headers, body, auth, output, and TLS; plus common HTTP test patterns used in API development and debugging."
related:
  [
    "[[cheatsheets/http-status-codes]]",
    "[[cheatsheets/jq-syntax]]",
    "[[cheatsheets/bash-one-liners]]",
    "[[cheatsheets/gh-cli]]",
    "[[backend/fastapi]]",
    "[[cheatsheets/index|Cheatsheets]]",
  ]
---

## Overview

`curl` is the universal HTTP client for testing, scripting, and debugging. This card covers the flags and patterns you reach for when building or debugging APIs. For parsing JSON responses, pipe to [[cheatsheets/jq-syntax]].

## Method and headers

Set the method and headers explicitly; do not rely on curl's defaults when the method matters.

| Flag | What it does |
| --- | --- |
| `-X POST` | Set the HTTP method. |
| `-H "Content-Type: application/json"` | Add a request header. |
| `-H "Authorization: Bearer $TOKEN"` | Auth header from a shell variable. |
| `-H "Accept: application/json"` | Request JSON response. |
| `-I` | Fetch headers only (HEAD request). |
| `-i` | Include response headers in output. |
| `-v` | Verbose: show request and response headers, TLS handshake. |
| `--trace-ascii -` | Full wire trace to stdout. |

Combine `-i` with `jq` to see both headers and a pretty-printed body in one pass:
```bash
curl -i https://api.example.com/users | head -20
```

## Request body

| Flag | What it does |
| --- | --- |
| `-d '{"key":"value"}'` | Send a request body (implies POST if `-X` not set). |
| `-d @payload.json` | Read body from a file. |
| `--data-raw '{"key":"value"}'` | Send body literally; `@` is not treated as a file reference. |
| `-F "file=@photo.jpg"` | Multipart form upload. |
| `-F "file=@photo.jpg;type=image/jpeg"` | Multipart with explicit MIME type. |
| `--data-urlencode "name=hello world"` | URL-encode a form field. |
| `-G -d "q=test"` | Convert `-d` data to a query string (GET request). |

Always pair `-d '{"...}'` with `-H "Content-Type: application/json"`. Without it, curl sends `application/x-www-form-urlencoded`.

## Output and download

| Flag | What it does |
| --- | --- |
| `-o file.json` | Write response body to a file. |
| `-O` | Write response to a file named by the URL. |
| `-s` | Silent; suppress progress meter. |
| `-S` | Show errors even with `-s`. |
| `--fail` | Exit with status 22 on HTTP error responses (4xx, 5xx). |
| `-w "%{http_code}"` | Print a custom write-out variable after the response. |
| `--limit-rate 1M` | Throttle download speed. |
| `-C -` | Resume an interrupted download. |
| `--compressed` | Request gzip/deflate compression; decompress automatically. |

Combine `--fail --silent --show-error` (or `--fail -sS`) for scripts where you want to abort on error without progress noise.

## Redirects, TLS, and proxies

| Flag | What it does |
| --- | --- |
| `-L` | Follow redirects. |
| `--max-redirs 5` | Limit redirect chain length. |
| `-k` | Skip TLS certificate verification. Development only. |
| `--cacert ca.pem` | Use a custom CA bundle. |
| `--cert client.pem --key client.key` | Mutual TLS: send a client certificate. |
| `--resolve example.com:443:127.0.0.1` | Override DNS for one host; useful for local HTTPS testing. |
| `-x http://proxy:8080` | Route through an HTTP proxy. |
| `--noproxy localhost,127.0.0.1` | Bypass proxy for listed hosts. |

Use `--resolve` instead of editing `/etc/hosts` when testing a new server before DNS propagates.

## Auth flags

| Flag | What it does |
| --- | --- |
| `-u user:pass` | HTTP Basic auth. |
| `-u user` | Prompt for password interactively. |
| `--oauth2-bearer $TOKEN` | OAuth 2.0 Bearer token in header. |
| `--negotiate -u :` | Kerberos/NTLM negotiation. |
| `-b "session=abc123"` | Send a cookie string. |
| `-b cookies.txt` | Send cookies from a file (Netscape format). |
| `-c cookies.txt` | Save response cookies to a file. |

For Bearer auth, `-H "Authorization: Bearer $TOKEN"` and `--oauth2-bearer $TOKEN` are equivalent; the header form works everywhere.

## Common HTTP test patterns

Ready-to-paste patterns for API development.

```bash
# GET with JSON response, pretty-printed
curl -sS https://api.example.com/users | jq '.'

# POST JSON body
curl -sS -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name": "alice"}' | jq '.'

# PUT with auth
curl -sS -X PUT https://api.example.com/users/1 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "alice updated"}' | jq '.'

# Check HTTP status code only
curl -o /dev/null -sS -w "%{http_code}\n" https://api.example.com/health

# Download a file, resume if interrupted
curl -L -C - -o large-file.zip https://example.com/large-file.zip

# Test HTTPS with a local server, bypassing cert check
curl -k https://localhost:8443/api/status
```

## Common gotchas

- `-d` without `-X` defaults to POST but does not set `Content-Type`. Always set the header explicitly.
- `-k` disables certificate verification completely, not just hostname checking. Never use in production scripts; use `--cacert` for self-signed CAs.
- `-L` follows redirects but drops headers like `Authorization` by default on cross-origin redirects. Use `--location-trusted` to keep headers, but only when the redirect destination is trusted.
- `-w "%{http_code}"` prints after the body on the same line without a newline. Use `-w "\n%{http_code}\n"` or redirect body to `-o /dev/null` for clean output.
- `-d '@file'` reads from `file`; `-d @file` (no quotes) works the same way in bash but looks like a bare `@` in some shells. Quote consistently.
- `--fail` exits non-zero on 4xx/5xx but still writes the response body to stdout. Redirect to `-o /dev/null` if you only want the exit code.

## Related

- [[cheatsheets/http-status-codes]]
- [[cheatsheets/jq-syntax]]
- [[cheatsheets/bash-one-liners]]
- [[cheatsheets/gh-cli]]
- [[backend/fastapi]]
- [[cheatsheets/index|Cheatsheets]]
