Unit
Production-grade Elixir hex package for the Unit embedded banking API.
Features
- ✅ Full Unit API coverage: applications, customers, accounts, cards, payments, transactions, webhooks, and more
- ✅ JSON:API envelope handling — resources decoded into typed Elixir structs
- ✅ Three-tier token model: Org, Customer, Cardholder
- ✅ Automatic retry with exponential back-off and jitter
- ✅ Idempotency key support on all mutating requests
- ✅ Telemetry instrumentation (
[:unit, :request, :start/stop/exception]) - ✅ Runtime config resolution (
{:system, "ENV_VAR"}and MFA tuples) - ✅ Sandbox simulation endpoints for every resource type
- ✅ Zero-surprise error types via
Unit.Error
Installation
# mix.exs
def deps do
[
{:unit, "~> 1.0"}
]
end
Configuration
# config/runtime.exs
config :unit,
api_token: System.get_env("UNIT_API_TOKEN"),
environment: :sandbox # :sandbox | :production
Quick start
# 1. Onboard an individual customer
{:ok, app} = Unit.API.Applications.create_individual(%{
full_name: %{first: "Jane", last: "Doe"},
ssn: "000000002",
date_of_birth: ~D[1990-01-15],
address: %{street: "123 Main St", city: "SF", state: "CA", postal_code: "94105", country: "US"},
email: "jane@example.com",
phone: %{country_code: "1", number: "5555550100"},
ip: "127.0.0.1"
})
# 2. Open a checking account
{:ok, account} = Unit.API.Accounts.create_deposit(app.customer_id, "checking")
# 3. Issue a virtual debit card
{:ok, card} = Unit.API.Cards.create_individual_virtual_debit(%{
customer_id: app.customer_id,
account_id: account.id
})
# 4. Send an ACH credit
{:ok, payment} = Unit.API.Payments.create_ach(%{
account_id: account.id,
amount: 10_000, # $100.00 in cents
direction: "Credit",
description: "Payroll",
counterparty: %{
routing_number: "812345678",
account_number: "1000000002",
account_type: "Checking",
name: "Jane Doe"
}
})
# 5. Listen for events via webhooks
{:ok, _webhook} = Unit.API.Webhooks.create(%{
label: "my-app",
url: "https://myapp.com/webhooks/unit",
token: "my-secret-token",
delivery_mode: "AtLeastOnce"
})
Error handling
All functions return {:ok, result} or {:error, %Unit.Error{}}:
case Unit.API.Payments.create_ach(params) do
{:ok, payment} ->
Logger.info("Payment created: #{payment.id}")
{:error, %Unit.Error{type: :validation_error, errors: errors}} ->
Logger.warning("Validation failed: #{inspect(errors)}")
{:error, %Unit.Error{type: :auth_error}} ->
Logger.error("Invalid or expired API token")
{:error, %Unit.Error{type: :network_error, message: msg}} ->
Logger.error("Network failure: #{msg}")
end
Per-request options
Every API function accepts opts that override global config:
# Use a customer-scoped token for front-end requests
Unit.API.Accounts.list(api_token: customer_token)
# Adjust timeout for a slow operation
Unit.API.Statements.get_pdf(id, timeout: 60_000)
# Use a different environment
Unit.API.Sandbox.receive_ach(params, environment: :sandbox)
Telemetry
Attach to standard telemetry events:
:telemetry.attach(
"unit-logger",
[:unit, :request, :stop],
fn _event, %{duration: d}, %{resource: r, action: a, status: s}, _config ->
Logger.info("[Unit] #{r}.#{a} → HTTP #{s} (#{div(d, 1_000_000)}ms)")
end,
nil
)
Sandbox simulations
# Simulate an incoming ACH credit (sandbox only)
Unit.API.Sandbox.receive_ach(%{
account_id: account.id,
amount: 50_000,
direction: "Credit",
description: "Test deposit"
})
# Simulate a card purchase
Unit.API.Sandbox.purchase_card(%{
card_id: card.id,
amount: 1_500,
merchant: %{name: "Coffee Shop", type: 5812, category: "Restaurants", location: "SF"}
})
API coverage
| Module | Endpoints |
|---|---|
Unit.API.Applications | create individual/business, get, list, update, cancel, documents upload |
Unit.API.Customers | get, list, update, archive, authorized users |
Unit.API.Accounts | create deposit, get, list, update, close, freeze/unfreeze, limits, balance history |
Unit.API.Cards | create (all types), get, list, update, freeze/unfreeze, report lost/stolen, close, activate |
Unit.API.Payments | ACH, Wire, Book, Bulk, received ACH, return received ACH, cancel |
Unit.API.Transactions | get, list, update tags |
Unit.API.Counterparties | create, get, list, update, delete |
Unit.API.Repayments | book, ACH, capital partner variants, get, list |
Unit.API.CheckDeposits | create, upload front/back, get, list, update |
Unit.API.CheckPayments | create, get, list, cancel, return, get images |
Unit.API.StopPayments | ACH, check, get, list, disable |
Unit.API.Chargebacks | create, list |
Unit.API.Statements | list, HTML, PDF, bank PDF |
Unit.API.Webhooks | create, get, list, update, delete, enable/disable |
Unit.API.Events | get, list, fire |
Unit.API.Tokens | customer token, token verification, cardholder token, org token |
Unit.API.Institutions | lookup by routing number |
Unit.API.Sandbox | approve/deny app, receive ACH/wire, authorize/purchase card, ATM, check deposit, interest |
License
MIT