Voice guide
Voice takes audio in and returns audio out. You send a recording of the question; you get a spoken answer and its details in response headers.
1. Check your plan and the tiers
Voice is for Business, Enterprise and Flagship plans. There is no keyless sandbox call for it: every call uses your wallet. Before you build, read GET /api/v1/voice/pricing with your key. It returns the plans that can use Voice (access.eligiblePlans), the tiers, the languages, the rate limits and what a query costs. For per-minute rates and plan details see the Voice reference.
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $VEDIKA_API_KEY" \
"https://api.vedika.io/api/v1/voice/pricing"2. Send a question, get an answer
Post a recording of the question to POST /api/v1/voice as the request body, with Content-Type: audio/wav. The examples read question.wav and save the spoken answer as answer.wav. Keep the key on your server and read it from the environment, as in the authentication notes.
curl
curl --fail-with-body --silent --show-error -X POST \
-H "Authorization: Bearer $VEDIKA_API_KEY" \
-H "Content-Type: audio/wav" \
-H "x-vedika-voice-tier: vedika-native" \
-H "x-vedika-voice-language: en" \
-H 'x-vedika-birth-details: {"datetime":"1990-05-15T10:30:00","latitude":19.07,"longitude":72.87,"timezone":"Asia/Kolkata"}' \
-H "Idempotency-Key: question-0001" \
--data-binary @question.wav \
-D headers.txt -o answer.wav \
"https://api.vedika.io/api/v1/voice"
# answer.wav holds JSON instead of audio if speech synthesis failed.
# Read the details: language, tier, transcription and billing.
grep -i '^x-vedika-voice-meta' headers.txt | cut -d' ' -f2 | tr -d '\r' | base64 -dJavaScript
// Node.js 18 or later. Save as voice.mjs and run: node voice.mjs
import { readFile, writeFile } from 'node:fs/promises';
const response = await fetch('https://api.vedika.io/api/v1/voice', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + process.env.VEDIKA_API_KEY,
'Content-Type': 'audio/wav',
'x-vedika-voice-tier': 'vedika-native',
'x-vedika-voice-language': 'en',
'x-vedika-birth-details': '{"datetime":"1990-05-15T10:30:00","latitude":19.07,"longitude":72.87,"timezone":"Asia/Kolkata"}',
'Idempotency-Key': 'question-0001',
},
body: await readFile('question.wav'),
});
const type = response.headers.get('content-type') ?? '';
if (!response.ok) throw new Error((await response.text()) || response.status);
if (type.includes('application/json')) {
// Speech synthesis failed: you get the answer as text instead of audio.
console.log((await response.json()).response);
} else {
await writeFile('answer.wav', Buffer.from(await response.arrayBuffer()));
const meta = JSON.parse(Buffer.from(response.headers.get('x-vedika-voice-meta'), 'base64').toString());
console.log(meta.transcription, meta.billing);
}Python
# Python 3, standard library only.
import base64, json, os, urllib.request
with open("question.wav", "rb") as f:
audio = f.read()
request = urllib.request.Request(
"https://api.vedika.io/api/v1/voice",
method="POST",
data=audio,
headers={
"Authorization": "Bearer " + os.environ["VEDIKA_API_KEY"],
"Content-Type": "audio/wav",
"x-vedika-voice-tier": "vedika-native",
"x-vedika-voice-language": "en",
"x-vedika-birth-details": '{"datetime":"1990-05-15T10:30:00","latitude":19.07,"longitude":72.87,"timezone":"Asia/Kolkata"}',
"Idempotency-Key": "question-0001",
},
)
with urllib.request.urlopen(request) as response:
body = response.read()
if "application/json" in response.headers.get("Content-Type", ""):
# Speech synthesis failed: you get the answer as text instead of audio.
print(json.loads(body)["response"])
else:
with open("answer.wav", "wb") as out:
out.write(body)
meta = json.loads(base64.b64decode(response.headers["x-vedika-voice-meta"]))
print(meta["transcription"], meta["billing"])What comes back
A successful call is HTTP 200 with the audio as the body. Check the Content-Type header for the format. The details are in headers: x-vedika-voice-tier, x-vedika-voice-lang, x-vedika-voice-duration, x-vedika-voice-cost and x-vedika-voice-meta. The last one is base64-encoded JSON with the language, the tier, the transcription of your question and the billing block. The tier header reports the tier that served the call, which can carry a longer name than the one you asked for. If speech synthesis fails the call still returns 200, with JSON that has the answer as text in response and audio set to null.
Request headers
| Header | Description |
|---|---|
x-vedika-voice-tier | Voice SKU/tier: vedika-standard, vedika-native, or vedika-jarvis (plus premium-indic SKUs). Omit to auto-select from detected language. |
x-vedika-voice-language | Language hint for transcription/synthesis (e.g. en, hi, ta). Lowercased. |
x-vedika-birth-details | JSON birth details for chart-grounded answers, e.g. {"datetime":"1990-05-15T10:30:00","latitude":19.07,"longitude":72.87,"timezone":"Asia/Kolkata"}. |
x-vedika-voice-persona | Optional persona id (one of 18 catalog personas). Unknown id falls back to the tier default persona. |
Idempotency-Key | Client-stable key folded with an audio fingerprint so a retry on the same audio reuses the same wallet charge instead of double-billing. |
Errors and limits
Check the HTTP status before reading the body. A 401 means check your key; an error about the plan means your plan does not include Voice (see step 1). Fix invalid input before retrying, and on a 429 honour Retry-After and back off. Send an Idempotency-Key so a retry on the same audio is not billed twice, and use a new key for each new question. Details are in Errors & limits.
Next steps
- Voice reference: rates and plan access.
- Voice product page
- API reference: every operation with inputs and recorded responses.