---
type: AI Model
id: fish-audio
title: Fish Audio API
provider: Fish Audio
description: "Fish Audio S2.1 Pro text-to-speech. Natural, expressive speech in 83 languages with free-form emotion markers and a library of 2.5M+ community voices."
resource: https://www.pixazo.ai/models/fish-audio
docs_url: https://www.pixazo.ai/models/fish-audio
latest_version: S2.1 Pro
tags:
  - text-to-speech
  - speech-to-text
  - fish-audio
variants:
  - id: fish-audio
    name: Fish Audio S2.1 Pro
    version: S2.1 Pro
    capabilities:
      - Text to Speech
  - id: fish-audio-speech-to-text
    name: Fish Audio Speech to Text
    version: Transcribe 1
    capabilities:
      - Speech to Text
timestamp: 2026-08-25T08:44:38.582Z
---

# Fish Audio API

> Provider: **Fish Audio**
> Source: https://www.pixazo.ai/models/fish-audio

Fish Audio S2.1 Pro text-to-speech. Natural, expressive speech in 83 languages with free-form emotion markers and a library of 2.5M+ community voices.

## Fish Audio S2.1 Pro

### Text to Speech

## Fish Audio S2.1 Pro Text to Speech API Documentation

Generate natural, expressive speech from text in 83 languages, with free-form emotion markers and a library of over 2.5 million community voices. Asynchronous: submit returns a `request_id`; poll the status endpoint until the request is `COMPLETED`. Typical synthesis completes in a few seconds.

```
POST https://gateway.pixazo.ai/fish-audio-s2-1-pro/v1/text-to-speech
```

## Authentication

All requests require an API key passed via header.

Header

Type

Required

Description

Ocp-Apim-Subscription-Key

string

Yes

Your API subscription key

## Text to Speech - Fish Audio S2.1 Pro

## Request Code

HTTP Python JavaScript cURL

```
POST https://gateway.pixazo.ai/fish-audio-s2-1-pro/v1/text-to-speech
Content-Type: application/json
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "text": "[whispering] When you are building something new, there is this mix of wonder and fear. [chuckling] But that is what makes it worth building.",
  "reference_id": "933563129e564b19a115bedd57b7406a",
  "format": "mp3",
  "mp3_bitrate": 128
}
```

```
import requests

url = "https://gateway.pixazo.ai/fish-audio-s2-1-pro/v1/text-to-speech"
headers = {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
  "text": "[whispering] When you are building something new, there is this mix of wonder and fear. [chuckling] But that is what makes it worth building.",
  "reference_id": "933563129e564b19a115bedd57b7406a",
  "format": "mp3",
  "mp3_bitrate": 128
}

resp = requests.post(url, json=data, headers=headers)
print(resp.json())
```

```
const res = await fetch("https://gateway.pixazo.ai/fish-audio-s2-1-pro/v1/text-to-speech", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
  },
  body: JSON.stringify({
  "text": "[whispering] When you are building something new, there is this mix of wonder and fear. [chuckling] But that is what makes it worth building.",
  "reference_id": "933563129e564b19a115bedd57b7406a",
  "format": "mp3",
  "mp3_bitrate": 128
})
});
console.log(await res.json());
```

```
curl -X POST 'https://gateway.pixazo.ai/fish-audio-s2-1-pro/v1/text-to-speech' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  --data-raw '{"text": "[whispering] When you are building something new, there is this mix of wonder and fear. [chuckling] But that is what makes it worth building.", "reference_id": "933563129e564b19a115bedd57b7406a", "format": "mp3", "mp3_bitrate": 128}'
```

## Output

