---
obj: application
repo: https://github.com/httpie/httpie
website: https://httpie.io
flatpak-id: io.httpie.Httpie
---

# HTTPie
modern, user-friendly command-line [HTTP](../../internet/HTTP.md) client (with optional GUI) for the API era. [JSON](../../files/JSON.md) support, colors, sessions, downloads, plugins & more.

## GUI
HTTPie features a graphical application for API testing. It supports everything features in the CLI version but with graphics.

![Screenshot](./httpie.avif)

## CLI
Usage:
```shell
http [flags] [METHOD] URL [ITEM [ITEM]]
```

### Querystring parameters
If you find yourself manually constructing URLs with querystring parameters on the terminal, you may appreciate the `param==value` syntax for appending [URL](../../internet/URL.md) parameters.

With that, you don’t have to worry about escaping the `&` separators for your [shell](../cli/Shell.md). Additionally, any special characters in the parameter name or value get automatically [URL](../../internet/URL.md)-escaped (as opposed to the parameters specified in the full [URL](../../internet/URL.md), which HTTPie doesn’t modify).
```shell
$ http https://api.github.com/search/repositories q==httpie per_page==1
```

```http
GET /search/repositories?q=httpie&per_page=1 HTTP/1.1
```

### Request Items
|                                                    Item Type | Description                                                                                                                                                                                                            |
| ------------------------------------------------------------:| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|                                    HTTP Headers `Name:Value` | Arbitrary [HTTP](../../internet/HTTP.md) header, e.g. `X-API-Token:123`                                                                                                                                                |
|        [URL](../../internet/URL.md) parameters `name==value` | Appends the given name/value pair as a querystring parameter to the [URL](../../internet/URL.md). The `==` separator is used.                                                                                          |
|                                    Data Fields `field=value` | Request data fields to be serialized as a [JSON](../../files/JSON.md) object (default), to be form-encoded (with `--form, -f`), or to be serialized as `multipart/form-data` (with `--multipart`)                      |
|                                Raw JSON fields `field:=json` | Useful when sending [JSON](../../files/JSON.md) and one or more fields need to be a `Boolean`, `Number`, nested `Object`, or an `Array`, e.g., `meals:='["ham","spam"]'` or `pies:=[1,2,3]` (note the quotes)          |
| File upload fields `field@/dir/file`, `field@file;type=mime` | Only available with `--form`, `-f` and `--multipart`. For example `screenshot@~/Pictures/img.png`, or `'cv@cv.txt;type=text/markdown'`. With `--form`, the presence of a file field results in a `--multipart` request |

### JSON Requests
Data is send as [JSON](../../files/JSON.md) by default.

Non-string [JSON](../../files/JSON.md) fields use the `:=` separator, which allows you to embed arbitrary [JSON](../../files/JSON.md) data into the resulting [JSON](../../files/JSON.md) object. Additionally, text and raw [JSON](../../files/JSON.md) files can also be embedded into fields using `=@` and `:=@`:
```shell
$ http PUT pie.dev/put \
    name=John \                        # String (default)
    age:=29 \                          # Raw JSON — Number
    married:=false \                   # Raw JSON — Boolean
    hobbies:='["http", "pies"]' \      # Raw JSON — Array
    favorite:='{"tool": "HTTPie"}' \   # Raw JSON — Object
    bookmarks:=@files/data.json \      # Embed JSON file
    description=@files/text.txt        # Embed text file
```

```http
PUT /person/1 HTTP/1.1
Accept: application/json, */*;q=0.5
Content-Type: application/json
Host: pie.dev

{
    "age": 29,
    "hobbies": [
        "http",
        "pies"
    ],
    "description": "John is a nice guy who likes pies.",
    "married": false,
    "name": "John",
    "favorite": {
        "tool": "HTTPie"
    },
    "bookmarks": {
        "HTTPie": "https://httpie.org",
    }
}
```

