Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

HTTPie User Guide

Generated June 2026 from httpie/cli at 5b604c3

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

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 scheme http://) and https (default scheme https://). 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

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 PUT because you named it.
  • name=John became a JSON field, so HTTPie set Content-Type: application/json.
  • X-API-Token:123 became 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 .dev0 suffix (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:

  • GET when the request has no body.
  • POST when 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 :port and :/path shorthands are perfect for local development — http :8000/api/health hits http://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 the Accept: application/json header even when you aren't sending data. HTTPie will also try to detect and prettify JSON responses even when the server returns the wrong Content-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]=value creates a nested object.
  • key[]=value appends to an array.
  • key[2]=value sets an explicit array index (missing indexes become null).
  • []:=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 index 1.


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-Length cannot 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, when stdin isn'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=user1 stores the file in the config directory under sessions/<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

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:

  1. --output/-o if you provide it (file is overwritten, or appended to with --continue).
  2. The server's Content-Disposition header.
  3. 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

--download always implies --follow and --check-status. HTTPie exits 1 if 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 Redirect and 308 Permanent Redirect, the original method and body are reused. Otherwise a body-less GET is 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=no disables 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 the REQUESTS_CA_BUNDLE environment 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-status so the exit code reflects the HTTP status (see Exit status codes).
  • Use --ignore-stdin so HTTPie doesn't hang waiting for piped input in non-interactive environments.
  • Use --timeout so 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-OPTION flag — e.g. --no-style or --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 pip that installs into an isolated plugins_dir, so it works even on installations (like Homebrew) where direct pip install into HTTPie's environment fails. httpie plugins ... is an accepted alias for httpie 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):

  1. Parse — your arguments are split into flags and request items. The request-item separators decide which become headers, data, params, or files.
  2. Method inference — if you didn't name a method, HTTPie picks GET or POST based on whether there's a body.
  3. Build — HTTPie assembles a request using the Requests library, applying session data, auth, and default headers.
  4. Send — unless --offline is set. Redirects are handled according to --follow/--max-redirects.
  5. 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 --OPTION has a corresponding --no-OPTION form that resets it to its default — useful for overriding default_options from 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).