Build Status Coverage Status Hex Version Hex Docs

An Elixir client for the Humaans API.

Installation

The package can be installed by adding humaans to your list of dependencies in mix.exs:

def deps do
  [
    {:humaans, "~> 0.6.0"}
  ]
end

Usage

To use this client with the Humaans API, you'll need to generate an API access token in the Humaans application.

Client-based approach

The recommended way to use this library is to instantiate a client first:

# Create a client with your access token
client = Humaans.new(access_token: "YOUR_ACCESS_TOKEN")

# Make API requests passing the client as the first argument
{:ok, people} = Humaans.People.list(client)
{:ok, person} = Humaans.People.retrieve(client, "person_id")
{:ok, company} = Humaans.Companies.retrieve(client, "company_id")

This approach allows you to create multiple clients with different access tokens and use them independently.

Tuning the HTTP client

Pass :req_options to Humaans.new/1 to customise the underlying Req client (timeouts, retries, plugins, etc.):

client =
  Humaans.new(
    access_token: "YOUR_ACCESS_TOKEN",
    req_options: [connect_options: [timeout: 30_000], retry: :transient]
  )

For deeper customisation, implement Humaans.HTTPClient.Behaviour and pass the module via :http_client.

Module access helpers

The library provides convenience functions to access the different resource modules:

client = Humaans.new(access_token: "YOUR_ACCESS_TOKEN")

# Use the module access helpers
{:ok, people} = Humaans.people().list(client)
{:ok, accounts} = Humaans.bank_accounts().list(client)
{:ok, companies} = Humaans.companies().list(client)

Rate-limit retries

The default HTTP client retries transient failures (status 408, 429, 500, 502, 503, 504) up to 3 times with exponential backoff, honouring the Retry-After header. To opt out, pass req_options: [retry: false] to Humaans.new/1.

Snake_case request bodies

You can write request bodies in idiomatic snake_case — Humaans.Client converts top-level keys to camelCase before sending them to the API. Already-camelCase keys keep their casing, so existing code that uses camelCase continues to work.

# Both of these send {"firstName": "Jane", "lastName": "Doe"}:
Humaans.People.create(client, %{first_name: "Jane", last_name: "Doe"})
Humaans.People.create(client, %{firstName: "Jane", lastName: "Doe"})

Atom and string input keys are normalized to string keys in the converted body (this avoids creating new atoms at runtime). Req JSON-encodes string-keyed maps transparently. Only top-level keys are converted; nested maps inside a body are left as-is.

Webhooks

Verify HMAC-SHA256 signatures on incoming webhook deliveries with Humaans.Webhooks.verify_signature/3. Pass the raw request body (not the re-encoded JSON):

case Humaans.Webhooks.verify_signature(raw_body, signature_header, secret) do
  :ok -> handle_event(raw_body)
  {:error, :invalid_signature} -> {:error, :unauthorized}
  {:error, :missing_signature} -> {:error, :unauthorized}
  {:error, :missing_secret} -> {:error, :misconfigured}
end

Filtering with Humaans.Query

Build filter queries for list endpoints using the operator helpers in Humaans.Query:

query =
  Humaans.Query.new()
  |> Humaans.Query.in_(:status, ["active", "onboarding"])
  |> Humaans.Query.gte(:createdAt, "2025-01-01")
  |> Humaans.Query.to_params()

{:ok, people} = Humaans.People.list(client, query)

Supported operators: eq, in_, nin, gt, gte, lt, lte. Use Humaans.Query.merge/2 to combine a query with pagination params or another query.

Available resources

Development

Requirements

  • Elixir ~> 1.15
  • Homebrew (for installing development tools)

Setup

Run the setup script to install development tools and git hooks:

bin/setup

This installs actionlint, check-jsonschema, lefthook, and markdownlint-cli2 via Homebrew, then configures the pre-commit hooks.

Commands

CommandDescription
mix setupInstall dependencies
mix testRun the test suite
mix credoRun the linter
mix formatFormat source files

License

Humaans is released under the MIT license.