### Forms
Submitting forms is very similar to sending [JSON](../../files/JSON.md) requests. Often the only difference is in adding the `--form, -f` option, which ensures that data fields are serialized as, and `Content-Type` is set to `application/x-www-form-urlencoded; charset=utf-8`.

#### Regular forms
```shell
$ http --form POST pie.dev/post name='John Smith'
```

```http
POST /post HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8

name=John+Smith
```

#### File upload forms
If one or more file fields is present, the serialization and content type is `multipart/form-data`:
```shell
$ http -f POST pie.dev/post name='John Smith' cv@~/files/data.xml
```

The request above is the same as if the following [HTML](../../internet/HTML.md) form were submitted:
```html
<form enctype="multipart/form-data" method="post" action="http://example.com/jobs">
    <input type="text" name="name" />
    <input type="file" name="cv" />
</form>
```

Please note that `@` is used to simulate a file upload form field, whereas `=@` just embeds the file content as a regular text field value.

When uploading files, their content type is inferred from the file name. You can manually override the inferred content type:
```shell
$ http -f POST pie.dev/post name='John Smith' cv@'~/files/data.bin;type=application/pdf'
```

### HTTP headers
To set custom headers you can use the `Header:Value` notation:
```shell
$ http pie.dev/headers User-Agent:Bacon/1.0 'Cookie:valued-visitor=yes;foo=bar' \
    X-Foo:Bar Referer:https://httpie.org/
```

```http
GET /headers HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Cookie: valued-visitor=yes;foo=bar
Host: pie.dev
Referer: https://httpie.org/
User-Agent: Bacon/1.0
X-Foo: Bar
```

#### Default request headers
There are a couple of default headers that HTTPie sets:

```http
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: HTTPie/<version>
Host: <taken-from-URL>
```

All of these can be overwritten or unset.

#### Reading headers from a file
You can read headers from a file by using the `:@` operator. This would also effectively strip the newlines from the end.

```shell
$ http pie.dev/headers X-Data:@files/text.txt
```

#### Empty headers and header un-setting
To unset a previously specified header (such a one of the default headers), use `Header:`:
```shell
$ http pie.dev/headers Accept: User-Agent:
```

To send a header with an empty value, use `Header;`, with a semicolon:
```shell
$ http pie.dev/headers 'Header;'
```

Please note that some internal headers, such as `Content-Length`, can’t be unset if they are automatically added by the client itself.

#### Multiple header values with the same name
If the request is sent with multiple headers that are sharing the same name, then the HTTPie will send them individually.
```shell
http example.org Cookie:one Cookie:two
```

```http
GET / HTTP/1.1
Cookie: one
Cookie: two
```

It is also possible to pass a single header value pair, where the value is a comma separated list of header values. Then the client will send it as a single header.
```shell
http example.org Numbers:one,two
```

```http
GET / HTTP/1.1
Numbers: one,two
```

Also be aware that if the current session contains any headers they will get overwritten by individual commands when sending a request instead of being joined together.

### Offline mode
Use `--offline` to construct [HTTP](../../internet/HTTP.md) requests without sending them anywhere. With `--offline`, HTTPie builds a request based on the specified options and arguments, prints it to `stdout`, and then exits. It works completely offline; no network connection is ever made. This has a number of use cases, including:

Generating API documentation examples that you can copy & paste without sending a request:
```shell
$ http --offline POST server.chess/api/games API-Key:ZZZ w=magnus b=hikaru t=180 i=2
```

```shell
$ http --offline MOVE server.chess/api/games/123 API-Key:ZZZ p=b a=R1a3 t=77
```

Generating raw requests that can be sent with any other client:
```shell
# 1. save a raw request to a file:
$ http --offline POST pie.dev/post hello=world > request.http

# 2. send it over the wire with, for example, the fantastic netcat tool:
$ nc pie.dev 80 < request.http
```

You can also use the `--offline` mode for debugging and exploring [HTTP](../../internet/HTTP.md) and HTTPie, and for “dry runs”.

