Credufy Voice Documentation
Everything you need to integrate AI voice agents into your app. Credufy Voice handles the full pipeline — speech-to-text, LLM, text-to-speech — so you only write a few lines of code.
Quickstart
Get a voice agent running in under 5 minutes.
1. Create an account
Sign up at voice.credufy.com. You get 50 free minutes every month — no credit card required.
2. Create an API key
Go to API Keys in the dashboard. Click "New API key". Copy the key — it starts with cv_live_ and is shown exactly once.
3. Create an agent
POST https://voice.credufy.com/api/v1/agents
Authorization: Bearer cv_live_xxx
Content-Type: application/json
{
"name": "Amara",
"slug": "amara_trcn",
"language": "en-NG",
"voiceProvider": "cartesia",
"voiceId": "your_cartesia_voice_id",
"model": "claude-haiku-4-5",
"firstMessage": "Hello! I am Amara. Ready to study?",
"systemPrompt": "You are Amara, a warm TRCN exam
tutor. Keep responses short. Use Nigerian English."
}4. Start a session
POST https://voice.credufy.com/api/v1/sessions/create
Authorization: Bearer cv_live_xxx
Content-Type: application/json
{
"agentId": "your_agent_id",
"userId": "your_user_id"
}
// Response:
{
"sessionId": "...",
"transport": "livekit",
"livekit": {
"url": "wss://....livekit.cloud",
"roomName": "voice-...",
"token": "eyJ..."
},
"expiresAt": "2026-08-12T10:05:00.000Z",
"agent": {
"name": "Amara",
"firstMessage": "Hello! I am Amara..."
}
}5. Connect via SDK
npm install @credufy/voice-sdk
import { CredufyVoice } from '@credufy/voice-sdk'
// Your backend calls /v1/sessions/create and returns
// the WHOLE response to the browser. Pass it verbatim —
// the SDK picks the best transport it contains (WebRTC
// via LiveKit, with a WebSocket fallback).
const voice = new CredufyVoice({
session, // the /v1/sessions/create response, as-is
onReady: (s) => console.log('Session ready', s),
onTranscript: (t) => setCaption(t.text), // caller speech
onToken: (tok) => appendAgentText(tok), // agent reply text
onStatus: (st) => setStatus(st), // listening|thinking|speaking
onAudio: (a) => setSpeaking(a === 'playing'),
onEnd: (sum) => console.log('Ended', sum),
onError: (err) => console.error(err),
})
await voice.start()
// When done:
voice.stop()
// Interrupt the agent mid-speech:
voice.interrupt()Authentication
All API requests require a Bearer API key in the Authorization header.
Authorization: Bearer cv_live_xxxxxxxxxxxxxxxxxxxx
Keys starting with cv_live_ are production keys. Keys starting with cv_test_ are test keys that do not consume billable minutes. Create and manage keys in your dashboard under API Keys.
Your first agent
An agent is a configured voice persona. It has a name, a language, a voice (Cartesia for the lowest latency, or ElevenLabs), an LLM model, and a system prompt that defines its personality and knowledge.
Agent fields
{
"name": "string — display name e.g. 'Amara'",
"slug": "string — unique ID e.g. 'amara_trcn'",
"language": "en-NG | pcm | ha | yo | ig",
"voiceProvider": "cartesia | elevenlabs",
"voiceId": "string — provider voice ID",
"model": "claude-haiku-4-5 | claude-sonnet-4-6",
"firstMessage": "string — what agent says first",
"systemPrompt": "string — the agent's personality",
"isPublic": "boolean — appear in marketplace"
}Writing a good system prompt
The system prompt is the most important field. A few rules specific to voice:
// GOOD — short, conversational, specific "You are Amara, a TRCN exam tutor. Keep every response to 2-3 sentences. Use Nigerian English naturally. After explaining, ask one question." // BAD — too long, uses markdown, lists "You are Amara. Your responsibilities are: 1. Help students prepare for TRCN 2. Explain concepts clearly 3. Provide feedback..."
Sessions API
POST /v1/sessions/create
// Request
{
"agentId": "string (required)",
"userId": "string (required) — your user ID",
"metadata": "object (optional) — session context, see below"
}
// Response 201
{
"sessionId": "string",
"transport": "livekit",
"livekit": {
"url": "wss://....livekit.cloud",
"roomName": "string",
"token": "JWT (expires in 5 minutes)"
},
"wsUrl": "wss://... (legacy WebSocket fallback)",
"expiresAt": "ISO datetime",
"agent": {
"id": "string",
"name": "string",
"firstMessage": "string"
},
"usage": { "minutesUsed": 0, "minutesIncluded": 120 }
}Session metadata — context and overrides
Anything you put in metadata is injected into the agent as session context: the agent reads it as part of its instructions for that one call. Two keys are treated as per-session overrides — this is how you run fully dynamic agents (a different prompt per user, per role, per lesson) from a single agent config:
{
"agentId": "...",
"userId": "user_42",
"metadata": {
// Overrides — replace the agent's stored config
// for THIS session only:
"systemPromptOverride": "You are a mock interviewer
for a Senior PM role at TechCorp...",
"firstMessage": "Hi Ada — ready for your interview?",
// Enforced by the platform:
"maxSeconds": 600,
// Everything else becomes context the agent can use:
"roleTitle": "Senior Product Manager",
"questions": ["Tell me about...", "How would you..."]
}
}GET /v1/sessions/:id
// Response 200
{
"session": {
"id": "string",
"agentId": "string",
"externalUserId": "string",
"status": "active | ended | error",
"durationSec": "number | null",
"transcript": "array | null",
"costUsd": "number | null",
"latency": "object | null — per-turn EOU/LLM/TTS ms, p50/p95",
"startedAt": "ISO datetime",
"endedAt": "ISO datetime | null",
"region": "string",
"agent": { "name": "string", "slug": "string" }
}
}Agents API
GET /v1/agents List all agents POST /v1/agents Create agent GET /v1/agents/:id Get agent (includes systemPrompt) PATCH /v1/agents/:id Update agent DELETE /v1/agents/:id Soft-delete agent
API Keys
Manage the keys your app uses to authenticate with the Credufy Voice API. Keys are created and revoked from the dashboard — there is no public API endpoint for key management, since keys authenticate the API itself.
GET /v1/keys List keys (prefix only — full key never returned again)
POST /v1/keys Create a key — { name, environment: "live" | "test" }
DELETE /v1/keys/:id Revoke a keyUsage API
GET /v1/usage?from=2026-08-01&to=2026-08-07
// Response 200
{
"usage": {
"sessions": 42,
"minutes": 183.5,
"costUsd": 4.96,
"byDate": [{ "date": "2026-08-01",
"sessions": 8, "minutes": 34.2, ... }],
"byAgent": [{ "agentId": "...",
"sessions": 42, "minutes": 183.5, ... }]
}
}Webhooks
Credufy Voice fires events to your configured endpoints when sessions start and end.
Available events
session.started — fired when WebSocket connects session.ended — fired when session ends (has transcript) transcript.final — fired on each final transcript chunk
Payload
{
"event": "session.ended",
"createdAt": "ISO datetime",
"sessionId": "string",
"agentId": "string",
"userId": "string",
"durationSec": 120,
"costUsd": 0.054,
"region": "jnb"
}Verifying signatures
// Node.js
import crypto from 'crypto'
function verifyWebhook(
rawBody: string,
signature: string,
secret: string,
): boolean {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex')
return `sha256=${expected}` === signature
}
// In your route handler:
const sig = req.headers['x-credufy-sig-256']
const ok = verifyWebhook(rawBody, sig, webhookSecret)
if (!ok) return res.status(401).end()SDK Reference
Installation
npm install @credufy/voice-sdk
Configuration
const voice = new CredufyVoice({
// Preferred: the whole /v1/sessions/create response.
// The SDK selects WebRTC (LiveKit) when present and
// falls back to the WebSocket gateway otherwise.
session: CreateSessionResponse,
// Legacy alternative (gateway only):
wsUrl?: string,
// Callbacks (all optional)
onReady: (s: { sessionId: string; firstMessage: string }) => void
onTranscript: (t: { text: string; final: boolean }) => void // caller speech
onToken: (token: string) => void // agent reply text stream
onStatus: (s: 'connecting'|'listening'|'thinking'|'speaking'|'ended') => void
onAudio: (a: 'playing'|'idle') => void // agent audio state
onEnd: (summary: { sessionId?: string; duration?: number }) => void
onError: (error: Error | Event) => void
})Methods
voice.start() // Open mic, connect WS, start session voice.stop() // End session cleanly voice.interrupt() // Stop AI mid-speech, return to listening
Nigerian language support
Credufy Voice is the only voice AI platform with native support for Nigerian languages. Set the language field on your agent to control STT (speech recognition) and TTS (speech synthesis) behaviour.
"language": "en-NG" // Nigerian English (default) "language": "pcm" // Nigerian Pidgin English "language": "ha" // Hausa "language": "yo" // Yoruba "language": "ig" // Igbo
Code-switching
Real Nigerian conversations mix languages naturally. Set language to en-NG and include Pidgin or local phrases in your system prompt — the STT engine handles code-switching automatically.
// System prompt for natural Nigerian English "Speak in warm Nigerian English. Use Pidgin phrases naturally where they fit — 'oya', 'make we', 'no worry', 'e easy'. Do not force it. Sound like a real person." // The agent will naturally produce: // "Oya, let us look at Chapter 3. // This one no hard at all — make we start."