# Quickstart

Source: https://docs.vieneu.io/docs/cloud-api/quickstart

Three steps, and the third one returns audio. Nothing here needs an SDK.

## 1. Get an API key

Keys live on the **[Developer page](https://www.vieneu.io/#/developer?create=test)** in the
VieNeu web app. Create one, copy it once — the plaintext is shown at creation and
never again — and put it in your environment:

```bash
export VIENEU_API_KEY="vn_sk_..."
```

A key can only be issued against an **active token grant**, so a brand-new
account has to start one first; the Developer page offers a free 7-day trial that
does exactly that, once per account. Without a grant, key creation answers `403`
with `No active API token grant found.`

Keys beginning `vn_sk_` are live. `vn_test_` keys behave identically — same
billing, same limits, same endpoints — except that each request is capped at 100
words, which makes them safe to paste into a sample repository.

## 2. Pick a voice

The catalogue is public — this call needs no key:

```bash
curl -s "https://api.vieneu.io/api/v1/voices?engine=v4" | head -c 400
```

```json
{"voices":[{"id":"Ngọc Lan","description":"Giọng nữ, giọng trầm dịu dàng",
  "name":"Ngọc Lan","gender":"female","region":"south","engine":"v4",
  "kind":"catalog"}, …]}
```

The `id` field is what you send. **Always filter by engine.** A voice belongs to
one engine, the two catalogues are only partly interchangeable, and sending an id
from the wrong one is a `400` rather than a substitution — see
[voice ids differ by engine](./overview.md#voice-ids-differ-by-engine).

## 3. Synthesize

`POST /v1/audio/speech` returns the audio bytes in the response — no job, no
polling. It is OpenAI's endpoint shape, so an OpenAI client works against it
unchanged; see [OpenAI-compatible endpoint](./openai-compatible.md).

### curl

```bash
curl 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.", "voice": "Ngọc Lan" }' \
  --output speech.mp3
```

### Python

```python
# pip install requests
import os
import requests

resp = requests.post(
    "https://api.vieneu.io/api/v1/audio/speech",
    headers={"Authorization": f"Bearer {os.environ['VIENEU_API_KEY']}"},
    json={"input": "Xin chào, đây là VieNeu.", "voice": "Ngọc Lan"},
    timeout=120,
)
resp.raise_for_status()
with open("speech.mp3", "wb") as f:
    f.write(resp.content)
print("wrote speech.mp3", len(resp.content), "bytes")
```

### JavaScript

```js
// Node 18+ — no dependencies.
import { writeFile } from 'node:fs/promises';

const resp = await fetch('https://api.vieneu.io/api/v1/audio/speech', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.VIENEU_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ input: 'Xin chào, đây là VieNeu.', voice: 'Ngọc Lan' }),
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}: ${await resp.text()}`);

await writeFile('speech.mp3', Buffer.from(await resp.arrayBuffer()));
console.log('wrote speech.mp3');
```

You now have an mp3. `response_format` changes that — `wav`, `opus`, `pcm` and
8 kHz `ulaw` are all available, with the field-level detail in the
[API reference](/api-reference) under `createSpeech`.

## Where to go next

- **Long text** — `/v1/audio/speech` holds the connection open for the whole
  synthesis. Past a few paragraphs, submit a job instead: see
  [the two ways to synthesize](./overview.md#the-two-ways-to-synthesize).
- **Playback before the text finishes** — [Streaming](./streaming.md).
- **When a call fails** — [Errors](./errors.md) lists every machine-readable
  `code` and what to do about it.
- **Everything else** — the [API reference](/api-reference) is generated from the
  server's own route definitions and covers every field of every endpoint.