### Cookies
[HTTP](../../internet/HTTP.md) clients send [cookies](../../internet/Cookie.md) to the server as regular [HTTP](../../internet/HTTP.md) headers. That means, HTTPie does not offer any special syntax for specifying cookies — the usual `Header:Value` notation is used:

Send a single [cookie](../../internet/Cookie.md):
```shell
$ http pie.dev/cookies Cookie:sessionid=foo
```

```http
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: sessionid=foo
Host: pie.dev
User-Agent: HTTPie/0.9.9
```

Send multiple cookies (note: the header is quoted to prevent the [shell](../cli/Shell.md) from interpreting the `;`):

```shell
$ http pie.dev/cookies 'Cookie:sessionid=foo;another-cookie=bar'
```

```http
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: sessionid=foo;another-cookie=bar
Host: pie.dev
User-Agent: HTTPie/0.9.9
```

### Authentication
#### Basic auth
```shell
$ http -a username:password pie.dev/basic-auth/username/password
```

#### Digest auth
```shell
$ http -A digest -a username:password pie.dev/digest-auth/httpie/username/password
```

#### Bearer auth
```shell
https -A bearer -a token pie.dev/bearer
```

#### Password prompt
If you omit the password part of `--auth, -a`, HTTPie securely prompts you for it:

```shell
$ http -a username pie.dev/basic-auth/username/password
```

### HTTP redirects
By default, [HTTP](../../internet/HTTP.md) redirects are not followed and only the first response is shown:
```shell
$ http pie.dev/redirect/3
```

#### Follow `Location`
To instruct HTTPie to follow the `Location` header of `30x` responses and show the final response instead, use the `--follow, -F` option:
```shell
$ http --follow pie.dev/redirect/3
```

With `307 Temporary Redirect` and `308 Permanent Redirect`, the method and the body of the original request are reused to perform the redirected request. Otherwise, a body-less `GET` request is performed.

#### Showing intermediary redirect responses
If you wish to see the intermediary requests/responses, then use the `--all` option:

```shell
$ http --follow --all pie.dev/redirect/3
```

#### Limiting maximum redirects followed
To change the default limit of maximum `30` redirects, use the `--max-redirects=<limit>` option:

```shell
$ http --follow --all --max-redirects=2 pie.dev/redirect/3
```

### Proxies
You can specify proxies to be used through the `--proxy` argument for each protocol (which is included in the value in case of redirects across protocols):
```shell
$ http --proxy=http:http://10.10.1.10:3128 --proxy=https:https://10.10.1.10:1080 example.org
```

With Basic authentication:
```shell
$ http --proxy=http:http://user:pass@10.10.1.10:3128 example.org
```

