HTTPie (pronounced aitch-tee-tee-pie) is a command-line HTTP client built to make interacting with web services and APIs as human-friendly as possible. You type requests in a simple, natural syntax that closely mirrors the actual HTTP message sent over the wire, and HTTPie gives you back formatted, colorized output. It is designed for testing, debugging, and generally talking to HTTP servers and JSON APIs from your terminal.
This guide covers everything you can do with the http and https commands: installation, the request-item syntax that lets you build any request, sessions, authentication, downloads, output control, and the httpie management interface. Every command, flag, and behavior described here is taken directly from HTTPie's source code (version 3.2.4).
Note
HTTPie installs two request commands:
http(default schemehttp://) andhttps(default schemehttps://). They are identical apart from the default scheme. A third command,httpie, is a management interface for plugins and configuration — it does not send requests. See The httpie management command.
Table of contents
- Quick start
- Installation
- The request syntax
- Request items: building any request
- Sending JSON
- Nested JSON
- Sending forms and uploading files
- HTTP headers
- Query string parameters
- Raw request body
- Authentication
- Cookies and sessions
- Controlling the output
- Downloading files
- Redirects, proxies, and networking
- HTTPS, SSL, and certificates
- Offline mode and scripting
- Configuration
- The httpie management command
- How HTTPie works under the hood
- Troubleshooting
- FAQ
- Complete option reference
Quick start
After installing HTTPie, make your first request:
https httpie.io/hello
That sends a GET request to https://httpie.io/hello and prints the colorized response headers and body.
The general shape of every command is:
http [flags] [METHOD] URL [ITEM [ITEM]]
Only the URL is required. Here is a request that sends a JSON body with a custom header, using a PUT method:
http PUT pie.dev/put X-API-Token:123 name=John
PUT /put HTTP/1.1
Accept: application/json, */*;q=0.5
Content-Type: application/json
Host: pie.dev
X-API-Token: 123
{
"name": "John"
}
Three things just happened automatically:
- The method was sent as
PUTbecause you named it. name=Johnbecame a JSON field, so HTTPie setContent-Type: application/json.X-API-Token:123became a request header.
That is the core idea: the separator between a key and a value (:, =, ==, :=, @, …) decides what kind of request part it becomes. The rest of this guide is mostly about those separators and the flags that shape the request and the output.
Tip
Add
-v(--verbose) to any command to see the full request and response — the single most useful flag for learning and debugging:http -v pie.dev/get
Installation
HTTPie is a Python application and is packaged for every major platform. Pick the method that matches your operating system. All commands below are taken from HTTPie's official packaging database.
Universal (any OS with Python)
Requires Python 3.7 or newer (check with python --version).
Install
python -m pip install --upgrade pip wheel
python -m pip install httpie
Upgrade
python -m pip install --upgrade pip wheel
python -m pip install --upgrade httpie
macOS
Homebrew
brew update
brew install httpie
MacPorts
port selfupdate
port install httpie
Windows
Chocolatey
choco install httpie
Linux
Debian / Ubuntu
curl -SsL https://packages.httpie.io/deb/KEY.gpg | sudo gpg --dearmor -o /usr/share/keyrings/httpie.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/httpie.gpg] https://packages.httpie.io/deb ./" | sudo tee /etc/apt/sources.list.d/httpie.list > /dev/null
sudo apt update
sudo apt install httpie
Also works for Debian-derived distributions (Linux Mint, Pop!_OS, elementary OS, Kubuntu, etc.).
Fedora
dnf install httpie
CentOS / RHEL
yum install epel-release
yum install httpie
Arch Linux
pacman -Syu httpie
Snap
snap install httpie
Single binary
Standalone executables — no Python installation needed:
https --download packages.httpie.io/binaries/linux/http-latest -o http
ln -ls ./http ./https
chmod +x ./http ./https
FreeBSD
pkg install www/py-httpie
Installing the development version
To try the latest unreleased code from the master branch:
python -m pip install --upgrade https://github.com/httpie/cli/archive/master.tar.gz
Verify any installation with:
http --version
3.2.4
Note
Development builds report a version with a
.dev0suffix (e.g.3.3.0.dev0).
The request syntax
Every HTTPie invocation follows the same grammar:
http [flags] [METHOD] URL [ITEM [ITEM ...]]
| Part | Required? | Description |
|---|---|---|
flags |
No | Options like -v, --form, --download. They come before or after the URL. |
METHOD |
No | GET, POST, PUT, DELETE, … Defaults are automatic (see below). |
URL |
Yes | The only required argument. Scheme defaults to http:// (or https:// with the https command). |
ITEM |
No | Zero or more request items — headers, data, params, files. |
The HTTP method
The method name comes right before the URL:
http DELETE pie.dev/delete
In addition to the standard methods (GET, POST, HEAD, PUT, PATCH, DELETE), any custom method name is allowed:
http AHOY pie.dev/post
There are no restrictions on which methods may carry a body — you can send an empty POST or a GET with a body.
Optional GET and POST
When you omit the method, HTTPie chooses one for you:
GETwhen the request has no body.POSTwhen the request has data items, piped input, or--raw.
http pie.dev/get # → GET (no data)
http pie.dev/post hello=world # → POST (has data)
The request URL
The URL is the only thing HTTPie strictly needs. Several shortcuts make it faster to type:
| You type | HTTPie sends |
|---|---|
http example.org |
http://example.org |
https example.org |
https://example.org |
http ://example.org |
http://example.org (paste-friendly: keep the ://, add a space) |
http :3000/bar |
http://localhost:3000/bar |
http :/foo |
http://localhost/foo |
http : |
http://localhost/ |
Tip
The
:portand:/pathshorthands are perfect for local development —http :8000/api/healthhitshttp://localhost:8000/api/health.
You can change the default scheme with --default-scheme:
http --default-scheme=https example.org # → https://example.org
Request items: building any request
Request items are the heart of HTTPie. Each item is a key/value pair, and the separator you use determines what part of the request it becomes. This is what lets you build virtually any HTTP request without quoting headaches or escaping &.
http PUT pie.dev/put \
X-Date:today \ # Header
token==secret \ # Query parameter
name=John \ # Data field (JSON by default)
age:=29 # Raw JSON field (a number, not a string)
The full separator table
| Separator | Item type | Example | Result |
|---|---|---|---|
: |
HTTP header | X-API-Token:123 |
Header X-API-Token: 123 |
== |
URL query parameter | search==httpie |
?search=httpie (auto URL-encoded) |
= |
Data field | name=John |
JSON string field (or form field with --form) |
:= |
Raw JSON field | age:=29, ok:=true, tags:='["a","b"]' |
Non-string JSON value |
@ |
File upload field | cv@~/files/cv.pdf |
Multipart file (with --form/--multipart) |
=@ |
Data field from file | essay=@notes.txt |
Field value read from a file |
:=@ |
Raw JSON from file | config:=@./config.json |
JSON value parsed from a file |
==@ |
Query param from file | token==@token.txt |
Param value read from a file |
:@ |
Header from file | X-Data:@payload.txt |
Header value read from a file |
; |
Empty header | Header; |
Sends Header: with an empty value |
Important
The
:=and:=@(raw JSON) separators only make sense for JSON requests. With--form/--multipart, simple scalar values (string, number, float) are still accepted, but complex JSON types (arrays, objects) raise an error:Cannot use complex JSON value types with --form/--multipart.
File-based values
Adding @ to a separator reads the value from a file instead of the command line. Trailing newlines are stripped:
http POST pie.dev/post \
X-Data:@files/text.txt \ # Header value from a file
token==@files/text.txt \ # Query param value from a file
name=@files/text.txt \ # Data field value from a file
bookmarks:=@files/data.json # JSON object embedded from a file
Escaping separators
If a separator character must appear literally in a key, escape it with a backslash:
http pie.dev/post field-name-with\:colon=value
For example, foo\==bar becomes the data field foo= with value bar (not a URL parameter).
If a field name or header starts with a dash, place it after the -- token so HTTPie doesn't mistake it for a flag:
http pie.dev/post -- -name-starting-with-dash=foo -Unusual-Header:bar
Sending JSON
JSON is the default content type. Any = and := data items are serialized into a JSON object, and HTTPie sets these headers automatically (both can be overridden):
| Header | Value |
|---|---|
Content-Type |
application/json |
Accept |
application/json, */*;q=0.5 |
http PUT pie.dev/put name=John email=[email removed]
PUT /put HTTP/1.1
Accept: application/json, */*;q=0.5
Content-Type: application/json
Host: pie.dev
{
"email": "[email removed]",
"name": "John"
}
String vs. non-string fields
Use = for strings and := for any other JSON type (numbers, booleans, arrays, objects):
http PUT pie.dev/put \
name=John \ # String
age:=29 \ # Number
married:=false \ # Boolean
hobbies:='["http", "pies"]' \ # Array
favorite:='{"tool": "HTTPie"}' \ # Object
bookmarks:=@files/data.json \ # Embed a JSON file
description=@files/text.txt # Embed a text file as a string
Tip
Use
--json(-j) to force JSON mode and theAccept: application/jsonheader even when you aren't sending data. HTTPie will also try to detect and prettify JSON responses even when the server returns the wrongContent-Type.
Explicit JSON
http --json pie.dev/get
This sets Accept to application/json, */*;q=0.5 regardless of whether you send any data.
Nested JSON
You can build deeply nested JSON objects and arrays directly from the command line using a path syntax inside the field name. You still use = and :=, but the key becomes a path:
http pie.dev/post \
platform[name]=HTTPie \
platform[about][mission]='Make APIs simple and intuitive' \
platform[about][stars]:=54000 \
platform[apps][]=Terminal \
platform[apps][]=Desktop \
platform[apps][]=Web
{
"platform": {
"name": "HTTPie",
"about": {
"mission": "Make APIs simple and intuitive",
"stars": 54000
},
"apps": ["Terminal", "Desktop", "Web"]
}
}
The rules:
key[child]=valuecreates a nested object.key[]=valueappends to an array.key[2]=valuesets an explicit array index (missing indexes becomenull).[]:=1(no leading key) builds a top-level array.
Type safety and errors
Each path has a fixed type once first used. Mixing object-access and array-access on the same path raises a clear, pointed error:
HTTPie Type Error: Can't perform 'key' based access on 'array' which has a type of 'array' but this operation requires a type of 'object'.
array[key]
^^^^^
Syntax mistakes are similarly guided:
HTTPie Syntax Error: Expecting ']'
foo[baz][quux
^
Note
Brackets, backslashes, and numeric indices can be escaped with
\when you need them literally — e.g.'foo\[bar\]:=1'produces the key"foo[bar]", and'object[\1]=x'produces the string key"1"instead of array index1.
Sending forms and uploading files
Add --form (-f) to serialize data items as a URL-encoded form instead of JSON. The Content-Type becomes application/x-www-form-urlencoded; charset=utf-8.
http --form POST pie.dev/post name='John Smith'
POST /post HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
name=John+Smith
File uploads
Use the @ separator to upload a file. The presence of any file field automatically upgrades a --form request to multipart/form-data:
http -f POST pie.dev/post name='John Smith' cv@~/files/data.xml
The content type of each uploaded file is inferred from its name; override it inline with ;type=:
http -f POST pie.dev/post cv@'~/files/data.bin;type=application/pdf'
Forcing multipart and custom boundaries
To send a multipart/form-data request even without files, use --multipart. To set a fixed boundary string, use --boundary:
http --multipart --boundary=xoxo --offline example.org hello=world
Note
File uploads are always streamed, so HTTPie can upload very large files without exhausting memory.
HTTP headers
Set any header with the Header:Value notation:
http pie.dev/headers User-Agent:Bacon/1.0 X-Foo:Bar Referer:https://httpie.org/
Default headers
HTTPie sets these by default, all overridable:
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: HTTPie/<version>
Host: <taken-from-URL>
Unsetting and emptying headers
| Goal | Syntax | Example |
|---|---|---|
| Remove a header entirely | Header: |
http pie.dev/headers Accept: User-Agent: |
| Send a header with an empty value | Header; |
http pie.dev/headers 'Header;' |
| Read a header value from a file | Header:@file |
http pie.dev/headers X-Data:@files/text.txt |
Warning
Some internal headers such as
Content-Lengthcannot be unset when HTTPie adds them automatically.
Repeated headers
Pass the same header name twice to send it as two separate header lines, or use a comma-separated value to send it as one:
http --offline example.org Cookie:one Cookie:two # Two Cookie lines
http --offline example.org Numbers:one,two # One line: Numbers: one,two
Query string parameters
The param==value syntax appends URL parameters without you having to escape & for the shell. Special characters in the name and value are automatically URL-encoded:
http https://api.github.com/search/repositories q==httpie per_page==1
GET /search/repositories?q=httpie&per_page=1 HTTP/1.1
You can also read a parameter value from a file with param==@file:
http pie.dev/get text==@files/text.txt
Raw request body
When the structured request-item syntax isn't what you want, you can pass an arbitrary raw body. There are three ways to do it, and they cannot be combined with key=value data items.
1. Pipe via stdin
http PUT pie.dev/put X-API-Token:123 < files/data.json
echo -n '{"name": "John"}' | http PATCH pie.dev/patch
http pie.dev/post <<<'{"name": "John"}'
grep '401 Unauthorized' /var/log/httpd/error_log | http POST pie.dev/post
2. The --raw option
Handy when piping is awkward (e.g. when generating documentation examples):
http --raw '{"name": "John"}' pie.dev/post
http --raw 'Hello, world!' pie.dev/post
3. A filename with @
Reads the file as the body and sets Content-Type from the file extension:
http PUT pie.dev/put @files/data.xml
Tip
In scripts, always pass
--ignore-stdin. Otherwise, whenstdinisn't a terminal (cron jobs, CI), HTTPie waits for piped body data and appears to hang. See Offline mode and scripting.
Chunked and compressed bodies
http --chunked PUT pie.dev/put hello=world # Transfer-Encoding: chunked
http --compress pie.dev/post @files/data.xml # Content-Encoding: deflate
http -xx PUT pie.dev/put hello=world # Force compression even if not smaller
By default, --compress (-x) is skipped if compression wouldn't reduce the size; passing it twice forces it.
Authentication
Two flags control authentication:
| Flag | Purpose |
|---|---|
--auth, -a |
The credentials — a username:password pair or a token. |
--auth-type, -A |
The mechanism: basic (default), digest, bearer, or any installed plugin. |
Basic, digest, and bearer
http -a username:password pie.dev/basic-auth/username/password # Basic (default)
http -A digest -a username:password pie.dev/digest-auth/... # Digest
https -A bearer -a token pie.dev/bearer # Bearer token
Password prompt and empty passwords
If you omit the password, HTTPie securely prompts for it:
http -a username pie.dev/basic-auth/username/password
http: password for [email removed]:
To send an empty password without a prompt, keep the trailing colon: -a username:.
Caution
When combined with
--session, prompted passwords are stored in the session file in plain text.
.netrc support
Credentials in your ~/.netrc are honored automatically. Disable this with --ignore-netrc:
http --ignore-netrc pie.dev/basic-auth/httpie/test
Auth plugins
More mechanisms install as plugins (AWS, OAuth, JWT, NTLM, HMAC, …). Search PyPI for httpie-, then install with the plugin manager:
httpie cli plugins install httpie-jwt-auth
Cookies and sessions
Cookies
HTTPie has no special cookie syntax — cookies are just headers:
http pie.dev/cookies Cookie:sessionid=foo
http pie.dev/cookies 'Cookie:sessionid=foo;another-cookie=bar'
Note
Quote the value when it contains
;so your shell doesn't interpret it.
Sessions
By default every request is independent. A session persists custom headers, authentication, and cookies between requests to the same host. Activate one with --session=NAME_OR_PATH.
http --session=user1 -a user1:password pie.dev/get X-Foo:Bar # Create
http --session=user1 pie.dev/get # Reuse — auth + X-Foo restored
Headers starting with Content- or If- are not persisted (they are request-specific).
Named vs. anonymous sessions
- Named:
--session=user1stores the file in the config directory undersessions/<host>/<name>.json. - Anonymous:
--session=./session.json(a path containing at least one/) stores it wherever you point and can be shared across hosts.
http --session=/tmp/session.json example.org
http --session=/tmp/session.json admin.example.org # Same session, different host
Important
For an anonymous session you must include at least one
/(e.g../session.json). Without a slash, HTTPie treats the value as a named session.
Read-only sessions
Use --session-read-only=NAME_OR_PATH to use a session without updating it from the response:
http --session-read-only=./ro-session.json pie.dev/headers Custom-Header:value
Cookie domain binding
Session cookies have a domain field that binds them to a host (and its subdomains). Set "domain": null in the session JSON to make a cookie unbound (sent to any host). All session data — credentials, passwords, cookies — is stored as plain-text JSON you can edit by hand.
Warning
Session files are plain text. Anyone with read access to the file can read the stored credentials and cookies.
Controlling the output
By default HTTPie prints the response headers and body. The following options change what is shown.
| Option | Prints |
|---|---|
--headers, -h |
Only the response headers |
--body, -b |
Only the response body |
--meta, -m |
Only the response metadata (elapsed time) |
--verbose, -v |
The whole exchange: request and response (also enables --all) |
-vv |
Like -v, plus response metadata |
--print, -p |
A custom selection (see below) |
--quiet, -q |
Nothing to stdout/stderr (-qq silences warnings too) |
Fine-grained --print
--print (-p) takes a string of characters, each selecting one part of the exchange:
| Character | Part |
|---|---|
H |
request headers |
B |
request body |
h |
response headers |
b |
response body |
m |
response metadata |
http --print=Hh PUT pie.dev/put hello=world # Request headers + response headers
http --print=hm pie.dev/get # Response headers + metadata
Colors and formatting
Syntax highlighting and formatting are applied automatically for terminal output. Control them with:
| Option | Effect |
|---|---|
--pretty=all |
Colors and formatting (default for terminals) |
--pretty=colors |
Colors only |
--pretty=format |
Formatting only |
--pretty=none |
No processing (default for redirected output) |
--style=NAME, -s |
Choose a color scheme |
Notable styles include auto (default, follows your terminal), pie-dark, pie-light, pie, monokai, and fruity. Run http --help to see every available style on your system.
Formatting sorts headers by name, indents and key-sorts JSON, and indents XML. Tune it with --format-options:
| Option | Default | Shortcut |
|---|---|---|
headers.sort |
true |
--sorted / --unsorted |
json.format |
true |
— |
json.indent |
4 |
— |
json.sort_keys |
true |
--sorted / --unsorted |
xml.format |
true |
— |
xml.indent |
2 |
— |
http --format-options headers.sort:false,json.sort_keys:false,json.indent:2 pie.dev/get
http --unsorted pie.dev/get # Shortcut: disable all sorting
Overriding response encoding and type
http --response-charset=big5 pie.dev/get # Force a charset
http --response-mime=text/yaml pie.dev/get # Force highlighter/formatter
Streamed responses
Responses are downloaded in chunks. Use --stream (-S) to flush each line immediately (like tail -f), which is ideal for long-lived endpoints:
http --stream pie.dev/stream/3
Note
Streaming is enabled automatically when the response has
Content-Type: text/event-stream(Server-Sent Events).
Binary data
Binary response bodies are suppressed in the terminal so they can't garble it:
+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+
Downloading files
The --download (-d) flag turns HTTPie into a wget-style downloader: response headers print to stderr and the body streams to a file with a progress bar.
http --download https://github.com/httpie/cli/archive/master.tar.gz
Downloading 251.30 kB to "httpie-master.tar.gz"
Done. 251.30 kB in 2.73862s (91.76 kB/s)
How the filename is chosen
In decreasing priority:
--output/-oif you provide it (file is overwritten, or appended to with--continue).- The server's
Content-Dispositionheader. - A name generated from the URL and
Content-Type.
To avoid overwriting, HTTPie adds a numeric suffix when needed.
Resuming a download
--continue (-c) resumes a partial download (requires --output and a server that supports Range/206):
http -dco file.zip example.org/file
-dco is shorthand for --download --continue --output.
Important
--downloadalways implies--followand--check-status. HTTPie exits1if the body wasn't fully downloaded.
Redirects, proxies, and networking
Following redirects
Redirects are not followed by default. Enable them with --follow (-F):
http --follow pie.dev/redirect/3
http --follow --all pie.dev/redirect/3 # Show every intermediary response
http --follow --max-redirects=2 pie.dev/redirect/3 # Cap the number followed (default 30)
Note
For
307 Temporary Redirectand308 Permanent Redirect, the original method and body are reused. Otherwise a body-lessGETis sent.
Proxies
http --proxy=http:http://10.10.1.10:3128 --proxy=https:https://10.10.1.10:1080 example.org
http --proxy=http:http://user:pass@10.10.1.10:3128 example.org # With auth
http --proxy=http:socks5://user:pass@host:port example.org # SOCKS
HTTPie also honors the ALL_PROXY, HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables.
Other networking flags
| Flag | Effect |
|---|---|
--timeout=SECONDS |
Fail if no response within the timeout (default 0 = no limit). |
--max-headers=N |
Stop after reading N response headers (default 0 = no limit). |
--check-status |
Exit non-zero on 3xx/4xx/5xx responses. |
--path-as-is |
Don't squash /../ and /./ in the URL path. |
HTTPS, SSL, and certificates
http --verify=no https://pie.dev/get # Skip cert verification
http --verify=/ssl/custom_ca_bundle https://example.org # Custom CA bundle
http --cert=client.pem https://example.org # Client certificate
http --cert=client.crt --cert-key=client.key https://example.org
If a client key is encrypted, HTTPie prompts for the passphrase automatically; supply it non-interactively with --cert-key-pass.
Choose a TLS version with --ssl (one of ssl2.3, ssl3, tls1, tls1.1, tls1.2, tls1.3) and the cipher list with --ciphers (OpenSSL cipher-list format).
Caution
--verify=nodisables certificate validation entirely, exposing the connection to man-in-the-middle attacks. Use it only against trusted hosts you control. You can also set a custom CA bundle via theREQUESTS_CA_BUNDLEenvironment variable.
Offline mode and scripting
Offline mode
--offline builds the request and prints it without sending anything over the network. It automatically prints both request headers and body (--print=HB):
http --offline POST pie.dev/post hello=world
Use it to generate documentation examples or raw request files:
http --offline POST pie.dev/post hello=world > request.http
nc pie.dev 80 < request.http
Scripting best practices
#!/bin/bash
if http --check-status --ignore-stdin --timeout=2.5 HEAD pie.dev/get &> /dev/null; then
echo 'OK!'
else
case $? in
2) echo 'Request timed out!' ;;
3) echo 'Unexpected HTTP 3xx Redirection!' ;;
4) echo 'HTTP 4xx Client Error!' ;;
5) echo 'HTTP 5xx Server Error!' ;;
6) echo 'Exceeded --max-redirects redirects!' ;;
*) echo 'Other Error!' ;;
esac
fi
- Use
--check-statusso the exit code reflects the HTTP status (see Exit status codes). - Use
--ignore-stdinso HTTPie doesn't hang waiting for piped input in non-interactive environments. - Use
--timeoutso a non-responsive server doesn't freeze your script.
Configuration
HTTPie reads an optional config.json file. It doesn't exist by default — create it yourself.
Config directory
| Platform | Location |
|---|---|
| Most systems | $XDG_CONFIG_HOME/httpie/config.json (defaults to ~/.config/httpie/config.json) |
| Legacy | ~/.httpie/config.json (used if ~/.httpie exists) |
| Windows | %APPDATA%\httpie\config.json |
Override the directory with the HTTPIE_CONFIG_DIR environment variable:
export HTTPIE_CONFIG_DIR=/tmp/httpie
http pie.dev/get
Run http --debug and look for config_dir to see your exact path.
Configurable options
| Key | Type | Purpose |
|---|---|---|
default_options |
array | Options applied to every invocation (e.g. a default style). |
plugins_dir |
path | Where httpie cli plugins install stores plugins. |
disable_update_warnings |
boolean | Turn off new-release notifications. |
{
"default_options": ["--style=fruity", "--check-status"]
}
Tip
Any default option can be undone for a single invocation with the matching
--no-OPTIONflag — e.g.--no-styleor--no-session.
The httpie management command
The httpie command (distinct from http/https) manages plugins and configuration. It never sends requests.
Plugin manager
| Command | What it does |
|---|---|
httpie cli plugins install <target>... |
Install plugins from PyPI or a local path. |
httpie cli plugins list |
List installed plugins and their entry points. |
httpie cli plugins upgrade <target>... |
Upgrade installed plugins. |
httpie cli plugins uninstall <target>... |
Remove plugins installed via this manager. |
httpie cli plugins install httpie-plugin
httpie cli plugins list
httpie_plugin (1.0.2)
httpie_plugin (httpie.plugins.auth.v1)
Note
The plugin manager is a thin overlay on top of
pipthat installs into an isolatedplugins_dir, so it works even on installations (like Homebrew) where directpip installinto HTTPie's environment fails.httpie plugins ...is an accepted alias forhttpie cli plugins ....
Other management commands
| Command | What it does |
|---|---|
httpie cli check-updates |
Check whether a newer release is available. |
httpie cli export-args [-f json] |
Export the http/https parser spec (for autocomplete tools). |
httpie cli sessions upgrade <host> <session> |
Upgrade one session file to the latest format. |
httpie cli sessions upgrade-all |
Upgrade every named session. |
httpie cli sessions upgrade-all
Upgraded 'api_auth' @ 'pie.dev' to v3.1.0
Upgraded 'login_cookies' @ 'httpie.io' to v3.1.0
The session-upgrade commands accept --bind-cookies, which binds previously unbound cookies to the session's host.
How HTTPie works under the hood
A quick mental model of what happens when you run a command (useful for predicting behavior):
- Parse — your arguments are split into flags and request items. The request-item separators decide which become headers, data, params, or files.
- Method inference — if you didn't name a method, HTTPie picks
GETorPOSTbased on whether there's a body. - Build — HTTPie assembles a request using the Requests library, applying session data, auth, and default headers.
- Send — unless
--offlineis set. Redirects are handled according to--follow/--max-redirects. - Output — the response streams through a formatter (colors, JSON/XML indentation) chosen from the
Content-Type, then prints.
Note
HTTPie is built on two well-known libraries: Requests for the HTTP transport and Pygments for syntax highlighting. For architecture, internals, and the plugin API, see the HTTPie Admin Guide.
Troubleshooting
Error: Request body (from stdin, --raw or a file) and request data (key=value) cannot be mixed.
Cause: You combined piped/--raw/@file body data with key=value data items. Only one source of request data is allowed.
Solution: Use either structured items or a raw body, not both. To let the key=value items win and ignore stdin, add --ignore-stdin.
Prevention: When scripting, decide up front whether a request is structured or raw.
Problem: HTTPie hangs and produces no output
Cause: In a non-interactive context (cron, CI, a subshell), stdin isn't a terminal, so HTTPie waits for a request body that never arrives.
Solution / Prevention: Always pass --ignore-stdin in scripts unless you are deliberately piping a body.
Error: Cannot use complex JSON value types with --form/--multipart.
Cause: You used a := raw-JSON array or object together with --form/--multipart.
Solution: Send the request as JSON (drop --form), or pass only scalar values (strings, numbers) as form fields.
Error: --continue only works with --download / --continue requires --output to be specified
Cause: --continue (-c) was used without --download, or without --output.
Solution: Resume downloads with all three: http -dco file.zip example.org/file.
Error: cannot combine --compress and --chunked / cannot combine --compress and --multipart
Cause: --compress can't be used with --chunked or --multipart in the same request.
Solution: Drop one of the conflicting flags.
Error: Only terminal output can be colorized on Windows.
Cause: You combined --pretty (colors) with --output to a file on Windows.
Solution: Write the file without colors, or print to the terminal and redirect separately.
Problem: JSON Content-Type not set when a single header is present
Cause: A known issue (#1640, #1834) where supplying certain single headers can suppress the automatic application/json content type.
Solution: Set the header explicitly: add Content-Type:application/json to the request.
Error: '<value>' is not a valid value
Cause: A request item didn't contain a recognized separator, so HTTPie couldn't classify it.
Solution: Make sure each item uses one of the separators (:, =, ==, :=, @, …). Escape a literal separator in a key with \.
Problem: A field or header starting with - is treated as a flag
Cause: HTTPie parses leading-dash tokens as options.
Solution: Put such items after the -- token: http pie.dev/post -- -Weird-Header:value.
Error: Unable to prompt for passwords because --ignore-stdin is set.
Cause: You used --auth without a password while --ignore-stdin is active, so HTTPie can't prompt.
Solution: Provide the full username:password, or remove --ignore-stdin for interactive use.
Problem: A binary response shows "binary data not shown in terminal"
Cause: This is intentional — HTTPie suppresses binary bodies to protect your terminal.
Solution: Redirect output to a file (> out.bin) or use --download.
Error: invalid config file / cannot read config file
Cause: config.json contains invalid JSON or can't be read.
Solution: Validate the file's JSON. Find its location with http --debug (look for config_dir).
Problem: A new-version warning keeps appearing
Cause: HTTPie checks for updates periodically and warns about once a week.
Solution: Set "disable_update_warnings": true in config.json.
FAQ
Q: What's the difference between http and https?
They are the same program; http defaults the URL scheme to http:// and https defaults it to https://. Use whichever saves typing.
Q: How do I see the request that HTTPie actually sends?
Use -v (--verbose) to print the full request and response, or --offline to build and print a request without sending it.
Q: How do I send a number or boolean in JSON instead of a string?
Use the := separator: age:=29, active:=true, tags:='["a","b"]'.
Q: Why did my request become a POST when I didn't ask for one?
HTTPie defaults to POST whenever there's body data, and GET otherwise. Name the method explicitly to override.
Q: How do I upload a file?
Use @: http -f POST pie.dev/post cv@~/files/cv.pdf. The --form flag plus a file field produces a multipart/form-data request.
Q: How do I keep a login across multiple requests?
Use a session: http --session=mysession -a user:pass example.org/login, then reuse --session=mysession on later commands.
Q: Where are my session and config files stored?
On most systems under ~/.config/httpie/ (sessions in sessions/<host>/), and %APPDATA%\httpie\ on Windows. Override with HTTPIE_CONFIG_DIR.
Q: How do I make form data the default instead of JSON?
Add --form to default_options in your config.json.
Q: How do I pass a raw JSON body instead of building it field by field?
Pipe it (echo '{...}' | http POST url), use --raw '{...}', or read it from a file with @file.json.
Q: How do I make HTTPie return a non-zero exit code on HTTP errors?
Add --check-status. The exit code will be 3 (3xx, unless --follow), 4 (4xx), or 5 (5xx).
Q: How do I disable colors when piping to another program?
Output is already uncolored when redirected. Force it anywhere with --pretty=none. Force colors on in a pipe with --pretty=all and view through less -R.
Q: How do I install an authentication method that isn't built in?
Install a plugin: httpie cli plugins install httpie-jwt-auth, then use it with -A jwt.
Q: How do I skip SSL verification for a self-signed certificate?
Use --verify=no, or better, point --verify at the CA bundle: --verify=/path/to/ca.pem.
Q: Can I send the same header twice?
Yes — repeat it: http example.org Cookie:one Cookie:two. HTTPie sends two separate header lines.
Q: How do I resume an interrupted download?
http -dco file.zip example.org/file — the server must support Range requests.
Q: How do I send a request body with a GET?
Just add data items and name the method: http GET pie.dev/get hello=world.
Complete option reference
Content type
| Option | Description |
|---|---|
--json, -j |
(default) Serialize data items as a JSON object; set JSON Content-Type/Accept. |
--form, -f |
Serialize data items as form fields (application/x-www-form-urlencoded). |
--multipart |
Always send multipart/form-data, even without files. |
--boundary |
Custom multipart boundary string (with --form). |
--raw |
Pass a raw request body string without processing. |
Content processing
| Option | Description |
|---|---|
--compress, -x |
Deflate-compress the body (Content-Encoding: deflate). Repeat to force. |
Output processing
| Option | Description |
|---|---|
--pretty |
all / colors / format / none. |
--style, -s |
Color scheme (default auto). |
--unsorted |
Disable all output sorting. |
--sorted |
Re-enable all output sorting. |
--response-charset |
Override response encoding for display (e.g. utf8, big5). |
--response-mime |
Override response MIME type for coloring/formatting. |
--format-options |
Fine-grained formatting (e.g. json.indent:2). |
Output options
| Option | Description |
|---|---|
--print, -p |
Select parts to print (H, B, h, b, m). |
--headers, -h |
Print only response headers. |
--meta, -m |
Print only response metadata. |
--body, -b |
Print only response body. |
--verbose, -v |
Print the whole exchange; repeat (-vv) to add metadata. |
--all |
Show all intermediary requests/responses. |
--history-print, -P |
Output options for intermediary exchanges. |
--stream, -S |
Stream the body line by line (tail -f behavior). |
--output, -o |
Save output to a file. |
--download, -d |
Download the body to a file (wget-style). |
--continue, -c |
Resume an interrupted download (needs --output). |
--quiet, -q |
Suppress stdout/stderr; repeat (-qq) to silence warnings. |
Sessions
| Option | Description |
|---|---|
--session |
Create or reuse-and-update a session. |
--session-read-only |
Read a session without updating it. |
Authentication
| Option | Description |
|---|---|
--auth, -a |
username[:password] or token. |
--auth-type, -A |
basic (default), digest, bearer, or a plugin. |
--ignore-netrc |
Ignore credentials from .netrc. |
Network
| Option | Default | Description |
|---|---|---|
--offline |
— | Build and print the request without sending it. |
--proxy |
— | PROTOCOL:PROXY_URL (repeatable). |
--follow, -F |
off | Follow 30x redirects. |
--max-redirects |
30 |
Maximum redirects to follow. |
--max-headers |
0 |
Max response headers to read (0 = no limit). |
--timeout |
0 |
Connection timeout in seconds (0 = no limit). |
--check-status |
off | Exit non-zero on error status codes. |
--path-as-is |
off | Don't squash /../ and /./ in the path. |
--chunked |
off | Use Transfer-Encoding: chunked. |
SSL
| Option | Default | Description |
|---|---|---|
--verify |
yes |
no to skip verification, or a CA-bundle path. |
--ssl |
— | TLS version: ssl2.3, ssl3, tls1, tls1.1, tls1.2, tls1.3. |
--ciphers |
— | OpenSSL cipher-list string. |
--cert |
— | Client-side certificate file. |
--cert-key |
— | Private key for --cert. |
--cert-key-pass |
— | Passphrase for the private key (prompted if omitted). |
Troubleshooting & meta
| Option | Default | Description |
|---|---|---|
--ignore-stdin, -I |
off | Don't read stdin (use in scripts). |
--help |
— | Show the help message. |
--manual |
— | Show the full manual / man page. |
--version |
— | Show the version and exit. |
--traceback |
off | Print a Python traceback on error. |
--default-scheme |
http |
Default URL scheme when none is given. |
--debug |
off | Print diagnostic info for bug reports. |
Note
Every
--OPTIONhas a corresponding--no-OPTIONform that resets it to its default — useful for overridingdefault_optionsfrom the config file on a single invocation.
Exit status codes
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Generic error |
2 |
Request timed out |
3 |
3xx redirect (with --check-status, no --follow) |
4 |
4xx client error (with --check-status) |
5 |
5xx server error (with --check-status) |
6 |
Too many redirects |
7 |
Plugin error |
130 |
Interrupted with Ctrl-C |
Environment variables
| Variable | Effect |
|---|---|
HTTPIE_CONFIG_DIR |
Override the configuration directory. |
XDG_CONFIG_HOME |
Base directory for the default config location. |
REQUESTS_CA_BUNDLE |
Custom CA bundle for SSL verification. |
ALL_PROXY, HTTP_PROXY, HTTPS_PROXY |
Proxy servers per protocol. |
NO_PROXY |
Hosts that bypass the configured proxies. |
HTTPIE_STDIN_READ_WARN_THRESHOLD |
Seconds before warning about idle stdin (default 10.0; 0 disables). |