# Speech to text
> Transcribe speech audio with speaker diarization, timestamps, non-verbal event tags, and JSON/SRT/VTT subtitles.

Transcribe speech audio into text with utterance timestamps, optional speaker
diarization, non-verbal audio-event tags, and ready-to-use JSON, SRT, and VTT
subtitle files.

## Primary agent path

Use the Universal Skill with the MCP tool `beatra.audio.transcribe`. The tool is
billable and returns an asynchronous task.

1. Upload local audio with `beatra.assets.upload` and use the returned
   `artifact_id` (or pass an `https_url`).
2. When language breadth, non-verbal event tagging, or price matters, call
   `beatra.models.list` with `capability: "speech_to_text"`. Otherwise omit
   `model` or pass `"auto"` (`doubao-seed-asr-2.0` by default, or automatically
   routed to `elevenlabs-scribe-v3` when `tag_audio_events: true` or
   `num_speakers` is requested).
3. Create one opaque `client_request_id` and submit the final arguments once.
4. Poll the returned task with `beatra.tasks.get` until it is terminal, and read
   the full transcript from that single-task response.

## AI guide

AI integration guide: https://docs.beatra.ai/llms/audio-speech-to-text.md

## Tool arguments

```json
{
  "audio": { "type": "artifact", "artifact_id": "artifact_01JX..." },
  "model": "auto",
  "language": "auto",
  "diarize": true,
  "subtitles": true,
  "client_request_id": "stt-opaque-1"
}
```

- `audio` (required; `source` accepted as an input alias on both MCP and REST):
  an artifact reference (`{"type": "artifact", "artifact_id": "..."}`)
  or HTTPS URL (`{"type": "https_url", "url": "https://..."}`). Accepted formats
  include MP3, WAV, M4A, AAC, FLAC, OGG, and Opus. Duration must be between
  `0.5` seconds and **`3,600` seconds (`60 minutes`)**, and file size at most
  `100 MiB`. Audio longer than `60 minutes` is rejected before billing with
  `422 invalid_request` (`details.reason: "audio_too_long"`; split longer recordings
  first with `beatra.audio.process` `operation: "trim"` — see
  [audio processing](https://docs.beatra.ai/en/docs/capabilities/speech/audio-processing)).
- `model` (optional, default `"auto"`): `"auto"`, `"doubao-seed-asr-2.0"`, or
  `"elevenlabs-scribe-v3"`.
- `language` (optional, default `"auto"`): `"auto"` for automatic language
  detection, or a BCP-47 / ISO-639-1 tag such as `"zh"`, `"yue"`, `"en"`, or `"ja"`.
- `diarize` (optional, boolean, default `false`): label speaker turns across
  `segments[]` (`speaker_0`, `speaker_1`, …).
- `num_speakers` (optional, integer `1`–`32`): expected speaker count hint on
  `elevenlabs-scribe-v3`; passing `num_speakers` implies `diarize: true` and
  automatically upgrades `model: "auto"` to `elevenlabs-scribe-v3` when available.
- `tag_audio_events` (optional, boolean, default `false`): tag non-verbal audio
  events such as laughter, applause, and music on `elevenlabs-scribe-v3`. When
  `model` is `"auto"`, passing `tag_audio_events: true` automatically selects
  `elevenlabs-scribe-v3` if available; passing `tag_audio_events: true` or
  `num_speakers` with an explicit `model: "doubao-seed-asr-2.0"` attaches a
  non-blocking `option_ignored` warning.
- `subtitles` (optional, boolean, default `true`): generate and persist the
  JSON, SRT, and VTT subtitle bundle on Beatra CDN at no extra charge.
- `model_options` (optional, object): forward-compatible bag for
  model-specific extension options.

## Models and cost

`beatra.models.list` with `capability: "speech_to_text"` is the live source for
selectable models, supported controls, and prices.

Transcription is prepaid by **started input minute** (`ceil(duration_seconds / 60)`),
with a per-request minimum:

| Model | Rate | Minimum | Strengths |
| --- | --- | --- | --- |
| `doubao-seed-asr-2.0` (`auto` default) | `15 credits` / started minute | `60 credits` (`<= 4 min`) | High-accuracy Chinese, Mandarin dialects & accents, English, Japanese, and multilingual speech with speaker diarization and timestamps. |
| `elevenlabs-scribe-v3` | `21 credits` / started minute | `61 credits` (`<= 2 min`) | 90+ global languages, up to 32 speakers (`num_speakers`), timestamps, and non-verbal `tag_audio_events` (`(laughter)`, `(applause)`, `(music)`). |

## Result and subtitles

When the task succeeds, `output` contains the full transcript, utterance-level
segments, optional audio events, and the subtitle bundle:

```json
{
  "type": "speech_to_text",
  "model": "doubao-seed-asr-2.0",
  "text": "大家好，欢迎来到今天的播客。谢谢邀请！",
  "language": "zh",
  "duration_seconds": 6.4,
  "segments": [
    {
      "text": "大家好，欢迎来到今天的播客。",
      "start_seconds": 0.12,
      "end_seconds": 3.48,
      "speaker_id": "speaker_0"
    },
    {
      "text": "谢谢邀请！",
      "start_seconds": 3.85,
      "end_seconds": 5.9,
      "speaker_id": "speaker_1"
    }
  ],
  "audio_events": [],
  "subtitles": {
    "url": "https://cdn.beatra.ai/tenants/.../subtitles.json",
    "format": "json",
    "files": {
      "json": "https://cdn.beatra.ai/tenants/.../subtitles.json",
      "srt": "https://cdn.beatra.ai/tenants/.../subtitles.srt",
      "vtt": "https://cdn.beatra.ai/tenants/.../subtitles.vtt"
    },
    "segment_count": 2
  }
}
```

- `subtitles` uses the exact same `files.{json, srt, vtt}` structure as
  [text to speech subtitles](https://docs.beatra.ai/en/docs/capabilities/speech/text-to-speech#subtitles),
  so downstream video composition and captioning pipelines consume both without
  format conversion.
- Silent or speech-free audio is a valid observation, not an error: the task
  succeeds with `text: ""`, `segments: []`, and `subtitles: null`.
- In task list views (`GET /v1/tasks`), long transcripts return a bounded
  preview marked `truncated: true`. Always read `beatra.tasks.get` or
  `GET /v1/tasks/{task_id}` for the complete `text` and `segments[]`.

## Task status and recovery

`queued` and `running` are not failures. Keep polling the same `task_id`; never
submit a replacement because work is still running. On a lost create response,
retry the identical arguments with the same `client_request_id`. If any input
changes, use a new ID. Failed tasks automatically refund the reserved credits.

## REST API

Direct protocol integrations may use `POST /v1/audio/transcriptions` with a
stable `Idempotency-Key` header and the shared task endpoints. Follow the
generated [API reference](https://docs.beatra.ai/en/docs/api-reference). Skill + MCP is the recommended
integration; use REST for custom, non-agent applications.
