v0.3 · private beta · 3 live providers
Drop a real-time AI customer-service character into any website. One signed callback. Your character reads and writes your data — and if a model provider goes down, we fail over to another automatically, so you never have to think about it.
what you skip
Building this yourself means owning a streaming media pipeline and a tool RPC protocol. We did it once, so you don't have to.
×// Open Runway WS, manage reconnect, backoff…
const ws = new WebSocket(`wss://api.runway.com/v1/sessions/${id}`)
ws.addEventListener('message', (e) => {
const { jsonrpc, method, params, id } = JSON.parse(e.data)
if (method === 'tool_call') {
const handler = TOOL_HANDLERS[params.name]
const result = await handler(params.args)
ws.send(JSON.stringify({ jsonrpc: '2.0', id, result }))
}
})
×// Pipe browser audio to Runway, return generated audio
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
const ctx = new AudioContext({ sampleRate: 16000 })
const processor = ctx.createScriptProcessor(4096, 1, 1)
processor.onaudioprocess = (e) => {
const pcm = float32ToInt16(e.inputBuffer.getChannelData(0))
ws.send(pcm)
}
×// Decode video frames + sync to audio playback…
const decoder = new VideoDecoder({ output, error })
const playoutClock = new MediaTimingClock(audioCtx)
+import { createBubblioSession } from '@bubblio/server'
+import { BubblioWidget } from '@bubblio/widget'
// 1. Server route — pass a callback URL.
const session = await createBubblioSession({
bubblioApiKey: process.env.BUBBLIO_API_KEY,
characterId: 'char_aria',
tools: [{
name: 'get_orders',
callbackUrl: 'https://you.com/api/tools',
}],
})
// 2. Frontend — drop in the widget.
<BubblioWidget config={{ characterId: 'char_aria', serverUrl: '/api/bubblio/session' }} />
architecture
Bubblio holds the provider keys and picks a healthy one at connect time. When the character calls a tool, we POST a signed payload to your server. You return JSON. We log every call for billing and observability. You never touch a WebSocket — or a model outage.
integration
Bubblio manages the Runway WebSocket, RPC protocol, and session lifecycle. Define tools as callback URLs — we sign every request, you return JSON.
// POST https://you.com/api/bubblio/tools// X-Bubblio-Signature: sha256=8a1f...{"sessionId": "sess_b8e4f2a01c","customerId": "cust_acme_inc","tool": "get_orders","args": {"orderId": "ORD-4291"},"context": {"userId": "u_19a7","locale": "en-US"}}
resilience
Realtime avatar providers have outages. Bubblio treats them as interchangeable: pick a preferred model or let us choose, and if it is unavailable when a visitor connects, we fail over to the next healthy one automatically — before the call even starts.
pricing
Free for approved teams during the private beta. Per-minute at general availability — one number you can predict, never a per-seat tax.
Request access today — we approve new teams daily. Explore the dashboard and mint API keys while you wait; generate characters and go live the moment you're approved.