# Integrations overview

Source: https://docs.vieneu.io/docs/integrations/overview

:::info The n8n node is not published yet
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](../cloud-api/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](./openai-clients.md) — per-client setup and troubleshooting by symptom · [endpoint reference](../cloud-api/openai-compatible) |
| 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](./mcp/index.md) |
| **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](./n8n.md) |
| 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](../cloud-api/vapi) · [LiveKit / Pipecat](./openai-clients.md#livekit-agents) · [Streaming](../cloud-api/streaming) |
| **Your own code** | Call `/api/v1` directly — that surface is much larger than the OpenAI-shaped one. | [Cloud API overview](../cloud-api/overview) · [API reference](/api-reference) |
| Something that must **react when a job finishes** | Register a webhook instead of polling. | [Webhooks](../cloud-api/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](../cloud-api/overview#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](../cloud-api/overview#billing).

## One request end to end

```bash
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](../cloud-api/overview#engines) — the engine also sets the price
multiplier). To choose one, ask which engine is the default, then list that
engine's voices:

```bash
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](./openai-clients.md#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`, and `stream_format` on the
  OpenAI route, deliver audio as it is generated rather than as one buffered
  download wearing a streaming label. It is declared per engine — `features` on
  `GET /v1/engines` includes `stream` for `v4`; the `v3` engine 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](../cloud-api/streaming).
- **Cloned voices, usable from code.** You clone a voice once in the web Studio
  ([vieneu.io/#/clone](https://vieneu.io/#/clone)) — the guided path that
  denoises the clip, transcribes it and plays it back before saving — and its
  `clone_…` id then works on `POST /v1/tts` and `POST /v1/tts/stream` like any
  catalogue voice. It is the one thing an OpenAI-compatible client cannot reach:
  a `clone_…` id on `/v1/audio/speech` is 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](./openai-clients.md).

## 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](../cloud-api/streaming#latency-honestly).
