atradio (Erlang SDK)

The official Erlang SDK for atradio.fm. It binds the shared Rust core (atradio-sdk) as a Rustler NIF. The auth / record / reconcile logic is identical to the Rust, Go, TypeScript, Python, Ruby, and Clojure SDKs.

Because the SDK's calls do network I/O — which must never block a BEAM scheduler — every I/O NIF runs on a dirty IO scheduler. Results cross as JSON binaries in {"ok"|"error"} envelopes, decoded with the OTP json module.

Install (Hex)

Published as atradio_erl (the OTP app + modules are atradio / atradio_nif). The NIF is fetched from the GitHub release on first load — no Rust needed to use the package.

%% rebar.config
{deps, [{atradio_erl, "~> 0.1"}]}.
# mix.exs
{:atradio_erl, "~> 0.1"}

Requirements

Setup

cd sdk/erlang
./build.sh # cargo build the NIF + copy it to priv/ + erlc the modules
erl -pa ebin -noshell -eval 'atradio_smoke:main(), init:stop().'

Usage

%% Reads — unauthenticated.
Recent = atradio:recent_stations(10),
atradio:popular_stations(10),
atradio:favorites(<<"alice.bsky.social">>, 50),
%% The favorite record key matches every other atradio SDK.
Rk = atradio:favorite_rkey(<<"rb:...">>), %% 16-byte binary
%% Writes — app-password login (persists a session file). Stations are maps
%% with binary camelCase keys.
Agent = atradio:login(<<"session.json">>, <<"alice.bsky.social">>, <<"app-password">>),
atradio:favorite(Agent, #{<<"stationId">> => <<"rb:...">>, <<"name">> => <<"KEXP">>,
<<"streamUrl">> => <<"https://…">>, <<"source">> => <<"radio-browser">>}),
atradio:set_play_status(Agent, Station).
%% The agent handle is a resource — released automatically by GC.

How it works