Packages
hackney
4.7.2
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Current section
Files
Jump to
Current section
Files
GETTING_STARTED.md
# Getting Started with hackney
This guide walks you through installing hackney and making your first HTTP requests.
## Installation
### Rebar3 (Erlang)
Add hackney to your `rebar.config`:
```erlang
{deps, [hackney]}.
```
### Mix (Elixir)
Add to your `mix.exs`:
```elixir
{:hackney, "~> 4.0"}
```
## Starting hackney
hackney is an OTP application. Start it before making requests:
```erlang
application:ensure_all_started(hackney).
```
## Your First Request
### Simple GET
The response body is returned directly in the response tuple:
```erlang
{ok, 200, Headers, Body} = hackney:get(<<"https://httpbin.org/get">>).
```
### Reading the Body of a Streamed Request
When you stream the request body, `start_response/1` returns a connection
PID. Read the full response body with `hackney:body/1` (or `stream_body/1`
for chunk-by-chunk):
```erlang
{ok, Status, RespHeaders, ConnPid} = hackney:start_response(ConnPid),
{ok, Body} = hackney:body(ConnPid).
```
## POST Requests
### Simple POST
```erlang
URL = <<"https://httpbin.org/post">>,
Headers = [{<<"content-type">>, <<"application/json">>}],
Body = <<"{\"name\": \"hackney\"}">>,
{ok, 200, _, Ref} = hackney:post(URL, Headers, Body).
```
### Form Data
```erlang
hackney:post(URL, [], {form, [{<<"key">>, <<"value">>}]}).
```
### Multipart / File Upload
```erlang
hackney:post(URL, [], {multipart, [
{<<"field">>, <<"value">>},
{file, <<"/path/to/file.txt">>}
]}).
```
## Request Options
| Option | Description |
|--------|-------------|
| `with_body` | Return body in response tuple |
| `{pool, Name}` | Use named connection pool |
| `{pool, false}` | Don't use pooling |
| `{connect_timeout, Ms}` | Connection timeout (default: 8000) |
| `{recv_timeout, Ms}` | Response timeout (default: 5000) |
| `async` | Receive response as messages |
| `{follow_redirect, true}` | Follow redirects |
| `insecure` | Skip SSL verification |
## Connection Pooling
hackney pools connections by default:
```erlang
%% Create a pool
hackney_pool:start_pool(api_pool, [{max_connections, 50}]).
%% Use the pool
hackney:get(URL, [], <<>>, [{pool, api_pool}]).
%% Disable pooling
hackney:get(URL, [], <<>>, [{pool, false}]).
```
## Error Handling
```erlang
case hackney:get(URL) of
{ok, Status, Headers, Body} ->
handle_response(Status, Headers, Body);
{error, timeout} ->
handle_timeout();
{error, Reason} ->
handle_error(Reason)
end.
```
## Next Steps
- [HTTP Guide](guides/http_guide.md) - Streaming, async responses, advanced features
- [WebSocket Guide](guides/websocket_guide.md) - Real-time bidirectional communication
- [Migration Guide](guides/MIGRATION.md) - Upgrading from hackney 1.x