Billing read APIs available via user API key

Five billing read endpoints are now callable with your user API key (Authorization: Bearer <key>). Previously these were UI-only; use them to build credit-balance dashboards, ledger exports, or invoice pipelines outside the console.

EndpointPurpose
GET /payment/v1/credits/balancecurrent credit balance
GET /payment/v1/credits/ledgerpaginated ledger with filters
GET /payment/v1/credits/usage/breakdownspend split by scope
GET /payment/v1/invoicesrecent Stripe invoices
GET /payment/v1/invoices/{invoiceId}/pdfinvoice PDF URL

Python SDK 5.3.0 — unified speech-to-text namespace (breaking), voice cloning, Electron LLM, webhook update

smallestai==5.3.0 retires the legacy Waves STT methods and moves both file and live transcription under one client.waves.speech_to_text namespace. It also adds voice cloning, the Electron LLM completion client, and a webhook-update method. Constructor signature is unchanged: SmallestAI(api_key="...") keeps working.

Update your install

Webhooks docs: signature verification, standard variables, deletion gate

The Webhooks guide now documents behaviors previously only discoverable from the wire or from the platform source.

What’s new

  • Signature verification. New section names the X-Signature header, the HMAC-SHA256 (hex) algorithm, and the raw-body input rule, with runnable Python and Node samples that use constant-time comparison.
  • Standard variables in metadata.variables. The platform always injects call_id, user_number, agent_number, conversation_type, agent_gender, default_language, supported_languages, current_date, current_time, current_day, and timezone. Custom keys from the agent’s config stack alongside these.
  • Signing secret via API. GET /webhook and GET /webhook?webhookId=<id> return the secret in the decryptedSecretKey field, so integrations can fetch it without opening the dashboard.
  • Deletion behavior. DELETE /webhook/{id} returns 400 while the webhook is still assigned to any agent. Clear assignments via DELETE /agent/{agentId}/webhook-subscriptions, then retry the delete.
  • PATCH /webhook/{id} scope. Only endpoint, description, and headers can be updated in place; event subscriptions must be changed through the webhook-subscriptions endpoints or the agent editor.

smallestai SDK — STT moves to the unified /waves/v1/stt endpoints; voice cloning + Electron LLM added

The smallestai Python SDK is switching its Waves-side generator input from the legacy pulse-stt specs to the unified stt-* specs, and picking up two Waves surfaces that were sitting in the repo unwired.

What changes on the next SDK regen

  • STT. client.waves.transcribe(model="pulse"|"pulse-pro", ...) on POST /waves/v1/stt/. Supersedes the previous transcribe_pulse method, which hit POST /waves/v1/pulse/get_text and had no model parameter, so it could not reach Pulse Pro. Existing production traffic on the legacy endpoint keeps working.
  • STT streaming. Live transcription is now surfaced from the unified WSS /waves/v1/stt/live?model=pulse spec.
  • Voice cloning. client.waves.voice_cloning.create_voice_clone(...) and list_voice_clones(...) are generated from the voice-cloning spec.
  • Electron LLM. client.electron.complete(...) on POST /waves/v1/chat/completions with model="electron". OpenAI-compatible request/response shape — you can also point any OpenAI SDK at https://api.smallest.ai/waves/v1 unchanged.

DNC endpoint restored in the OpenAPI spec

GET /dnc is back in the Atoms OpenAPI spec. The endpoint has been serving production traffic uninterrupted; the regression was spec-side only.

Background

The endpoint was originally added to the spec in the 5.1.0 completeness pass, and the Python SDK was regenerated at that point — client.atoms.dnc.list(...) has been in every shipped SDK from 5.1.0 onwards. A follow-on spec PR shortly after accidentally dropped the /dnc path block from openapi.yaml, so the API reference page stopped rendering it and any tooling that consumes the spec started missing it.

Agent Versioning v2: branch and revision API (PRO-1789)

Agent Versioning moves from the linear drafts + versions model to a branch + draft + revision model. Every editable copy of an agent is now a branch; each branch has one open draft and its own revision history; exactly one branch per agent is live and serves production traffic.

New endpoints under /agent/{id}/branches and /agent/{id}/diff. Base tags: Agent Versioning - Branches and Agent Versioning - Revisions. Full list on the migration guide.

Agent Locking retired — superseded by Agent Versioning

