Skip to main content
Back to SDKs

Release history

Every shipped version of @solidnumber/sdk — the typed TypeScript and JavaScript client for the Solid# API. Newest at the top.

Latestv1.2.0· 2026-09npm i @solidnumber/sdk

Authored by Adam Campbell · BSL-1.1 · GitHub · npm

All releases

Quick scan. Each row is one published version; the notes for each follow below.

VersionDateSummary
v1.2.02026-09One route classifier, and it lives on the server. The device-route state machine arrives — before it, no console anywhere handled a caller changing headsets mid-call.
v1.1.02026-09A second entry point: @solidnumber/sdk/voice, the browser voice console’s pure logic — one copy, replacing three that had already drifted.
v1.0.02026-07SolidClient — typed, namespaced access to the Solid# REST API.

Release notes

What changed, why it mattered, and what it means for anything already importing this package.

v1.2.0

2026-09

⛔ The class vocabulary for "where is this caller’s audio coming from" briefly existed twice — once in this package and once in the backend. Two copies of a vocabulary in two languages cannot be kept in step by intention; they drift, and this drift would have been silent, because the only symptom was a flag on a telemetry field nobody reads until they are already debugging a call. So classification moved to the backend and this package deleted its copy. The client now sends what only a client can see — the device labels — and the server decides what they mean. Improving the classification is one edit, in one language, that applies to every surface at once, and it can be re-run over calls that are already recorded.

A native app is the exception, because it genuinely knows more than a label: iOS names its audio port and Android names its communication device. A client may therefore state a route explicitly, and the server prefers it when it recognises it — while keeping an unrecognised name verbatim, because a route we have never heard of is the only signal that our list is missing one.

The device-route state machine: permission, hot-swapping a microphone without dropping the call, and two rules that are easy to get wrong in opposite directions — keep the old microphone until the replacement is usable (stopping first turns every headset swap into a gap of silence, and a permanent one if the new device fails to open), and never publish two at once. Mute survives a route change, because re-acquiring a track is exactly the moment that state is silently lost.

Microphone selection never trusts a remembered device id indefinitely. A device chosen last week can be unplugged today, and asking for it exactly throws — which a caller experiences as "the microphone is broken". A remembered id is used only if it is still present, and the fallback says it was a fallback, because a silent substitution is how somebody ends up on their laptop speaker with no idea why.

⛔ Removes exports from the ./voice subpath published the same day. Strictly a breaking change, shipped as a minor deliberately: nothing depended on it yet, and the stable root export is untouched, so a major would have wrongly signalled an API-client break to the people who do use that. Once anything imports ./voice, a removal goes to a major.

v1.1.0

2026-09

Four helper files existed in three hand-ported copies across our own apps, and nothing compared them. Three were still logically identical (verified by diff, not assumed). Two had drifted: one had split into two variants, one of them missing a function outright, and another had become two genuinely different functions with different defaults. One copy had also dropped a no-store hint when asking the server which session to open — so a cached answer kept that console on the old lane after a rollout, and the change appeared to do nothing. One of the three had no tests at all.

What ships: protocol V2 playback tracking (what the listener has actually heard, not what was sent), local ducking (the browser turns her down on a credible onset and restores the volume if the server does not confirm a barge), 24 kHz stream resampling, the mute / stop-listening / heartbeat capture frames, and server-decided session routing with a per-surface allow-list — so a route response can never point a console at a socket it was not entitled to name.

Pure and side-effect free: no React, no socket, nothing touching the window at import time. It loads in a Next server component, a React Native bundle and a plain Node test alike.

The package gained DOM types, which it had never had — until now it was an API client that could not even name a MediaStream — and subpath exports, which it also had none of. Every published entry point is now verified to resolve AND to import before release, because an exports map is a promise written in JSON and nothing checks it: a map pointing at a file the build never emitted installs perfectly and fails at a consumer’s first import, which is the worst place to find out.

v1.0.0

2026-07

A typed client over axios with namespaces for CRM, agents, pages, vibe, billing and the rest; bearer auth; first-class TypeScript types. Node 18 and above.

All SDKs & librariesREST API referenceCLI release history
Release history — @solidnumber/sdk changelog | Solid# | SolidNumber