#### Environment variables
You can also configure proxies by [environment variables](../../linux/Environment%20Variables.md) `ALL_PROXY`, `HTTP_PROXY` and `HTTPS_PROXY`, and the underlying [Requests library](https://requests.readthedocs.io/en/latest/) will pick them up. If you want to disable proxies configured through the [environment variables](../../linux/Environment%20Variables.md) for certain hosts, you can specify them in `NO_PROXY`.

In your `~/.bash_profile`:
```shell
export HTTP_PROXY=http://10.10.1.10:3128
export HTTPS_PROXY=https://10.10.1.10:1080
export NO_PROXY=localhost,example.com
```

#### SOCK
Usage for SOCKS is the same as for other types of proxies:
```shell
$ http --proxy=http:socks5://user:pass@host:port --proxy=https:socks5://user:pass@host:port example.org
```

### HTTPS
To skip the host’s SSL certificate verification, you can pass `--verify=no` (default is `yes`):

```shell
$ http --verify=no https://pie.dev/get
```

### Output options
By default, HTTPie only outputs the final response and the whole response message is printed (headers as well as the body). You can control what should be printed via several options:

|                     Option | What is printed                                                                                    |
| --------------------------:| -------------------------------------------------------------------------------------------------- |
|            `--headers, -h` | Only the response headers are printed                                                              |
|               `--body, -b` | Only the response body is printed                                                                  |
|               `--meta, -m` | Only the response metadata is printed                                                              | 
|            `--verbose, -v` | Print the whole [HTTP](../../internet/HTTP.md) exchange (request and response). This option also enables `--all` (see below) |
| `--verbose --verbose, -vv` | Just like `-v`, but also include the response metadata.                                            |
|              `--print, -p` | Selects parts of the [HTTP](../../internet/HTTP.md) exchange                                                                 |
|              `--quiet, -q` | Don’t print anything to `stdout` and `stderr`                                                      |

### Download mode
HTTPie features a download mode in which it acts similarly to [wget](../cli/network/wget.md).

When enabled using the `--download, -d` flag, response headers are printed to the terminal (`stderr`), and a progress bar is shown while the response body is being saved to a file.
```shell
$ http --download https://github.com/httpie/cli/archive/master.tar.gz
```

```http
HTTP/1.1 200 OK
Content-Disposition: attachment; filename=httpie-master.tar.gz
Content-Length: 257336
Content-Type: application/x-gzip

Downloading 251.30 kB to "httpie-master.tar.gz"
Done. 251.30 kB in 2.73862s (91.76 kB/s)
```

#### Downloaded filename
There are three mutually exclusive ways through which HTTPie determines the output filename (with decreasing priority):

1. You can explicitly provide it via `--output, -o`. The file gets overwritten if it already exists (or appended to with `--continue, -c`).
2. The server may specify the filename in the optional `Content-Disposition` response header. Any leading dots are stripped from a server-provided filename.
3. The last resort HTTPie uses is to generate the filename from a combination of the request [URL](../../internet/URL.md) and the response `Content-Type`. The initial [URL](../../internet/URL.md) is always used as the basis for the generated filename — even if there has been one or more redirects.

To prevent data loss by overwriting, HTTPie adds a unique numerical suffix to the filename when necessary (unless specified with `--output, -o`).

#### Piping while downloading
You can also redirect the response body to another program while the response headers and progress are still shown in the terminal:

```shell
$ http -d https://github.com/httpie/cli/archive/master.tar.gz | tar zxf -
```

#### Resuming downloads
If `--output, -o` is specified, you can resume a partial download using the `--continue, -c` option. This only works with servers that support `Range` requests and `206 Partial Content` responses. If the server doesn’t support that, the whole file will simply be downloaded:
```shell
$ http -dco file.zip example.org/file
```

`-dco` is shorthand for `--download` `--continue` `--output`.

### Sessions
By default, every request HTTPie makes is completely independent of any previous ones to the same host.

However, HTTPie also supports persistent sessions via the `--session=SESSION_NAME_OR_PATH` option. In a session, custom [HTTP](../../internet/HTTP.md) headers (except for the ones starting with `Content-` or `If-`), authentication, and cookies (manually specified or sent by the server) persist between requests to the same host.

```shell
# Create a new session:
$ http --session=./session.json pie.dev/headers API-Token:123

# Inspect / edit the generated session file:
$ cat session.json

# Re-use the existing session — the API-Token header will be set:
$ http --session=./session.json pie.dev/headers
```

All session data, including credentials, prompted passwords, [cookie](../../internet/Cookie.md) data, and custom headers are stored in plain text. That means session files can also be created and edited manually in a text editor—they are regular [JSON](../../files/JSON.md). It also means that they can be read by anyone who has access to the session file.

#### Readonly session
To use the original session file without updating it from the request/response exchange after it has been created, specify the session name via `--session-read-only=SESSION_NAME_OR_PATH` instead.
```shell
# If the session file doesn’t exist, then it is created:
$ http --session-read-only=./ro-session.json pie.dev/headers Custom-Header:orig-value

# But it is not updated:
$ http --session-read-only=./ro-session.json pie.dev/headers Custom-Header:new-value
```