The Agent Locking feature is retired. Its use case (protecting a production agent from accidental edits) is fully covered by Agent Versioning: keep production traffic on a published version, iterate on a draft, and only promote when you are ready to switch traffic over.

Docs changes

  • The platform/analytics/locking.mdx page has been removed.
  • The Monitor > Locking sidebar entry is gone. Monitor now matches the platform sidebar: Analytics + Evaluations.
  • Any inbound links to the old Locking URLs redirect to the Versioning page.

Voice Agents docs URL migration — atoms → voice-agents, atoms-platform → platform

The Voice Agents product now lives under /voice-agents/ on the docs site, replacing the older /atoms/ prefix. The main tab’s URL also drops the brand doubling: /atoms/atoms-platform/* becomes /voice-agents/platform/*. All other tabs move too. /atoms/developer-guide/* becomes /voice-agents/developer-guide/*. Same for api-reference, mcp, integrations, developer-tools, and changelog.

SIP termination URL — automatic normalization + corrected format guidance

Importing your own phone number (POST /product/import-phone-number) is now forgiving about the SIP Termination URL format. The expected value is your provider’s bare hostname or IP, optionally with a port (for example sip.telnyx.com or 203.0.113.10:5081) — but full SIP URIs are now accepted and automatically normalized: the sip:/sips: scheme, URI parameters (such as ;transport=udp), and any user info are stripped before the trunk is created. Previously a pasted SIP URI failed the import with a provider-side error.

Realtime Agent — register-call token flow + streamed transcripts

The Realtime Agent WebSocket reference now documents the recommended token flow for browser and client-side apps: call the new POST /conversation/register-call endpoint server-side to mint a short-lived, single-use access token (30-second TTL), then open the WebSocket with that token so your API key never reaches the browser. Connecting with a raw API key directly is still fully supported for server-side and trusted clients.

Realtime Agent — text-only chat mode

The Realtime Agent WebSocket now supports a text-only session: open the connection with ?mode=chat to run a conversation with no STT, TTS, or audio. The client sends user turns via input_text.send and receives the agent’s replies as transcript events. It works for any agent and is ideal for non-browser/server-side clients and automated prompt testing.

AgentDTO — 19 customer-facing fields added to the `GET /agent/{id}` response schema

The GET /atoms/v1/agent/{id} response was already returning these 19 fields at runtime (via the platform’s response transformer), but the OpenAPI AgentDTO schema did not include them — so the auto-generated Python SDK couldn’t surface them as typed attributes, and customers had to fall through to .dict() / raw-dict access.

Each field below was cross-referenced against the canonical schema — types, defaults, min/max bounds, and nested-object shapes were verified against the live API response.

Atoms API 5.1.0 completeness — 9 new endpoints + phone/KB SDK method names

Adds 9 customer-facing endpoints that the Atoms backend already serves but were not exposed in the OpenAPI spec, plus an x-fern-sdk-method-name cleanup pass on the phone-numbers and knowledge-base namespaces.

New endpoints

  • POST /agent/with-ai — create an agent from a natural-language brief.
  • GET /agent/{id}/call-logs — fetch conversation logs for an agent.
  • GET /agent/{id}/widget-config — read the chat-widget configuration for an agent.
  • PATCH /agent/{id}/widget-config — update the chat-widget configuration for an agent.
  • GET /agent/prompt-config — fetch prompt-config metadata (question definitions + labels) used by the agent builder.
  • GET /dnc — list DNC entries for the organization.
  • GET /account/get-account-details — get the authenticated user + organizations they belong to.
  • PATCH /account/update-org-name — update the organization’s display name.
  • GET /user/subscription — get the caller’s subscription, plan limits, and feature flags.
  • GET /campaign/{id}/logs/export — export a campaign’s call logs as a JSON file.

Atoms API — agents, analytics, call actions, concurrency, integrations, and disposition templates

New agent endpoints (7). New endpoints for creating, configuring, and operating agents:

EndpointDescription
POST /agentCreate a new agent by name. Versioning is enabled by default; use the drafts flow to set prompt, firstMessage, tools, or runtime config before going live. The legacy PATCH /workflow/{workflowId} path bypasses the version lifecycle and should be avoided.
POST /agent/with-aiGenerate an agent from either a free-text description or a structured questions[] array (mutually exclusive). Voice fields (emotiveToggle, voiceId, voiceModel) must all be present or all absent; emotiveToggle: true requires voiceModel: GPT_REALTIME. Returns 503 if the security-check service is unavailable.
GET /agent/prompt-configReturns the questionnaire for the Create-with-AI flow — questions[], exampleLabels[], and defaultLabel.
GET /agent/{id}/widget-configReturns the full web widget config: position, size, theme, colors, consent settings, public key, and allowlist.
PATCH /agent/{id}/widget-configPartial update of any widget config field, including display strings (ctaTitle, ctaSubtitle, chatPlaceholder, voiceEmptyMessage, etc.). Changing avatarUrl automatically removes the old CDN asset from S3.
POST /agent/{id}/avatar/presigned-urlReturns a pre-signed S3 PUT URL for avatar upload. Requires fileName, contentType (must start with image/), and fileSize (max 2 MB). URL expires after 300 seconds; response includes presignedUrl, cdnUrl, and key.
GET /agent/{id}/call-logsPaginated call logs for a specific agent. Query params: page (default 1), offset (default 10). Each entry includes callId, callStatus, callType, fromNumber, toNumber, createdAt, and callDuration (ms).

Python SDK 5.1.0 regen-prep — generator pin, spec field/type fixes, naming cleanup

Spec changes that prepare the next Python SDK regen so the auto-generated client (a) preserves the 4.4.7 sub-package import surface that customers still rely on and (b) picks up several missing or mistyped fields from the live API.

Generator pin

fern-python-sdk is pinned to 4.61.3 (the version 4.4.x was generated with). 5.12.12 combined with exclude_types_from_init_exports: true strips type exports from every package __init__, not just the top-level one — Fern’s own auto-generated wire tests do from smallestai.atoms.<ns> import <Type> and ImportError out. The pin is the proper fix until Fern ships a 5.x build that scopes the exclusion to top-level only.

Python SDK 5.1.0 — 10 new endpoints, verb-noun method renames, 19 typed agent fields

smallestai==5.1.0 adds 10 endpoints that were already serving traffic but missing from the SDK surface, cleans up auto-generated method names across the namespaces that still had verbose summary-derived names, and surfaces 19 customer-facing fields on the agent response that the auto-generated client previously couldn’t type. Constructor signature is unchanged from 5.0.0 — SmallestAI(api_key="...") keeps working.

Revert `fern-python-sdk` generator pin from 4.61.3 back to 5.12.12

PR #262 pinned the Python SDK generator from 5.12.12 down to 4.61.3 to address sub-package __init__ type-export stripping under exclude_types_from_init_exports: true. An empirical regen test against 4.61.3 showed that change was the wrong fix:

  • 4.61.3’s core/ is missing helpers (encode_path_param, _make_default_async_client) that our preserved / .fernignore’d files depend on — so the regen produces mypy failures it didn’t have on 5.12.12.
  • 4.61.3 also does not restore the sub-package type exports the downgrade was supposed to fix — the empty __init__ symptom reproduces on it.

Python SDK 5.0.0 — method renames, new `calls` namespace, conversations sub-operations

smallestai==5.0.0 ships a method-rename pass that aligns the auto-generated SDK with the canonical OpenAPI operation IDs. The constructor signature is unchanged from 4.4.7 — SmallestAI(api_key="...") keeps working — so the only client-side action is renaming the method calls below.

Method renames

Verbose Fern-generated names → canonical short names:

Atoms API — Conversation cancel, recording URL, retries endpoints

The Atoms OpenAPI spec now covers four customer-facing Conversations endpoints: POST /conversation/cancel (body-form), POST /conversation/{id}/cancel (path-form, only IN_QUEUE calls), GET /conversation/logs/{id}/recording/download-url (returns a pre-signed URL), and GET /conversation/logs/{callId}/retries (call-family retry attempts).

Spec only — no SDK regen yet. The new methods will land on the next Python SDK release that picks up these paths.

Atoms API — Knowledge Base ingestion endpoints

The Atoms OpenAPI spec now covers seven customer-facing Knowledge Base ingestion endpoints: presigned-URL request for file uploads, complete file upload, fetch sitemap URLs, scrape URLs into a KB, list scraped URLs, delete a scraped URL, and update KB metadata (name + description).

Spec only — no SDK regen yet. The new methods will land on the next Python SDK release that picks up these paths.