PolarExpress

Comprehensive Elixir SDK for the Polar API, with verified 1:1 feature parity to the official JavaScript SDK.

Note: This is an community Elixir SDK for Polar. Polar's official SDKs are in TypeScript/JavaScript and Python. This project is generated from the same OpenAPI spec that Polar uses to build their official SDKs, follows the same service architecture, and is structured to match the official JavaScript SDK. The goal is an idiomatic Elixir experience with the same API coverage.

What's Included

The SDK layer provides typed resource structs, typed request params, and auto-paging pagination — all generated from the spec with full documentation. The client layer handles HTTP execution via Finch with connection pooling, automatic retries, request encoding, response deserialization, and telemetry.

Together, the complete Polar API surface is covered: 31 service modules, 30 typed resource structs, 85 typed params modules, webhook signature verification, and automatic pagination.

Installation

With Igniter (recommended for Phoenix)

Beta: The Igniter installer is new and under active testing. Report issues here.

If your project uses Igniter, one command sets up the webhook plug, controller, route, and setup guidance:

mix igniter.install polar_express

See the Igniter Installer guide for a detailed walkthrough of what the installer does.

Manual

Add polar_express to your dependencies in mix.exs:

def deps do
  [
    {:polar_express, "~> 0.1.5"}
  ]
end

Requires Elixir 1.19+ and OTP 27+.

Configuration

PolarExpress does not read config :polar_express. Read secrets at your application boundary and pass them explicitly.

Start the default Finch pool in your supervision tree:

children = [
  PolarExpress
]

Create clients with explicit credentials:

client =
  PolarExpress.client(System.fetch_env!("POLAR_ACCESS_TOKEN"),
    server: :sandbox,
    max_retries: 3,
    timeout_ms: 30_000
  )

See the Getting Started guide for all config options.

Quick Start

client = PolarExpress.client(System.fetch_env!("POLAR_ACCESS_TOKEN"))

# Create a customer
{:ok, customer} = PolarExpress.Services.CustomersService.create_customer(client, %{
  email: "jane@example.com"
})

# List products
{:ok, products} = PolarExpress.Services.ProductsService.list_products(client, %{"limit" => 10})

# Create a checkout
{:ok, checkout} = PolarExpress.Services.CheckoutsService.create_checkout_session(client, %{
  "product_price_id" => "price_123",
  "success_url" => "https://example.com/success"
})

Responses are automatically deserialized into typed structs:

customer.id        #=> "cus_abc123"
customer.email     #=> "jane@example.com"
customer.__struct__ #=> PolarExpress.Resources.Customers

Pass options per-client for multi-key or multi-server scenarios:

client = PolarExpress.client("pk_test_key", server: :sandbox)
client = PolarExpress.client("pk_test_other_key", max_retries: 5)

Features

SDK

Client

Guides

Development

# Sync the OpenAPI spec
bash scripts/sync_openapi.sh

# Generate the SDK
mix polar.generate --clean --stats

# Verify
mix compile --warnings-as-errors
mix test
mix docs --warnings-as-errors
bash scripts/diff_js.sh

Code Generation

The SDK is auto-generated from Polar's OpenAPI spec via mix polar.generate. The generator produces:

A small set of overrides handle cases where the spec's metadata doesn't match the JavaScript SDK's service layout. Each override is documented with a reason and enforced by tests.

Parity Testing

JavaScript SDK parity is a hard invariant. CI runs scripts/diff_js.sh to verify 1:1 service file and endpoint coverage. The test suite includes dedicated parity assertions comparing the generated endpoint set against both the OpenAPI spec and the JavaScript SDK fixture tree.

License

MIT License. See LICENSE for details.