Skip to main content

SmallestAI Python SDK

pypi

pip install smallestai gives you one package with two surfaces, plus a CLI:

  • Atoms — build, configure, deploy, and phone-call voice AI agents (client.atoms).
  • Models — low-latency text-to-speech and speech-to-text, sync/async and streaming (client.waves; smallestai models in the CLI).
  • CLI — smallestai for managing agents, deploying agent-crew code, and running speech models.
pip install smallestai

Table of Contents

Quickstart: create an agent and call it

from smallestai import SmallestAI

client = SmallestAI(api_key="<your-api-key>")

# create an agent (the response .data is the new agent id)
agent_id = client.atoms.agents.create_agent(name="my-first-agent").data

# place an outbound call (from_product_id is a rented number's product id)
client.atoms.calls.start_outbound_call(
    agent_id=agent_id,
    phone_number="+1XXXXXXXXXX",
    from_product_id="<rented-number-product-id>",
)

Text-to-speech and speech-to-text (Models)

synthesize_tts streams audio bytes. List available voices with client.waves.get_voices().

from smallestai import SmallestAI

client = SmallestAI(api_key="<your-api-key>")

with open("out.wav", "wb") as f:
    for chunk in client.waves.synthesize_tts(text="Hello from Smallest.", voice_id="<voice-id>"):
        f.write(chunk)

Streaming speech-to-text helper:

from smallestai.waves.helpers import stream_speech_to_text

for event in stream_speech_to_text(client, language="en"):
    print(event)

Agent crew: your own LLM in the middle

An agent crew runs the LLM turn on a model you choose while Smallest handles STT and TTS. Point the crew node's OpenAIClient at any OpenAI-compatible endpoint (a hosted API, or a local model via Ollama):

from smallestai.atoms.crew.nodes import OutputCrewNode
from smallestai.atoms.crew.clients.openai import OpenAIClient


class Assistant(OutputCrewNode):
    def __init__(self):
        super().__init__(name="assistant")
        self.llm = OpenAIClient(
            model="claude-haiku-4-5",
            api_key="<your-llm-key>",
            base_url="https://api.anthropic.com/v1/",  # or http://localhost:11434/v1 for Ollama
        )

    async def generate_response(self):
        async for chunk in await self.llm.chat(self.context.messages, stream=True):
            if chunk.content:
                yield chunk.content

Conversation history is handled for you: every turn is appended to self.context, and you send self.context.messages to the model each turn.

Deploy it with the CLI:

smallestai auth login
smallestai agent-crew init --agent-id <agent-id>
smallestai agent-crew deploy --entry-point server.py
smallestai agent-crew builds        # pick the build -> Make Live

A flat directory (server.py + requirements.txt at the root) is the simplest layout; a src/ layout with a pyproject.toml also works (declare all runtime deps in the pyproject).

Reusable tools and secrets

Build a tool once in your org's registry and reference it from any agent, and store API keys in a write-only secrets vault. Tools and Secrets wrap the /tool and /secret endpoints; both default to the SMALLEST_API_KEY environment variable.

from smallestai.atoms.helpers import Tools, Secrets

tools = Tools()  # or Tools(api_key="sk_...")
created = tools.create(
    {
        "name": "get_order_status",
        "description": "Look up an order status by id",
        "type": "api_call",
        "method": "GET",
        "url": "https://api.example.com/orders",
        "parameters": [{"name": "order_id", "type": "text", "description": "order id", "required": True}],
    }
)
tool_id = created["data"]["toolId"]
tools.list()
tools.duplicate(tool_id)
tools.delete(tool_id)

# secrets are write-only: the value is encrypted at rest and never returned
secrets = Secrets()
secrets.create(name="example_api_key", value="...")
secrets.list()  # names and metadata only

Reference a saved tool from an agent with toolRefs: ["<toolId>"] on its single-prompt config. The tool must exist in the registry first, or the reference is dropped when the agent runs. Referencing a tool makes it available; the agent only calls it when its prompt says to.

CLI

smallestai auth login                        # store your API key
smallestai agents list                       # list, get, call, and manage agents
smallestai calls list                        # inspect call logs, transcripts, recordings
smallestai calls events <call-id>            # stream a live call's events (transcript, latency, tools)
smallestai calls transcript <call-id> -f     # stream the transcript live
smallestai models                            # text-to-speech, speech-to-text, voices
smallestai agent-crew deploy ...             # package and deploy crew code
smallestai agent-crew logs [build-id]        # stream a build's compile + deploy logs
smallestai agent-crew chat                   # talk to a running crew locally

