Integrations overview
The n8n node (n8n-nodes-vieneu 0.1.0) is marked private and has never been
published to npm. It is built and working, but the repository it lives in is not
public, so there is no install command you can run today — contact VieNeu to
get the package, and watch the changelog for the
release.
Nothing else here depends on it. The MCP server, the OpenAI-compatible endpoint, the raw API, webhooks and Vapi are live and need nothing installed.
This page routes you to the right one. Each destination owns its own detail; this one deliberately repeats none of it.
Which path is yours
| What you already have | How VieNeu plugs in | Where |
|---|---|---|
| An app that speaks the OpenAI TTS protocol — Open WebUI, SillyTavern, LobeChat, LiteLLM, anything on the OpenAI SDK | Three settings: base URL, key, voice id. No plugin, no adapter. | OpenAI-compatible apps — per-client setup and troubleshooting by symptom · endpoint reference |
| An AI assistant — Claude, ChatGPT, Cursor, Claude Code | A hosted MCP server: add https://api.vieneu.io/mcp, sign in with your VieNeu account, ask for speech in plain language. Nothing to install. | MCP server |
| n8n | A community node (self-hosted n8n, built from source), or two ready-made workflows built from n8n's own HTTP Request node that install nothing and run on n8n Cloud. | n8n node |
| A voice agent or phone system | Vapi has a dedicated webhook route. LiveKit Agents, Pipecat and anything else with an OpenAI TTS plugin use /v1/audio/speech with response_format: "pcm". | Vapi · LiveKit / Pipecat · Streaming |
| Your own code | Call /api/v1 directly — that surface is much larger than the OpenAI-shaped one. | Cloud API overview · API reference |
| Something that must react when a job finishes | Register a webhook instead of polling. | Webhooks |
What every path shares
Base URL https://api.vieneu.io/api/v1. One key, under either header name:
Authorization: Bearer vn_sk_...
X-API-Key: vn_sk_...
vn_sk_ keys are live; vn_test_ keys behave identically but cap each request
at 100 words. Any other string — sk-…, none, an empty placeholder — is a
401 before any lookup, so a client that insists on a non-empty key field must
be given a real one. A Bearer token containing a dot is read as a JWT and
ignored, which is why pasting one produces "API key required" rather than
"invalid key". A third header, X-VAPI-SECRET, is accepted on every /v1 route
— last in precedence, so an explicit header always wins. It exists because a
Vapi assistant's configuration can set neither of the other two. See
Authentication.
Synthesis is billed per submitted character, minimum 50, times the engine's multiplier; a request that produces no audio is refunded automatically. See Billing.
One request end to end
curl -sS https://api.vieneu.io/api/v1/audio/speech \
-H "Authorization: Bearer $VIENEU_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input": "Xin chào, đây là VieNeu.", "response_format": "mp3"}' \
--output speech.mp3
Name response_format even though mp3 is the default. Only an explicit mp3
is guaranteed to be mp3: when the request never mentions a format and the worker
cannot encode one, the endpoint falls back to wav rather than failing, and
-sS --output discards the X-Output-Format header that would have told you.
Written to speech.mp3, those are bytes your player refuses.
Omitting voice uses the first active voice on the configured default engine
(see Engines — the engine also sets the price
multiplier). To choose one, ask which engine is the default, then list that
engine's voices:
curl -sS https://api.vieneu.io/api/v1/engines # no key needed; find "isDefault": true
curl -sS "https://api.vieneu.io/api/v1/audio/voices?engine=<that key>" \
-H "Authorization: Bearer $VIENEU_API_KEY"
v4 is today's default — and, since v3 was retired from the cloud API on
2026-09-24, the only engine — but the registry is the source of truth, so
substitute whatever the first call reports. The retired catalogue's ids (opaque
vieneu-… slugs) shared almost no space with v4's display names, so a voice
saved from an unfiltered list before the retirement 400s now; pick a fresh one.
Details in Getting voice ids.
What the OpenAI shape cannot reach
POST /api/v1/audio/speech, plus the GET /api/v1/audio/voices companion its
voice picker reads, is the whole compatibility surface — there is no adapter to
install and nothing to maintain per client. Two things live outside that shape,
and if you are comparing providers they are worth testing directly rather than
inferring:
- Incremental streaming.
POST /v1/tts/stream, andstream_formaton the OpenAI route, deliver audio as it is generated rather than as one buffered download wearing a streaming label. It is declared per engine —featuresonGET /v1/enginesincludesstreamforv4; thev3engine retired on 2026-09-24 never had it, because it handed over its chunks in a burst at the end and could not honour the latency promise. See Streaming. - Cloned voices, usable from code. You clone a voice once in the web Studio
(vieneu.io/#/clone) — the guided path that
denoises the clip, transcribes it and plays it back before saving — and its
clone_…id then works onPOST /v1/ttsandPOST /v1/tts/streamlike any catalogue voice. It is the one thing an OpenAI-compatible client cannot reach: aclone_…id on/v1/audio/speechis a 400.
The smaller frictions of the OpenAI shape — no GET /v1/models, unknown body
fields rejected rather than ignored, OpenAI voice names unmapped, the doubled
/api/v1 base-URL trap, streaming needing two fields, browser-side CORS, and
which 429 came from where — all have a symptom and a fix in
OpenAI-compatible apps.
Latency, honestly
On the standard plans, first audio lands in roughly 1–2 seconds. That is comfortable for read-aloud, IVR prompts, dubbing and assistants that tolerate a beat before speaking. It is not the 200–300 ms class that hard real-time conversational agents expect. Enterprise runs on a dedicated node where that ceiling is agreed per contract instead — down to ≤ 250 ms. Either way, design around the number you measure on the plan you are on — see Latency, honestly.