Live previewVocaic Agent API

Your agent writes once. Everyone understands it.

Send one message with a list of people and how each one wants to receive it. Vocaic translates, picks the voice and the English accent, and returns a playable MP3 for voice recipients. Every reply comes back as clean English text with its language and mode.

Preview: limits apply, no uptime guarantee yet.

Quick start

One call to reach everyone

Create a key in the console, then send a deliver request. The same body works from the command line, JavaScript or Python.

curl
# 1. Create a key in the console below, then:
curl https://vocaic.example/api/v1/deliver \
  -H "Authorization: Bearer vk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Your appointment moved to 3:40 pm. Reply yes to confirm.",
    "language": "en",
    "recipients": [
      { "id": "wei",    "language": "en", "accent": "zh-CN", "mode": "voice" },
      { "id": "priya",  "language": "hi", "mode": "text" },
      { "id": "oliver", "language": "en", "accent": "en-GB", "mode": "voice" }
    ]
  }'
JavaScript (fetch)
const res = await fetch("https://vocaic.example/api/v1/deliver", {
  method: "POST",
  headers: {
    "Authorization": "Bearer vk_live_your_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    message: "Your appointment moved to 3:40 pm. Reply yes to confirm.",
    language: "en",
    recipients: [
      { id: "wei", language: "en", accent: "zh-CN", mode: "voice" },
      { id: "priya", language: "hi", mode: "text" },
    ],
  }),
});
const { deliveries } = await res.json();
// deliveries[0].audioUrl is a playable MP3 for voice recipients.
Python (requests)
import requests

res = requests.post(
    "https://vocaic.example/api/v1/deliver",
    headers={"Authorization": "Bearer vk_live_your_key"},
    json={
        "message": "Your appointment moved to 3:40 pm. Reply yes to confirm.",
        "language": "en",
        "recipients": [
            {"id": "wei", "language": "en", "accent": "zh-CN", "mode": "voice"},
            {"id": "priya", "language": "hi", "mode": "text"},
        ],
    },
)
deliveries = res.json()["deliveries"]
Receive a reply as clean English
curl https://vocaic.example/api/v1/replies \
  -H "Authorization: Bearer vk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "from": "priya", "mode": "text", "language": "hi-IN", "text": "हाँ, मैं पुष्टि करता हूँ।" }'
# -> { "ok": true, "text": "Yes, I confirm.", "language": "hi-IN", "mode": "text", "translated": true }
Text to speech, get an MP3
# Synthesize spoken English in a chosen accent, get an MP3 back:
curl https://vocaic.example/api/v1/speech \
  -H "Authorization: Bearer vk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "text": "Your table is ready. Please come to the front desk.", "accent": "en-IN" }' \
  --output hello.mp3
