Start AI voice sessions, manage configuration, track usage, and receive webhooks — all with one API key. No SDKs required.
Base URL
https://api.voisero.info
All requests must use HTTPS.
Every request requires your API key in the Authorization header:
Authorization: Bearer vl_live_your_api_key_here
Set your default agent settings. These apply to every new session unless overridden per-request.
Get your current configuration.
curl https://api.voisero.info/v1/config \
-H "Authorization: Bearer YOUR_API_KEY"
{
"provider": "basic",
"prompt": "You are a helpful assistant.",
"language": "ro",
"maxDuration": 300,
"webhookUrl": null
}
Update any combination of settings.
| Field | Type | Description |
|---|---|---|
| provider | string | basic — low cost & low latency | advanced — superior quality & reasoning |
| prompt | string | System prompt — personality and instructions for the agent |
| language | string | Language hint (e.g. ro, en, de) |
| maxDuration | integer | Max call duration in seconds (10 – 3600) |
curl -X PUT https://api.voisero.info/v1/config \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"provider":"advanced","prompt":"You are a recruitment assistant.","maxDuration":180}'
A session is a single voice conversation. Only one active session at a time per API key.
Start a new voice session. Returns a WebSocket URL your frontend connects to.
All fields are optional — defaults come from your config.
| Field | Type | Description |
|---|---|---|
| provider | string | Override provider for this session |
| prompt | string | Override prompt for this session |
| language | string | Override language for this session |
| maxDuration | integer | Override max duration for this session |
curl -X POST https://api.voisero.info/v1/sessions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
{
"sessionId": "sess_1775550000_a1b2c3d4",
"provider": "basic",
"connectionType": "wss",
"joinUrl": "wss://provider.example/session/abc123...",
"maxDuration": 300,
"status": "active"
}
Get session status with live elapsed timer.
curl https://api.voisero.info/v1/sessions/SESSION_ID \
-H "Authorization: Bearer YOUR_API_KEY"
{
"sessionId": "sess_1775550000_a1b2c3d4",
"status": "active",
"elapsed": { "totalSeconds": 47, "display": "0m 47s" },
"maxDuration": 300,
"transcript": []
}
End an active session immediately.
curl -X DELETE https://api.voisero.info/v1/sessions/SESSION_ID \
-H "Authorization: Bearer YOUR_API_KEY"
No SDKs or packages to install. The joinUrl is a standard WebSocket URL that works in any browser.
1. Your backend calls POST /v1/sessions → gets joinUrl (wss://...)
2. Pass joinUrl to your frontend
3. Frontend opens WebSocket connection
4. User speaks → mic audio streams over WebSocket
5. AI responds with audio → plays in browser
6. Session auto-ends at maxDuration, or you call DELETE
// joinUrl from your backend (never expose API key in frontend)
const joinUrl = "wss://...";
const ws = new WebSocket(joinUrl);
ws.onopen = async () => {
// Get microphone access
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const ctx = new AudioContext({ sampleRate: 16000 });
const source = ctx.createMediaStreamSource(stream);
const processor = ctx.createScriptProcessor(4096, 1, 1);
processor.onaudioprocess = (e) => {
if (ws.readyState === WebSocket.OPEN) {
const pcm = e.inputBuffer.getChannelData(0);
const int16 = new Int16Array(pcm.length);
for (let i = 0; i < pcm.length; i++) {
int16[i] = Math.max(-32768, Math.min(32767, pcm[i] * 32768));
}
ws.send(int16.buffer);
}
};
source.connect(processor);
processor.connect(ctx.destination);
};
ws.onmessage = async (event) => {
if (event.data instanceof Blob) {
// Play AI audio response
const ctx = new AudioContext();
const buf = await ctx.decodeAudioData(await event.data.arrayBuffer());
const src = ctx.createBufferSource();
src.buffer = buf;
src.connect(ctx.destination);
src.start();
}
};
ws.onclose = () => console.log("Session ended");
┌──────────────┐ HTTPS ┌────────────────┐ HTTPS ┌─────────────┐
│ Browser │ ───────────────► │ Your Backend │ ───────────────► │ Voisero │
│ (user) │ ◄─────────────── │ (any language)│ ◄─────────────── │ API │
│ │ joinUrl │ │ joinUrl │ │
└──────┬───────┘ └────────────────┘ └─────────────┘
│
│ wss:// (direct audio)
▼
┌──────────────┐
│ Voice AI │
│ Provider │
└──────────────┘
Your backend holds the API key. The browser connects directly to the voice provider — audio never passes through your server.
Cumulative usage: total calls, total time, active sessions.
curl https://api.voisero.info/v1/usage \
-H "Authorization: Bearer YOUR_API_KEY"
{
"totalCalls": 24,
"totalTime": { "seconds": 3720, "display": "62m 0s" },
"activeSessions": 0
}
List all sessions (newest first) with duration.
| Query Param | Type | Description |
|---|---|---|
| limit | integer | Results per page (default 20, max 100) |
| offset | integer | Skip N results for pagination |
| status | string | Filter: active, ended, timeout |
curl "https://api.voisero.info/v1/sessions?limit=5&status=ended" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"sessions": [
{
"id": "sess_1775550000_a1b2c3d4",
"provider": "basic",
"status": "ended",
"reason": "manual",
"duration_seconds": 270,
"elapsed": { "totalSeconds": 270, "display": "4m 30s" }
}
],
"pagination": { "total": 24, "limit": 5, "offset": 0 }
}
Get notified when a session ends.
Register or update your webhook URL.
curl -X PUT https://api.voisero.info/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-server.com/webhook"}'
{
"event": "session.ended",
"sessionId": "sess_...",
"provider": "basic",
"reason": "manual",
"duration": 270,
"transcript": [...],
"timestamp": "2026-04-07T12:04:30Z"
}
Every webhook includes an X-Signature header — HMAC-SHA256 of the body using your webhookSecret:
const expected = crypto
.createHmac('sha256', webhookSecret)
.update(JSON.stringify(body))
.digest('hex');
const valid = (signature === expected);
Remove your webhook.
| Status | Meaning | What to do |
|---|---|---|
| 401 | Invalid or missing API key | Check your Authorization header |
| 400 | Bad request / invalid provider | Check request body fields |
| 404 | Session not found | Verify the session ID belongs to your account |
| 409 | Session already active | End current session first with DELETE |
| 500 | Server error | Retry or contact support |
All errors return JSON: {"error": "description"}