Realtime Voice API

Connect AI to real phone calls

Get an audio stream via WebSocket from any call — inbound or outbound — and connect it to OpenAI, Claude, ElevenLabs, or your own model.

How does it work?

  1. 1

    Phone

    Get a number from us

  2. 2

    46elks

    We handle all the technical work to deliver the call as a WebSocket stream

  3. 3

    Your app

    You receive the audio stream and decide what to do with it

  4. 4

    AI / Tools

    Choose any AI you want. Build your own tools and use them in the call.

Try it now.

Try one of our demos and see what's possible with AI in real phone calls.

Talk to our documentation

Ask questions about the 46elks API directly over the phone. Our assistant knows it inside out.

+46 76-686 29 49

You own the entire chain

No black box. You get the audio stream and send back audio. In between you do exactly what you want — transcribe, analyze, generate responses, call your tools.

Works with any AI you choose

OpenAI Realtime, Claude, ElevenLabs, Whisper, your own model — doesn't matter. The only requirement is that your app receives and sends audio.

Easy to build on

A complete AI voice assistant in ~60 lines of Python. No SIP. No Asterisk. Just a WebSocket.

WebSocket URL:
wss://my.server.io/audio
async def openai_bridge(elks_ws, openai_ws):
    # Get the call metadata from the hello message
    hello = json.loads(await elks_ws.recv())
    print(f"Received {hello['to']} <- {hello['from']} ({hello['callid']})")

    # Tell the API the format we want to receive audio in
    await elks_ws.send(json.dumps({
        "t": "listening",
        "format": "pcm_24000"
    }))

    # Tell the API the format we'll be sending audio in
    await elks_ws.send(json.dumps({
        "t": "sending",
        "format": "pcm_24000"
    }))
Show more...
    elks_recv = asyncio.create_task(elks_ws.recv())
    openai_recv = asyncio.create_task(openai_ws.recv())

    while True:
        receivers = [elks_recv, openai_recv]
        done, _ = await asyncio.wait(receivers, return_when=asyncio.FIRST_COMPLETED)

        if elks_recv in done:
            raw = elks_recv.result()
            elks_recv = asyncio.create_task(elks_ws.recv())
            msg = json.loads(raw)

            if msg["t"] == "audio":
                # Forward the audio to OpenAI
                await openai_ws.send(json.dumps({
                    "type": "input_audio_buffer.append",
                    "audio": msg["data"],
                }))

            elif msg["t"] == "bye":
                # The call has ended
                await openai_ws.send(json.dumps({"type": "response.cancel"}))
                print("Call ended:", msg["message"])
                break

        if openai_recv in done:
            raw = openai_recv.result()
            openai_recv = asyncio.create_task(openai_ws.recv())
            msg = json.loads(raw)

            if msg["type"] == "input_audio_buffer.speech_started":
                # Cancel AI response and interrupt audio
                await openai_ws.send(json.dumps({"type": "response.cancel"}))
                await elks_ws.send(json.dumps({"t": "interrupt"}))

            elif msg["type"] == "response.audio.delta":
                # Forward the audio to 46elks
                await elks_ws.send(json.dumps({
                    "t": "audio",
                    "data": msg["delta"],
                }))

            elif msg["type"] in ("response.audio.done", "response.done", "response.cancelled"):
                # Stop ignoring audio
                await elks_ws.send(json.dumps({
                    "t": "sending",
                    "format": "pcm_24000"
                }))

This is a working AI voice assistant. ~60 lines. Swap out OpenAI for any model you want.

See full example with tool-calling ->

What you can build

AI voice assistant

An AI that answers calls, speaks naturally, and takes actions — books appointments, checks orders, answers questions. With tool-calling it becomes an agent, not just a voice.

AI that calls out

Your app initiates a call and connects an AI agent. Outbound sales, reminders, follow-ups.

Real-time transcription

Transcribe live. Flag keywords. Run sentiment analysis while the call is in progress. Surface relevant information in real time.

System integration

CRM updates, ticket management, logging — automatic, in real time. The phone becomes an interface to your systems.

Under the hood

Protocol

WebSocket (wss://) with full duplex.

Audio format

PCM 8/16/24 kHz, G.711, G.722, Opus, MP3, WAV.

Direction

Inbound and outbound calls.

Streams

Separate streams for caller and agent, individually controllable.

Control

bye ends the call gracefully. interrupt clears the buffer immediately.

Integration

JSON messages, base64-encoded audio.

Pricing

Realtime Voice is included with 46elks virtual numbers

0.15 SEK/min to connect a call to WebSocket
3 concurrent calls per number Talk to us if you need more

See full price list →

Get in touch

If you’re wondering how you can use 46elks for a project,
don’t hesitate to contact us.