← All articlesEngineering · 10 February 2026 · 4 min read

A developer tour of the Waridi API

Speech synthesis, recognition, streaming, agents, cloning and dubbing, all from one API. A hands-on walk through the endpoints with curl, Python and Node.

Waridi Engineering

Waridi is in early access, and the API is where most builders will meet us first. This post is a quick tour: what each endpoint does, what a request looks like, and where the sharp edges are today.

One honest caveat up front. During early access, request and response shapes may still change. We will announce breaking changes in the changelog and give notice before we make them. Pin your SDK version and read release notes before upgrading.

The basics

Everything lives under one base URL:

https://api.waridi.io/v1

Requests are authenticated with an API key sent as a bearer token. You get keys from Waridi Studio once your early access account is active. Keep them on your server. Never ship a key inside a mobile app or a web page.

export WARIDI_API_KEY="wr_live_..."

There are two official SDKs. Both wrap the same HTTP API.

pip install waridi
npm install @waridi/sdk

Text to speech: POST /v1/tts

Waridi Sauti turns text into speech. Choose a voice and a model tier. sauti-standard is tuned for speed and cost. sauti-pro is tuned for expressiveness.

curl https://api.waridi.io/v1/tts \
  -H "Authorization: Bearer $WARIDI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sauti-standard",
    "voice": "amani",
    "language": "sw-TZ",
    "text": "Karibu! Oda yako itafika kesho asubuhi.",
    "format": "mp3"
  }' \
  --output karibu.mp3

The same call in Python:

from waridi import Waridi

client = Waridi()  # reads WARIDI_API_KEY from the environment

audio = client.tts.create(
    model="sauti-pro",
    voice="amani",
    language="sw-TZ",
    text="Habari za asubuhi. Malipo yako yamepokelewa.",
    format="wav",
)
audio.save("malipo.wav")

Numbers, dates and currency are normalised for you, so "TSh 25,000" is read the way a Tanzanian would say it. If you need control, you can pass hints. For example, you can read a value digit by digit, as you would for a phone number.

Speech to text: POST /v1/stt

Waridi Sikia transcribes recorded audio. The model is sikia-1. It is built for Swahili, regional accents and the Swahili–English mixing people use every day.

import { Waridi } from "@waridi/sdk";
import fs from "node:fs";

const waridi = new Waridi({ apiKey: process.env.WARIDI_API_KEY });

const result = await waridi.stt.create({
  model: "sikia-1",
  file: fs.createReadStream("call-recording.wav"),
  language: "sw",
  timestamps: "word",
});

console.log(result.text);
// "Nimejaribu ku-login mara tatu lakini haikubali password."

Notice the transcript keeps the English words the caller used. We do not force everything into one language. If the caller mixed, the transcript mixes too.

Streaming: wss://api.waridi.io/v1/stream

For anything live, from captions to agents, use the WebSocket stream. You send audio frames up and receive partial and final transcripts back. You can also send text and receive synthesised audio frames back.

import asyncio
from waridi import AsyncWaridi

async def main():
    client = AsyncWaridi()
    async with client.stream.connect(model="sikia-1", sample_rate=16000) as stream:
        async for event in stream.transcribe(microphone_frames()):
            if event.type == "partial":
                print("...", event.text)
            elif event.type == "final":
                print("✓", event.text)

asyncio.run(main())

Partials arrive while the person is still speaking, so your app can react before they finish. The streaming guide covers frame sizes, endpointing settings and reconnect behaviour.

Agents: POST /v1/agents

Waridi Agents combine Sikia, a language model and Sauti into a voice agent that can hold a phone conversation. You describe the agent, its voice and the tools it may call. We handle the turn-taking.

curl https://api.waridi.io/v1/agents \
  -H "Authorization: Bearer $WARIDI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "msaada-wa-wateja",
    "voice": "amani",
    "language": "sw-TZ",
    "instructions": "Wewe ni msaidizi wa huduma kwa wateja. Jibu kwa ufupi na kwa upole.",
    "tools": [{ "type": "webhook", "name": "check_balance", "url": "https://example.com/balance" }],
    "telephony": { "type": "sip" }
  }'

The response includes an agent ID and connection details for SIP or WebRTC. The voice agents docs and the telephony guide explain how to connect a phone number or a browser.

Voice cloning: POST /v1/voices/clone

Cloning creates a custom voice from recordings of a real person. This endpoint will not create a voice without verified consent from the voice owner. The request must reference a completed consent record, which the speaker gives themselves in Waridi Studio by reading a short statement in their own voice.

voice = client.voices.clone(
    name="sauti-ya-zuhura",
    consent_id="cns_...",  # created by the voice owner, not by you
    files=[open("sample-1.wav", "rb"), open("sample-2.wav", "rb")],
)
print(voice.id)

If the consent record is missing, expired or revoked, the request fails. That is deliberate. Read voice cloning before building anything on top of it.

Dubbing: POST /v1/dub

Waridi Dub takes a video or audio file and returns a localised version. Long jobs run asynchronously. You get a job ID back and can poll for status or receive a webhook.

const job = await waridi.dub.create({
  source_url: "https://example.com/episode-01.mp4",
  source_language: "en",
  target_language: "sw-TZ",
  review: true, // hold the output for human review before final export
});

Errors and limits

Errors come back as JSON with a stable code field. Branch on the code, not the message text. Early access accounts have conservative rate limits. Handle 429 responses with backoff rather than retrying in a tight loop. The errors and rate limits pages list the details.

Start building

The free sandbox gives you enough audio each month to try every endpoint above. The quickstart takes about ten minutes. When you are ready, request early access. We read every message, and early feedback is shaping what this API becomes. Karibu.

Keep reading

Private beta · Now onboarding

Kila sauti ina thamani.
Every voice matters.

Build with the voice stack made for African languages.

Request early accessRead the docs