Getting Started with hackney

May 25, 2026 ยท View on GitHub

This guide walks you through installing hackney and making your first HTTP requests.

Installation

Rebar3 (Erlang)

Add hackney to your rebar.config:

{deps, [hackney]}.

Mix (Elixir)

Add to your mix.exs:

{:hackney, "~> 4.0"}

Starting hackney

hackney is an OTP application. Start it before making requests:

application:ensure_all_started(hackney).

Your First Request

Simple GET

The response body is returned directly in the response tuple:

{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):

{ok, Status, RespHeaders, ConnPid} = hackney:start_response(ConnPid),
{ok, Body} = hackney:body(ConnPid).

POST Requests

Simple POST

URL = <<"https://httpbin.org/post">>,
Headers = [{<<"content-type">>, <<"application/json">>}],
Body = <<"{\"name\": \"hackney\"}">>,
{ok, 200, _, Ref} = hackney:post(URL, Headers, Body).

Form Data

hackney:post(URL, [], {form, [{<<"key">>, <<"value">>}]}).

Multipart / File Upload

hackney:post(URL, [], {multipart, [
    {<<"field">>, <<"value">>},
    {file, <<"/path/to/file.txt">>}
]}).

Request Options

OptionDescription
with_bodyReturn 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)
asyncReceive response as messages
{follow_redirect, true}Follow redirects
insecureSkip SSL verification

Connection Pooling

hackney pools connections by default:

%% 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

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