Changelog
SautiPBX is in closed beta and pre-1.0. The API and the Browser SDK may still change. This page tracks what has shipped so far.
2026-09-02: Assets
Section titled “2026-09-02: Assets”The portal has a new Assets page. Upload audio and play it with <Play asset="slug"/>, or
write a call-control document in the portal and use its hosted URL as a webhook. A missing asset
reports PLAY.0404. See Assets.
2026-08-16. New domain and SDK 0.2.0
Section titled “2026-08-16. New domain and SDK 0.2.0”The platform moved to sautipbx.com. The API is now served from https://api.sautipbx.com/api,
the portal from app.sautipbx.com, and browser-phone media from rtc.sautipbx.com. The previous
sauti-pbx.services.co.ke host has been retired and no longer resolves.
The browser SDK moved scope with it: @sautipbx/voice-sdk@0.2.0 replaces
@sauti-pbx/voice-sdk. Its default WSS endpoint now points at rtc.sautipbx.com, so a version
bump is all most integrations need.
2026-07-12. Call-control webhooks carry customPayload and endUser
Section titled “2026-07-12. Call-control webhooks carry customPayload and endUser”The call-control request now includes customPayload whenever the caller attached one (previously
echoed only on events), and. For a browser-phone outbound call. An endUser object identifying
the user who placed it (uuid, email, display_name, extension_number). Because From is the
account’s shared DID, endUser is how your handler attributes an outbound browser call to a
specific user.
2026-07-11. Per-purpose webhooks, and call-failure reasons
Section titled “2026-07-11. Per-purpose webhooks, and call-failure reasons”Webhooks are now configurable per purpose. voice_inbound, voice_outbound, status: both
account-wide (POST /account/webhooks takes a purpose) and per number (POST /numbers/configure
takes a webhook_urls map). The Number object now includes webhook_inbound (the resolved route
and its source).
A refused browser-phone call now returns a specific SIP status (e.g. 402 for insufficient
balance), and the SDK exports describeFailure() to turn a call’s failure reason into a readable
line.
2026-07-09. Standardised ICE config
Section titled “2026-07-09. Standardised ICE config”POST /phone-tokens/mint now returns a single iceServers array, matching what the SDK’s
authenticate() expects directly. No more remapping STUN/TURN fields by hand.
2026-07-08. Browser SDK published
Section titled “2026-07-08. Browser SDK published”The browser SDK was published to npm. Call, answer, hold, mute, DTMF, and device selection over WebRTC. See the Browser SDK guide.
2026-07-05. Realtime event stream and idempotent number acquisition
Section titled “2026-07-05. Realtime event stream and idempotent number acquisition”Added POST /stream/token for the WebSocket event feed. POST /numbers/acquire now accepts
Idempotency-Key.
2026-06-21. Outbound calling, billing controls, stable event codes
Section titled “2026-06-21. Outbound calling, billing controls, stable event codes”POST /calls/originate and POST /calls/hangup shipped, both idempotent. Per-account concurrency
and calls-per-second caps went live (see rate limits). Every event and terminal
outcome now carries a stable dotted code. See Events & codes.
2026-06-20. Call control verbs, V1 complete
Section titled “2026-06-20. Call control verbs, V1 complete”The full V1 verb vocabulary: Say, Play, Dial, Record, RecordSession, Redirect,
Pause, Hangup. Shipped. See
Call control (verbs).
2026-06-10. First REST endpoints
Section titled “2026-06-10. First REST endpoints”Calls, recordings, and the realtime stream became queryable over the REST API for the first time.