Chuyển tới nội dung chính

Vapi (voice agent)

Vapi builds voice agents that answer and place phone calls. It speaks through a TTS provider of your choosing — and its custom-voice provider lets that be any HTTPS endpoint. VieNeu implements exactly what it expects, so your agent can answer in Vietnamese.

This matters because Vietnamese is essentially absent from the realtime TTS vendors Vapi ships with.

Configure the assistant

{
"voice": {
"provider": "custom-voice",
"server": {
"url": "https://api.vieneu.io/api/v1/vapi/speech?voiceId=Ngọc%20Lan",
"secret": "vn_sk_your_key_here",
"timeoutSeconds": 30
}
}
}

That is the whole integration. Two details are doing the work:

secret is your VieNeu API key. Vapi sends it as the X-VAPI-SECRET header, and its config has no field for an Authorization header — so this is where the key goes. It is the same key, checked the same way, and it is billed to the same account.

The voice goes in the URL. Vapi's request payload has no voice field, so pass ?voiceId= (URL-encoded). List the options with GET /v1/audio/voices. Add &engine=v4 for the premium engine if your plan includes it. Omit voiceId entirely and you get the engine's default voice.

What happens on each utterance

Vapi POSTs:

{
"message": {
"type": "voice-request",
"text": "Xin chào, tôi có thể giúp gì cho bạn?",
"sampleRate": 24000
}
}

VieNeu answers 200 with Content-Type: application/octet-stream and raw mono 16-bit little-endian PCM at exactly that sample rate, streamed as it is generated rather than buffered — so the agent starts speaking sooner.

Vapi asks for 8000, 16000, 22050 or 24000 Hz depending on the transport. All four are supported, and the response is always at the rate requested: raw PCM carries no rate of its own, so anything else would come out at the wrong pitch.

Billing and behaviour

Billed per submitted character, like the rest of /v1. Audio that gets cut short is refunded automatically.

AI refinement never runs on this endpoint, regardless of your account settings. An agent's job is to answer quickly, and an extra model round-trip in front of every utterance is the opposite of that. Deterministic text preparation still runs, so Vietnamese is pronounced correctly. If your agent's text contains things you want read a particular way — currency, dates, product codes — normalize it in your prompt, where you can see the result.

Latency, honestly

First audio leaves in roughly 1–2 seconds. That works for an agent that answers a question, reads a menu, confirms a booking. It is slower than the 200–300 ms the fastest English-only vendors reach, and it will be noticeable as a beat before the agent speaks.

Two things worth doing: keep timeoutSeconds at 30 or above, and keep utterances short — a paragraph costs more waiting than three sentences.

Utterances are capped at 800 characters (about 50 seconds of speech), and the cap exists for that reason: a longer turn cannot be delivered inside Vapi's 30-second deadline, so it would be cut off mid-word and billed anyway. If your agent produces longer replies, split them — Vapi will request each piece separately and the caller hears them back to back.

If no worker starts answering within 12 seconds, the request fails with a 503 rather than holding the socket until Vapi gives up. That distinction matters: a status code your fallbackPlan can act on beats a timeout, which just looks like a provider that stopped responding.

Set a fallbackPlan on the assistant if a missed utterance would be worse than a non-Vietnamese voice.

Troubleshooting

SymptomCause
401The secret is not a valid VieNeu API key, or the key was revoked.
400 with a voice messagevoiceId is not in the catalogue for that engine — check GET /v1/audio/voices.
403The key's token grant is empty or expired, or your plan excludes the engine.
400 about message.text lengthThe turn was over 800 characters — split it.
503 naming a sample rateNo worker in the pool has been updated to encode raw PCM yet. We fail over across the fleet first, so this means all of them. Retry; contact us if it persists.
503 about no worker answeringNothing started producing audio within 12 seconds. Usually a capacity spike; your fallbackPlan covers the turn.
502 about no audioThe worker accepted the request and then produced nothing. Not billed.

Every response carries X-Request-Id. Quote it and we can find the exact call.