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 -d

JavaScript

// 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

HeaderDescription
x-vedika-voice-tierVoice SKU/tier: vedika-standard, vedika-native, or vedika-jarvis (plus premium-indic SKUs). Omit to auto-select from detected language.
x-vedika-voice-languageLanguage hint for transcription/synthesis (e.g. en, hi, ta). Lowercased.
x-vedika-birth-detailsJSON 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-personaOptional persona id (one of 18 catalog personas). Unknown id falls back to the tier default persona.
Idempotency-KeyClient-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