The speech command group is now models (text-to-speech, speech-to-text, voices); waves still works as a hidden, back-compatible alias.

Async client

The SDK exports an async client with the same surface:

import asyncio
from smallestai import AsyncSmallestAI


async def main():
    client = AsyncSmallestAI(api_key="<your-api-key>")
    agents = await client.atoms.agents.list_agents()
    print(agents.data)


asyncio.run(main())

Environments

from smallestai import SmallestAI
from smallestai.environment import SmallestAIEnvironment

client = SmallestAI(environment=SmallestAIEnvironment.PRODUCTION)

Exception handling

from smallestai.core.api_error import ApiError

try:
    client.atoms.agents.get_agent(id="does-not-exist")
except ApiError as e:
    print(e.status_code, e.body)

Streaming and websockets

The speech models support real-time, low-latency streaming over websockets. stream() returns a context manager; iterate it to process messages as they arrive.

from smallestai import SmallestAI

client = SmallestAI(api_key="<your-api-key>")

# real-time speech-to-text
with client.waves.speech_to_text.stream() as socket:
    for message in socket:
        print(message)

The async client mirrors this with async with / async for. Text-to-speech streams too: synthesize_tts(...) yields audio bytes as they are generated (see above).

Advanced

Access raw response data

Use .with_raw_response to get the response headers and status alongside the parsed data.

response = client.atoms.agents.with_raw_response.get_agent(id="<agent-id>")
print(response.headers)  # response headers
print(response.status_code)  # status code
print(response.data)  # parsed object

Retries

The SDK retries retryable requests with exponential backoff (default 2). Configure it at the client or per request.

client = SmallestAI(api_key="<your-api-key>", max_retries=3)

# or per request
client.atoms.agents.get_agent(id="<agent-id>", request_options={"max_retries": 1})

Timeouts

Defaults to 60 seconds. Configure at the client or per request.

client = SmallestAI(api_key="<your-api-key>", timeout=20.0)

# or per request
client.atoms.agents.get_agent(id="<agent-id>", request_options={"timeout_in_seconds": 5})

Custom client

Override the httpx client for proxies, custom transports, and similar.

import httpx
from smallestai import SmallestAI

client = SmallestAI(
    api_key="<your-api-key>",
    httpx_client=httpx.Client(
        proxy="http://my.test.proxy.example.com",
        transport=httpx.HTTPTransport(local_address="0.0.0.0"),
    ),
)

Reference and docs

Telemetry

The SDK sends anonymous, aggregated usage telemetry (which CLI commands run, deploy outcomes) so we can see what to improve. It never includes personal data or secrets: no API keys, agent ids, prompts, transcripts, phone numbers, file paths, or error messages. Only the event name, SDK / Python / OS version, and a random anonymous install id. It is fire-and-forget and never blocks your program.

Opt out any time:

export SMALLESTAI_TELEMETRY=0    # or DO_NOT_TRACK=1

Contributing

Most of src/ is generated from an API spec and gets overwritten on regeneration, so hand edits there will not stick. If you spot a bug or a gap, open an issue.

Metadata

Release files for smallestai 5.12.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for smallestai 5.12.3
File Size Uploaded Provenance Actions
smallestai-5.12.3.tar.gz 510.2 kB Without provenance Details for smallestai-5.12.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for smallestai 5.12.3
File Interpreter ABI Platform Actions
smallestai-5.12.3-py3-none-any.whl Python 3 none any Details for smallestai-5.12.3-py3-none-any.whl

Total release size: 1.6 MB

Release files / smallestai-5.12.3.tar.gz

Download URL smallestai-5.12.3.tar.gz
Size 510.2 kB
Tags Source
SHA-256 checksum
How to use checksums
4f40931a8796353e8ebf24e234f80734c2139c0d5521e0ec62e3096eb4387965
BLAKE2b-256 checksum
How to use checksums
dec6ce0ffd9bec18fbb80099c2af56694e6314082709730ecbb983b1ac676eeb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.5.1 CPython/3.9.25 Linux/6.17.0-1022-azure

Release files / smallestai-5.12.3-py3-none-any.whl

Download URL smallestai-5.12.3-py3-none-any.whl
Size 1.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
66a6056aeff1360f5ca94deb226bac09275280d28d6232d6d3eca8af455f525c
BLAKE2b-256 checksum
How to use checksums
3f1135dcd981480210d78a0391cfdff2e41883f1482e98292b679dd0ee27436a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.5.1 CPython/3.9.25 Linux/6.17.0-1022-azure

Security for smallestai 5.12.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

5.12.3 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page