# Give one of: voiceId (en-GB-Sonia), accent (british, en-IN, zh-CN), or language (ja-JP).
Translate text
const res = await fetch("https://vocaic.example/api/v1/translate", {
  method: "POST",
  headers: {
    "Authorization": "Bearer vk_live_your_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ text: "Welcome, your order is on its way.", target: "es-ES" }),
});
const { text, translated } = await res.json();
// text: "Bienvenido, su pedido esta en camino."  (source defaults to English)
Check your usage
curl https://vocaic.example/api/v1/usage \
  -H "Authorization: Bearer vk_live_your_key"
# -> { "ok": true, "usage": { "day": "2026-10-03", "used": 42, "remaining": 4958,
#        "limit": 5000, "perMinute": 60, "recipientsPerCall": 10, "resetsAt": "..." } }
Live previewConsole

Try it here

This console calls the real API on this site. Create a key, edit the clinic example, send it, play each voice delivery, then send a reply and read the clean English.

Create a key

Send a delivery

Send a reply, get clean English

Get events by webhook

Register a URL to receive a signed POST whenever a delivery or a reply is created. Each request carries a Vocaic-Signature header you verify with your signing secret. Failed deliveries are retried with backoff. This works with a Zapier, Make or n8n catch hook URL.

Events

Speech, translate and usage

Reference

Endpoints

  • POST/api/v1/keysSame-origin

    Create a developer key. Same-origin only (the console below). The key is shown once; store it safely.

    • Body: { name }
    • Returns: { ok, key, id, createdAt, limits }
    • Limit: 5 keys per IP per day
  • GET/api/v1/voicesPublic

    List English accent groups, accented English voices, and conversation languages with their default voices.

    • No body
    • Returns: { ok, englishAccentGroups, accentedEnglish, conversationLanguages }
  • POST/api/v1/speechBearer key

    Synthesize spoken English (or a conversation language) and return the audio directly as audio/mpeg.

    • Body: { text (<= 1000 chars), voiceId? | accent? | language? }
    • Returns: audio/mpeg (the Vocaic-Voice header names the voice used)
  • POST/api/v1/translateBearer key

    Translate text between languages through Vocaic's own cached translation. Source defaults to English.

    • Body: { text (<= 1000 chars), source?, target }
    • Returns: { ok, text, source, target, translated }
  • GET/api/v1/usageBearer key

    The calling key's usage for the current UTC day plus the limits that apply. No text, key or IP is returned.

    • No body
    • Returns: { ok, key: { id, name }, usage: { day, used, remaining, limit, perMinute, recipientsPerCall, resetsAt } }
  • POST/api/v1/deliverBearer key

    Deliver one message to 1 to 10 people, each in their mode, language and accent. Voice recipients get a playable MP3.

    • Body: { message (<= 1000 chars), language, recipients: [{ id, language, accent?, voiceId?, mode }] }
    • Returns: { ok, requestId, deliveries: [{ id, mode, language, accent?, voice, text, translated, audioUrl?, audioSeconds? }] }
  • GET/api/v1/audio/<id>None

    Fetch a delivered MP3. Unguessable id, no auth, kept 24 hours. Supports byte ranges.

    • Returns: audio/mpeg
    • 404 after it expires
  • POST/api/v1/repliesBearer key

    Turn a person's reply back into clean English. Text is translated; English audio (base64, <= 2 MB) is transcribed.

    • Body: { from, mode, language, accent?, text? , audio? (base64 MP3/WAV/WebM) }
    • Returns: { ok, from, text, original, language, accent?, mode, translated }
  • POST/api/v1/webhooksBearer key

    Register a URL and the events you want. The signing secret is returned once; store it. GET lists this key's webhooks.

    • Body: { url, events: ['delivery.created','reply.created'], description? }
    • Returns: { ok, webhook, signingSecret }
  • POST/api/v1/webhooks/<id>/testBearer key

    Send a signed sample event to the registered URL now, so you can confirm your receiver verifies the signature.

    • Body: { event? }
    • Returns: { ok, delivered, statusCode, error? }
  • GET/api/v1/webhooks/<id>Bearer key

    The webhook plus its recent delivery attempts (status, attempts, last code). DELETE removes the webhook.

    • Returns: { ok, webhook, deliveries }
    • Header on every event: Vocaic-Signature: t=..., v1=...

Errors

  • 400Bad input (missing fields, bad JSON, unsupported language).
  • 401Missing or invalid Bearer key.
  • 413The body or an audio clip is too large.
  • 429A rate limit was hit. Check the Retry-After header.
  • 503Speech or translation is temporarily unavailable.

Limits

  • 60 requests per minute per key.
  • 5000 requests per day per key.
  • Up to 10 recipients per deliver call.
  • Delivered MP3s are kept for 24 hours, then deleted.
Webhooks

Receive events, signed

Register a URL and the events you want. Vocaic sends a signed POST on delivery.created and reply.created, retries failures with backoff, and gives you a test-send button in the console above. The signature is an HMAC-SHA256 you verify with your signing secret. Point it at a Zapier, Make or n8n catch hook, or your own server.

Vocaic-Signature header
Vocaic-Signature: t=1764800000, v1=4a7f...e2  (hex HMAC-SHA256 of `${t}.${rawBody}`)
Verify a webhook (Node)
import crypto from "node:crypto";

// Express-style handler. Use the RAW request body (not a re-serialized object).
export function handler(req, res) {
  const header = req.get("Vocaic-Signature") || "";
  const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
  const t = Number(parts.t);
  const raw = req.rawBody; // the exact bytes Vocaic sent

  // Reject old timestamps (5 minute tolerance) to stop replays.
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return res.status(400).end();

  const expected = crypto
    .createHmac("sha256", process.env.VOCAIC_WEBHOOK_SECRET)
    .update(t + "." + raw)
    .digest("hex");

  const ok = parts.v1 && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
  if (!ok) return res.status(400).end();

  const event = JSON.parse(raw); // { id, event, created, data }
  // event.event is "delivery.created" or "reply.created".
  res.status(200).end(); // a 2xx tells Vocaic the delivery succeeded
}
  • Reply with any 2xx to acknowledge; anything else is retried.
  • Retries back off: 10s, 30s, 2m, 5m, 15m, then the delivery is marked failed.
  • Reject a timestamp more than 300 seconds old to stop replays.
  • Each event body is { id, event, created, data }; the id lets you dedupe retries.
Live previewVoice for any agent

Give any chat agent a voice

vocaic-voice.js is a tiny, dependency-free browser SDK. It listens on the microphone and emits clean text with end-of-turn detection, and speaks replies in any Vocaic voice with barge-in (start talking to interrupt). Audio stays on the device except the text sent for synthesis. This is the same engine that powers Talk with Ava on the Ava page.

Add voice in and out
<script type="module">
  import { VocaicVoice } from "https://vocaic.example/sdk/vocaic-voice.js";

  const voice = new VocaicVoice({ voiceId: "en-GB-Sonia", locale: "en-GB" });
  voice.on("partial", (text) => showInterim(text));   // live words
  voice.on("turn", async (text) => {                    // a finished spoken turn
    const reply = await myAgent.respond(text);          // your agent, any backend
    await voice.speak(reply);                            // Ava-style spoken reply, interruptible
  });
  voice.on("state", (s) => render(s));                  // "idle" | "listening" | "speaking"
  voice.startListening();
</script>
Methods
voice.startListening();   // mic -> "partial" and "turn" events
voice.stopListening();
await voice.speak(text);  // speak, resolves when done; interrupts playback
voice.stopSpeaking();     // barge-in: stop talking now
voice.setVoice(id, locale);
voice.on("state", fn);    // "idle" | "listening" | "speaking"
voice.on("error", fn);

The SDK is served from /sdk/vocaic-voice.js on this origin. Phone and WhatsApp agents are not part of this preview.

Live previewRead aloud

Add a listen button to any article

One script tag adds a Listen to this article player to any page. The player reads the article text from your own page and speaks it paragraph by paragraph in the voice or accent you choose, with play, pause, speed and the current paragraph highlighted. The text is spoken on the reader's device through Vocaic. No URL is fetched by the server. The player loads from /sdk/vocaic-reader.js and runs in a same-origin iframe at /embed/read.

Drop in the player
<!-- Put this where you want the player, then add the script. -->
<article>
  <h1>Your article title</h1>
  <p>Your first paragraph...</p>
  <p>Your second paragraph...</p>
</article>

<script
  src="https://vocaic.example/sdk/vocaic-reader.js"
  data-article="article"
  data-voice="en-GB-Sonia"
  defer></script>
Or mount it yourself
<script src="https://vocaic.example/sdk/vocaic-reader.js" data-auto="false"></script>
<script>
  VocaicReader.mount({
    articleSelector: "#post-body",   // where your article is
    mount: "#listen",                // where to put the player
    voiceId: "en-IN-Neerja",   // optional reading voice
  });
</script>
  • The article never leaves the reader's device except the text sent to Vocaic for synthesis.
  • Choose a reading voice with data-voice (an accent English voice id).
  • Click any paragraph to start reading from there. Speed options: 0.75x to 1.5x.
Voices

The accent layer, live from the API

This list loads from /api/v1/voices. Use an accent id or a locale with an English recipient, or a voice id directly.

Loading voices...