HTTPie Cheatsheet - HTTP Client & REST API Test Commands
HTTPie encodes intent in the syntax of the request item itself, and that is the reason to reach for it over curl. A colon after a keyword means HTTP header, == means URL query parameter, = writes a string into the JSON body, := writes a number or boolean, and @ uploads file contents. Once that mapping is muscle memory, a cURL line copied from DevTools becomes readable without consulting which of -H, -d or --data-urlencode takes unquoted data. The response side is the other half of the argument: bodies are pretty-printed and highlighted, so you rarely decide whether to pipe into jq. The authentication group covers Basic, Bearer and Digest plus named sessions via --session, which makes multi-step flows workable — log in once, then reuse the stored cookie. Reach for it during API development or for CI smoke requests; stay with curl when you need load generation or already have frozen cURL scripts in production.
Typical Use Case
For back-end and front-end developers who call APIs by hand from a terminal, and for testers writing API smoke checks. curl requires memorising a pile of -H, -d and --data-binary flags, while HTTPIE reads close to natural language: name=value, := for numeric types, == for query strings, @ to read a file, field@file to upload. This sheet covers methods and data types, built-in authentication (Basic / Bearer / Digest), named sessions for reusing a login, downloads with resume, streaming output, proxies, and the three flags that matter when debugging: -v, -h and --check-status.
Basic Requests 7
http GET https://api.example.com/usershttp https://api.example.com/usershttp POST https://api.example.com/users name=John age:=30http PUT https://api.example.com/users/1 name=Janehttp DELETE https://api.example.com/users/1http PATCH https://api.example.com/users/1 email=new@mail.comhttp HEAD https://api.example.com/usersHeaders & Params 7
http https://api.example.com X-Token:abc123http https://api.example.com X-Token:abc123 Cookie:session=xyzhttp https://api.example.com page==2 size==10http -j https://api.example.comhttp -f https://api.example.com field=valuehttp -v https://api.example.comhttp -p Hh https://api.example.comAuth & Session 6
http -a user:pass https://api.example.comhttp -A bearer -a TOKEN https://api.example.comhttp -A digest -a user:pass https://api.example.comhttp --session=logged-in https://api.example.comhttp --session=logged-in https://api.example.com/profilehttp --session-read-only=logged-in https://api.example.comFiles & Downloads 6
http -d https://example.com/file.zip -o file.ziphttp --download https://example.com/file.ziphttp POST https://api.example.com/upload file@./photo.jpghttp POST https://api.example.com/data @data.jsonhttp -d https://example.com/file.zip --continuehttp POST https://api.example.com/upload file@./photo.jpg field=valueOutput & Formatting 6
http https://api.example.com | jq ".data"http -b https://api.example.comhttp -h https://api.example.comhttp --pretty=none https://api.example.comhttp -o response.json https://api.example.comhttp --stream https://api.example.com/streamTips & Tricks 5
http --proxy http:http://127.0.0.1:7890 https://api.example.comhttp --follow https://example.com/redirecthttp --timeout=30 https://api.example.comhttp --verify=no https://self-signed.example.comhttp --check-status https://api.example.com/usersParameter matrix
| Parameter | Effect | Example |
|---|---|---|
field=value / field:=value | Plain fields are sent as strings; := forces a numeric type | http POST https://api.example.com/users name=John age:=30 |
param==value | == places the field in the URL query string instead of the body | http https://api.example.com page==2 size==10 |
-f / -j | -f submits form-urlencoded; -j forces Content-Type: application/json | http -f https://api.example.com field=value |
file@./photo.jpg / @data.json | A leading @ reads a file; field@file uploads it | http POST https://api.example.com/upload file@./photo.jpg |
-a / -A | -a user:pass is Basic auth; -A bearer -a TOKEN is Bearer token auth | http -A bearer -a TOKEN https://api.example.com |
--session=name | Create and reuse a named session, carrying cookies and headers automatically | http --session=logged-in https://api.example.com/profile |
--session-read-only=name | Use a session read-only, sending its credentials without persisting changes | http --session-read-only=logged-in https://api.example.com |
-v / -p Hh / -h / -b | Output control: full exchange / request headers / response headers only / body only | http -v https://api.example.com |
-d / --download / --continue | Download mode; combined with --continue for resuming an interrupted download | http -d https://example.com/file.zip --continue |
--check-status / --timeout=30 / --verify=no | Exit non-zero on 4xx/5xx for CI; bound the request time; skip self-signed verification | http --check-status https://api.example.com/users |
Common pitfalls
SymptomA numeric field arrives at the server as a string, or the JSON contains stringified numbers.
CauseEvery field assigned with = is a string by default; a type must be declared explicitly.
FixUse the := form for numbers, booleans and nulls: http POST https://api.example.com/users name=John age:=30.
SymptomParameters land in the request body and the server cannot read them from the query string.
CauseA single = was used; = writes the body while == writes the URL query string.
FixSwitch to ==: http https://api.example.com page==2 size==10.
SymptomRequests to a self-signed local endpoint fail TLS verification, while curl works with -k.
CauseHTTPIE validates the certificate chain and hostname strictly and will not silently downgrade the way curl -k does.
FixFor local self-signed endpoints only, add --verify=no (http --verify=no https://self-signed.example.com); never leave it on in a production script.
SymptomThe CI pipeline stays green even though the endpoint returned 500.
CauseBy default HTTPIE prints the body and exits successfully; the exit code does not reflect 4xx/5xx.
FixAdd --check-status: http --check-status https://api.example.com/users, so a bad status yields a non-zero exit code.
SymptomA second request with the session returns 401 even though the first login succeeded.
CauseA typo in the session name means the saved cookies and headers are not found, so the request goes out anonymously.
FixKeep the name identical: log in with http --session=logged-in https://api.example.com, then reuse the same --session name; use --session-read-only when you only want to read it.
SymptomAn interrupted large-file download has to start over from byte zero.
CauseResume was not requested, so the whole file is rewritten every time.
FixAdd --continue: http -d https://example.com/file.zip --continue (or use --download for a progress bar).
Troubleshooting
1Inspect the full exchange when the endpoint fails
http -v https://api.example.com-v prints both request and response, immediately revealing whether headers were sent and what status came back.
2Inspect request headers only
http -p Hh https://api.example.com-p Hh prints request headers (H) and response headers (h) only — the fastest way to check Authorization or Content-Type.
3Headers only, for health checks and redirect chains
http -h https://api.example.com-h prints response headers only; combine with --follow to follow 301/302 redirects.
4Save the body to a file, then process it
http -o response.json https://api.example.comOr pipe directly: http https://api.example.com | jq ".data"; use -b when you want the raw body without formatting.
5Debugging behind proxies and with self-signed certificates
http --verify=no --proxy http:http://127.0.0.1:7890 https://api.example.comKeep --verify=no for local debugging only; for real network failures check proxy settings and the request timeout (--timeout=30).
Tips
- Install: pip install httpie or brew install httpie.
- := for JSON number/bool, == for query params, = for JSON string field.
- HTTPie pretty-prints and highlights JSON, easier than curl | jq.
- --session saves cookies and auth for multi-step API debugging.
- Item syntax: Header:Value, param==value, field=value, field:=value, file@/path.
- Use -o to save the body; pair with --download for large files with progress.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 19, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us