> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://api.llynx.io/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://api.llynx.io/docs/_mcp/server.

# Quickstart

Make your first speech requests in a few minutes: one call that turns text into
audio, one that turns that audio back into text, and one that shows what they cost.
The examples use Python with the `requests` library, or Node.js 18 or newer.

### Create an API key

Sign up at [api.llynx.io](https://api.llynx.io/signup) with your business email, verify
it and accept the terms. Open **API keys** and create a key. It is shown once; store it
on your server and never in a browser or mobile app. The examples read it from the
`LLYNX_API_KEY` environment variable.

### Turn text into speech

Send the text, its language tag and an optional voice gender. The response body is a
complete WAV file, so save it straight to disk.

**`Python`**

```python title="Python"
import os
import requests

response = requests.post(
    "https://api.llynx.io/v2/audio/speech",
    headers={"Authorization": f"Bearer {os.environ['LLYNX_API_KEY']}"},
    json={
        "input": "Your order has shipped and will arrive on Thursday.",
        "language": "en",
        "gender": "female",
        "response_format": "wav",
    },
)
response.raise_for_status()
with open("hello.wav", "wb") as f:
    f.write(response.content)
print(response.headers["X-Llynx-Credits-Reserved"], "credits")
```

**`JavaScript`**

```javascript title="JavaScript"
import { writeFile } from "node:fs/promises";

const response = await fetch("https://api.llynx.io/v2/audio/speech", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.LLYNX_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input: "Your order has shipped and will arrive on Thursday.",
    language: "en",
    gender: "female",
    response_format: "wav",
  }),
});
if (!response.ok) throw new Error(await response.text());
await writeFile("hello.wav", Buffer.from(await response.arrayBuffer()));
console.log(response.headers.get("X-Llynx-Credits-Reserved"), "credits");
```

Play `hello.wav`. This sentence is 51 characters, so it costs about 0.5 credits; the
`X-Llynx-Credits-Reserved` response header shows the exact figure.

### Turn speech into text

Upload a recording with the language spoken in it. Here `bonjour.m4a` is a short French
voice note; the `hello.wav` you just generated works too, with `language` set to `en`.

**`Python`**

```python title="Python"
import os
import requests

with open("bonjour.m4a", "rb") as audio:
    response = requests.post(
        "https://api.llynx.io/v2/audio/transcriptions",
        headers={"Authorization": f"Bearer {os.environ['LLYNX_API_KEY']}"},
        files={"file": ("bonjour.m4a", audio, "audio/mp4")},
        data={"language": "fr"},
    )
response.raise_for_status()
result = response.json()
print(result["text"])
```

**`JavaScript`**

```javascript title="JavaScript"
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("file", new Blob([await readFile("bonjour.m4a")], { type: "audio/mp4" }), "bonjour.m4a");
form.append("language", "fr");

const response = await fetch("https://api.llynx.io/v2/audio/transcriptions", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.LLYNX_API_KEY}` },
  body: form,
});
if (!response.ok) throw new Error(await response.text());
const result = await response.json();
console.log(result.text);
```

The response is JSON:

```json
{
  "id": "req_7c1d9b2e-4f3a-4b8e-9c0d-2a6e5f1b3d47",
  "text": "Bonjour, votre commande arrivera jeudi.",
  "language": "fr",
  "language_mode": "explicit",
  "duration_ms": 2800,
  "capabilities_revision": "v1",
  "usage": {
    "credit_unit": "stt_credit",
    "credits_reserved": 0.15,
    "billable_seconds": 3
  }
}
```

Any recording works the same way: WAV, MP3, M4A, FLAC, Ogg or WebM, up to 60 seconds.
Swap the tag to try another language, for example `hi`, `ta` or `es`.

### Check your balance

**`Python`**

```python title="Python"
import os
import requests

response = requests.get(
    "https://api.llynx.io/v2/audio/credits",
    headers={"Authorization": f"Bearer {os.environ['LLYNX_API_KEY']}"},
)
response.raise_for_status()
balances = response.json()
print(balances["stt"]["available"], "STT credits,", balances["tts"]["available"], "TTS credits")
```

**`JavaScript`**

```javascript title="JavaScript"
const response = await fetch("https://api.llynx.io/v2/audio/credits", {
  headers: { Authorization: `Bearer ${process.env.LLYNX_API_KEY}` },
});
if (!response.ok) throw new Error(await response.text());
const balances = await response.json();
console.log(balances.stt.available, "STT credits,", balances.tts.available, "TTS credits");
```

New accounts start with introductory credit for each service. Balances for speech to
text and text to speech are separate; the response shows allocated, used and available
credit for each.

## Before you go to production

* **Languages.** Every request names its language with a tag from the
  [Languages](/docs/capabilities) page. Requests in other languages are rejected.
* **Limits.** Recordings up to 60 seconds and 32 MiB; text up to 2,000 characters per
  request. Generated audio is WAV, 16-bit mono at 24 kHz.
* **Charges.** Transcription costs one credit per 20 seconds of audio, rounded up to
  the whole second. Speech costs one credit per 100 input characters. Buy more with a
  one-time pack; see [credits and packs](/docs/credits).
* **Failures.** A request that fails after it was accepted is refunded. Results are not
  stored, so a retry is a new request; see [retries and failures](/docs/retries).
* **Reference.** Request and response fields, headers and error codes are in the
  [API reference](/docs/api-reference).