```
{
  "request_id": "fish-audio-s2-1-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/fish-audio-s2-1-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

[Try Now](https://api.pixazo.ai/api-details#api=fish-audio-s2-1-pro&operation=fish-audio-s2-1-pro-request)

## Webhook (Optional)

Instead of polling, you can receive a Webhook callback when the request reaches a terminal state. Provide a Webhook URL via header on the submit request.

Header

Required

Description

X-Webhook-URL

To enable

HTTPS URL to receive the Webhook callback.

X-Webhook-Mode

No

`terminal` (default, one callback on COMPLETED/ERROR) or `sync` (per-poll callbacks).

### Example: enable Webhook

```
curl -X POST 'https://gateway.pixazo.ai/fish-audio-s2-1-pro/v1/text-to-speech' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  -H 'X-Webhook-URL: https://your-server.com/webhook' \
  --data-raw '{"text": "[whispering] When you are building something new, there is this mix of wonder and fear. [chuckling] But that is what makes it worth building.", "reference_id": "933563129e564b19a115bedd57b7406a", "format": "mp3", "mp3_bitrate": 128}'
```

### Callback Payload (success)

```
{
  "request_id": "fish-audio-s2-1-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "fish-audio-s2-1-pro",
  "output": {
    "media_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/fish-audio/1785407392754-66f0f615.mp3",
    "media_type": "audio/mpeg"
  },
  "created_at": "2026-07-30T10:29:44.313Z",
  "completed_at": "2026-07-30T10:29:53.391Z"
}
```

### Failure callback shape

```
{
  "request_id": "fish-audio-s2-1-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "fish-audio-s2-1-pro",
  "error": "Description of the failure"
}
```

#### Delivery semantics

-   **terminal** mode: one Webhook callback when the request is COMPLETED or ERROR.
-   **sync** mode: a Webhook callback on each status change.
-   Callbacks are idempotent on `request_id` — de-duplicate on it.
-   Respond `200` within a few seconds; the Webhook endpoint must be HTTPS.

## Request Parameters

Parameter

Required

Type

Default

Allowed values / range

Description

`text`

Yes

string

—

1 – 5000 characters

The text to synthesize. Supports emotion and effect markers such as `[whispering]`, `[chuckling]`, `[laughing]`, `[sighing]` and `[audience laughing]`. Markers are free-form and add no cost or latency.

`reference_id`

No

string or array

—

32-char hex voice id, or an array of up to 8

The voice(s) to speak with. Pass a **single string** for one speaker, or an **array of ids** for multi-speaker dialogue (see Multi-Speaker Dialogue below). Omit to use the provider default voice. Browse voices at `fish.audio`; the id is the last path segment of `fish.audio/m/<id>`. You are responsible for holding the rights to any voice you reference.

`format`

No

string

`mp3`

`mp3`, `wav`

Output audio container. `mp3` returns `audio/mpeg`; `wav` returns 16-bit mono PCM at 44.1 kHz.

`mp3_bitrate`

No

integer

`128`

`64`, `128`, `192`

MP3 bitrate in kbps. Only valid when `format` is `mp3`; sending it with `wav` returns 400.

`latency`

No

string

`balanced`

`normal`, `balanced`

Synthesis latency trade-off. `balanced` (our default) favours the lowest time-to-first-audio; `normal` accepts more latency in exchange for the provider's best quality.

`chunk_length`

No

integer

`300`

100 to 300

Text chunk size used during synthesis. Smaller chunks start faster; larger chunks give steadier prosody across long passages.

`normalize`

No

boolean

`true`

`true`, `false`

Normalize numbers, dates and abbreviations in English and Chinese text before synthesis.

`temperature`

No

number

`0.7`

0.0 to 1.0

Controls expressiveness. Higher is more varied, lower is more consistent.

`top_p`

No

number

`0.7`

0.0 to 1.0

Controls diversity via nucleus sampling.

`prosody`

No

object

—

—

Optional prosody controls (see the two fields below).

`prosody.speed`

No

number

`1.0`

0.5 to 2.0

Speaking rate multiplier. `2.0` is twice as fast, `0.5` is half speed.

`prosody.volume`

No

number

`0`

\-20 to 20

Volume adjustment in decibels.

### Parameters not supported

Worth reading if you are porting existing Fish Audio code — some parameters are rejected outright, while others are accepted and then ignored.

#### Rejected with `400`

Parameter

Why

Use instead

`model`

The model is fixed for this endpoint and is not caller-selectable.

—

`references`

Inline zero-shot voice cloning requires a MessagePack request body, which this JSON endpoint cannot carry.

`reference_id` with a Fish Audio voice id

`format: "pcm"` / `"opus"`

Not offered; `mp3` and `wav` cover playback in every browser and player.

`mp3` or `wav`

#### Accepted but ignored

These are silently dropped — the request still returns `202`, but the value has no effect on the generated audio. Only the parameters listed in the table above are forwarded.

`sample_rate`, `opus_bitrate`, `max_new_tokens`, `repetition_penalty`, `min_chunk_length`, `condition_on_previous_chunks`, `early_stop_threshold`, `features`, `prosody.normalize_loudness`, and any parameter not listed above

## Voice & Emotion Control

### Choosing a voice

`reference_id` accepts two forms. Omit it entirely to use the provider default voice.

Form

Use for

Value

**String**

A single speaker

`"933563129e564b19a115bedd57b7406a"`

**Array**

Multi-speaker dialogue

`["<speaker-0-id>", "<speaker-1-id>"]` — up to 8 ids

Voice ids are 32-character hexadecimal strings. Browse the Fish Audio voice library at `fish.audio` — the id is the last path segment of `fish.audio/m/<id>`.

### Multi-Speaker Dialogue

Pass an **array** of voice ids and mark speaker changes in `text` with `<|speaker:N|>` tags. The index in the tag selects the voice at that position in the array — `<|speaker:0|>` uses the first id, `<|speaker:1|>` the second, and so on.

```
{
  "text": "<|speaker:0|>Good morning!<|speaker:1|>Good morning! How are you?<|speaker:0|>I am great, thanks for asking!",
  "reference_id": [
    "933563129e564b19a115bedd57b7406a",
    "d13f84b987ad4f22b56d2b47f4eb838e"
  ],
  "format": "mp3"
}
```

-   Text before any tag is spoken by the **first** voice in the array.
-   A tag index with no matching array entry is not valid — supply one id per speaker index you use.
-   Passing two or more ids **without** any `<|speaker:N|>` tag returns `400`, because every line would otherwise be rendered in the first voice.
-   For a single speaker, pass the id as a plain string — tags are not needed.

### Emotion & effect markers

Place markers inline in `text` using square brackets. They are interpreted as performance direction and are not spoken aloud.

Category

Examples

Emotions

`[happy]`, `[sad]`, `[angry]`, `[excited]`, `[calm]`, `[nervous]`, `[confident]`, `[sarcastic]`

Tone

`[whispering]`, `[shouting]`, `[soft tone]`, `[in a hurry tone]`, `[emphasis]`

Audio effects

`[laughing]`, `[chuckling]`, `[sighing]`, `[gasping]`, `[panting]`, `[clear throat]`

Special

`[audience laughing]`, `[background laughter]`, `[break]`, `[long-break]`

Markers are **not** restricted to this list — any descriptive phrase works, for example `[whispers sweetly]` or `[laughing nervously]`. Use at most three emotion markers per sentence, and place sentence-level direction at the start of the sentence. Markers add no character cost and no latency.

## Example Request

```
{
  "text": "[whispering] When you are building something new, there is this mix of wonder and fear. [chuckling] But that is what makes it worth building.",
  "reference_id": "933563129e564b19a115bedd57b7406a",
  "format": "mp3",
  "mp3_bitrate": 128
}
```

## Example Response

```
{
  "request_id": "fish-audio-s2-1-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/fish-audio-s2-1-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

## Request Headers

Header

Required

Description

Content-Type

Yes

`application/json`

Ocp-Apim-Subscription-Key

Yes

Your API subscription key.

X-Webhook-URL

No

Enable Webhook callbacks (see Webhook section).

## Response Handling

Status Code

Meaning

202

Accepted — request queued; returns `request_id` and `polling_url`.

400

Bad request — invalid or missing parameters: missing `text`, text over 5000 characters, a malformed `reference_id`, `mp3_bitrate` sent with `format: "wav"`, or two or more `reference_id` values without `<|speaker:N|>` tags. Also returned for `references` and `model` — see “Parameters not supported” above.

401

Unauthorized — missing or invalid subscription key.

402

Insufficient balance.

403

Forbidden.

429

Too many requests.

500

Internal server error.

## Error Responses

```
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
```

A failed generation is reported via the status endpoint (or Webhook) with `status: "ERROR"` and an `error` message — for example `Reference not found` when `reference_id` does not name an existing voice.

## Retrieving Results

Poll the status endpoint with the `request_id` from the submit response until `status` is `COMPLETED` (or `FAILED`/`ERROR`).

```
curl 'https://gateway.pixazo.ai/v2/requests/status/fish-audio-s2-1-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY'
```

### Completed response

```
{
  "request_id": "fish-audio-s2-1-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "fish-audio-s2-1-pro",
  "output": {
    "media_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/fish-audio/1785407392754-66f0f615.mp3",
    "media_type": "audio/mpeg"
  },
  "created_at": "2026-07-30T10:29:44.313Z",
  "completed_at": "2026-07-30T10:29:53.391Z"
}
```

## Response Fields

Field

Type

Description

request\_id

string

Unique request identifier.

status

string

QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR.

model\_id

string

The model that handled the request.

output.media\_url

string

Permanent URL of the generated audio.

output.media\_type

string

Audio MIME type (`audio/mpeg` for mp3, `audio/wav` for wav).

created\_at

string

Request creation timestamp.

completed\_at

string

Completion timestamp.

polling\_url

string

Status URL for this request.

error

string

Error message when `status` is FAILED/ERROR.

## Status Values & Flow

`QUEUED` → `PROCESSING` → `COMPLETED` (success) or `FAILED`/`ERROR` (failure).

### Pricing

Billed at **$0.02 per 1,000 UTF-8 bytes** of input text, rounded up to the next whole 1,000. Every request bills at least one block.

Billing is measured in **UTF-8 bytes, not characters**. For English and other Latin-script text the two are the same — one character is one byte — but characters outside the ASCII range take more than one byte, so the same character count costs more in those languages.

Input

Characters

UTF-8 bytes

Blocks

Cost

English

500

500

1

$0.02

English

1,200

1,200

2

$0.04

Chinese / Japanese (3 bytes per character)

416

1,248

2

$0.04

Maximum single request, English

5,000

5,000

5

$0.10

The 5,000-character limit on `text` counts characters, not bytes — and characters outside the Basic Multilingual Plane (most emoji) count as **two** toward it. The most expensive possible request is therefore 5,000 three-byte characters, such as Chinese or Japanese: 15,000 bytes, or **$0.30**. Text made of 4-byte characters hits the limit at 2,500 characters, or $0.20.

## Fish Audio Speech to Text

### Speech to Text

## Fish Audio Speech to Text API Documentation

Transcribe audio into text with automatic language detection and optional word-level timestamps. Asynchronous: submit returns a `request_id`; poll the status endpoint until the request is `COMPLETED`. The transcript is returned as a JSON file.

```
POST https://gateway.pixazo.ai/fish-audio-speech-to-text/v1/speech-to-text
```

## Authentication

All requests require an API key passed via header.

Header

Type

Required

Description

Ocp-Apim-Subscription-Key

string

Yes

Your API subscription key

## Speech to Text - Fish Audio

## Request Code

HTTP Python JavaScript cURL

```
POST https://gateway.pixazo.ai/fish-audio-speech-to-text/v1/speech-to-text
Content-Type: application/json
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/speech-17s.mp3",
  "language": "en",
  "ignore_timestamps": false
}
```

```
import requests

url = "https://gateway.pixazo.ai/fish-audio-speech-to-text/v1/speech-to-text"
headers = {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/speech-17s.mp3",
  "language": "en",
  "ignore_timestamps": false
}

resp = requests.post(url, json=data, headers=headers)
print(resp.json())
```

```
const res = await fetch("https://gateway.pixazo.ai/fish-audio-speech-to-text/v1/speech-to-text", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
  },
  body: JSON.stringify({
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/speech-17s.mp3",
  "language": "en",
  "ignore_timestamps": false
})
});
console.log(await res.json());
```

```
curl -X POST 'https://gateway.pixazo.ai/fish-audio-speech-to-text/v1/speech-to-text' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  --data-raw '{"audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/speech-17s.mp3", "language": "en", "ignore_timestamps": false}'
```

## Output

```
{
  "request_id": "fish-audio-speech-to-text_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/fish-audio-speech-to-text_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

[Try Now](https://api.pixazo.ai/api-details#api=fish-audio-speech-to-text&operation=fish-audio-speech-to-text-request)

## Webhook (Optional)

Instead of polling, you can receive a Webhook callback when the request reaches a terminal state. Provide a Webhook URL via header on the submit request.

Header

Required

Description

X-Webhook-URL

To enable

HTTPS URL to receive the Webhook callback.

X-Webhook-Mode

No

`terminal` (default, one callback on COMPLETED/ERROR) or `sync` (per-poll callbacks).

### Example: enable Webhook

```
curl -X POST 'https://gateway.pixazo.ai/fish-audio-speech-to-text/v1/speech-to-text' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  -H 'X-Webhook-URL: https://your-server.com/webhook' \
  --data-raw '{"audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/speech-17s.mp3", "language": "en", "ignore_timestamps": false}'
```

### Callback Payload (success)

```
{
  "request_id": "fish-audio-speech-to-text_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "fish-audio-speech-to-text",
  "output": {
    "media_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/{request_id}/output.json",
    "media_type": "application/json"
  },
  "created_at": "2026-07-30T14:49:39.898Z",
  "completed_at": "2026-07-30T14:49:59.000Z"
}
```

### Failure callback shape

```
{
  "request_id": "fish-audio-speech-to-text_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "fish-audio-speech-to-text",
  "error": "Description of the failure"
}
```

#### Delivery semantics

-   **terminal** mode: one Webhook callback when the request is COMPLETED or ERROR.
-   **sync** mode: a Webhook callback on each status change.
-   Callbacks are idempotent on `request_id` — de-duplicate on it.
-   Respond `200` within a few seconds; the Webhook endpoint must be HTTPS.

## Request Parameters

Parameter

Required

Type

Default

Allowed values / range

Description

`audio_url`

Yes

string

—

http(s) URL, file up to 25 MB

Public URL of the audio to transcribe. Common formats are supported, including mp3, wav, m4a, flac and ogg. The file is fetched by the gateway, so the URL must be reachable without authentication.

`language`

No

string

— (auto-detected)

One of 57 ISO codes: `af` (Afrikaans), `ar` (Arabic), `hy` (Armenian), `az` (Azerbaijani), `be` (Belarusian), `bs` (Bosnian), `bg` (Bulgarian), `ca` (Catalan), `zh` (Chinese), `hr` (Croatian), `cs` (Czech), `da` (Danish), `nl` (Dutch), `en` (English), `et` (Estonian), `fi` (Finnish), `fr` (French), `gl` (Galician), `de` (German), `el` (Greek), `he` (Hebrew), `hi` (Hindi), `hu` (Hungarian), `is` (Icelandic), `id` (Indonesian), `it` (Italian), `ja` (Japanese), `kn` (Kannada), `kk` (Kazakh), `ko` (Korean), `lv` (Latvian), `lt` (Lithuanian), `mk` (Macedonian), `ms` (Malay), `mr` (Marathi), `mi` (Maori), `ne` (Nepali), `no` (Norwegian), `fa` (Persian), `pl` (Polish), `pt` (Portuguese), `ro` (Romanian), `ru` (Russian), `sr` (Serbian), `sk` (Slovak), `sl` (Slovenian), `es` (Spanish), `sw` (Swahili), `sv` (Swedish), `tl` (Tagalog), `ta` (Tamil), `th` (Thai), `tr` (Turkish), `uk` (Ukrainian), `ur` (Urdu), `vi` (Vietnamese), `cy` (Welsh)

Optional language hint. Omit it and the model detects the language automatically, returning what it found in the transcript. There is no `auto` option — sending a placeholder such as `"auto-detected"` is rejected with HTTP 400.

`ignore_timestamps`

No

boolean

`true`

`true`, `false`

Set to `false` to include word-level `segments` with start and end times. Adds latency on audio shorter than 30 seconds.

### Audio limits

-   The audio file must be at most **25 MB**. Larger files are rejected before transcription starts.
-   `audio_url` must be an `http` or `https` URL and must be publicly reachable.
-   There is no fixed duration limit; cost scales with the length of the audio (see Pricing).

## Transcript Format

The completed request returns `output.media_url`, a JSON file containing the transcript. Fetch that URL to read the result.

```
{
  "text": "Strong consistency test. This should complete in a few seconds, not sixty.",
  "language": "English",
  "language_code": "en",
  "duration": 5.8253125,
  "segments": [
    {
      "text": "Strong",
      "start": 0,
      "end": 0.56
    },
    {
      "text": "consistency",
      "start": 0.56,
      "end": 1.12
    }
  ]
}
```

Field

Type

Description

text

string

The full transcript.

language

string

Detected language name, e.g. `English`.

language\_code

string

Detected language code, e.g. `en`.

duration

number

Length of the transcribed audio in seconds. This is the quantity you are billed on.

segments

array

Word-level entries of `{text, start, end}` with times in seconds. Empty unless `ignore_timestamps` is `false`.

## Example Request

```
{
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/speech-17s.mp3",
  "language": "en",
  "ignore_timestamps": false
}
```

## Example Response

```
{
  "request_id": "fish-audio-speech-to-text_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/fish-audio-speech-to-text_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

## Request Headers

Header

Required

Description

Content-Type

Yes

`application/json`

Ocp-Apim-Subscription-Key

Yes

Your API subscription key.

X-Webhook-URL

No

Enable Webhook callbacks (see Webhook section).

## Response Handling

Status Code

Meaning

202

Accepted — request queued; returns `request_id` and `polling_url`.

400

Bad request — missing `audio_url`, a non-http(s) URL, or a wrongly typed `language` / `ignore_timestamps`.

401

Unauthorized — missing or invalid subscription key.

402

Insufficient balance.

429

Too many requests.

500

Internal server error.

An unreachable `audio_url`, an oversized file, or a file that is not recognisable audio is reported through the status endpoint as `status: "ERROR"`, not as a synchronous error. Failed requests are not billed.

## Retrieving Results

Poll the status endpoint with the `request_id` from the submit response until `status` is `COMPLETED` (or `FAILED`/`ERROR`), then fetch `output.media_url` for the transcript.

```
curl 'https://gateway.pixazo.ai/v2/requests/status/fish-audio-speech-to-text_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY'
```

### Completed response

```
{
  "request_id": "fish-audio-speech-to-text_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "fish-audio-speech-to-text",
  "output": {
    "media_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/{request_id}/output.json",
    "media_type": "application/json"
  },
  "created_at": "2026-07-30T14:49:39.898Z",
  "completed_at": "2026-07-30T14:49:59.000Z"
}
```

## Response Fields

Field

Type

Description

request\_id

string

Unique request identifier.

status

string

QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR.

model\_id

string

The model that handled the request.

output.media\_url

string

URL of the transcript JSON file.

output.media\_type

string

`application/json`.

created\_at

string

Request creation timestamp.

completed\_at

string

Completion timestamp.

error

string

Error message when `status` is FAILED/ERROR.

## Status Values & Flow

`QUEUED` → `PROCESSING` → `COMPLETED` (success) or `FAILED`/`ERROR` (failure).

### Pricing

Billed at **$0.006 per minute of audio** ($0.36 per audio hour), rounded up to the next whole minute. Billing is based on the **length of the audio you submit**, not on the size of the transcript.

Audio length

Billed minutes

Cost

6 seconds

1

$0.006

90 seconds

2

$0.012

10 minutes

10

$0.06

1 hour

60

$0.36

A hold is placed when the request is submitted, because the audio length is not known until transcription completes. The hold is reduced to the real cost once the duration is known, and released in full if the request fails.
