# Audio to Text & RAG Chunks: Offline Whisper, SRT, Timestamps (`bongo-seakhoa/audio-to-text-rag-chunks`) Actor

Transcribe MP3, WAV, FLAC and OGG audio offline with Whisper. Timestamped RAG chunks, SRT and VTT subtitles, language detection. No API key needed.

- **URL**: https://apify.com/bongo-seakhoa/audio-to-text-rag-chunks.md
- **Developed by:** [Bongo Seakhoa](https://apify.com/bongo-seakhoa) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 audio minute transcribed (accurate)s

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Audio to Text & RAG Chunks: Offline Whisper, SRT, Timestamps

Transcribe MP3, WAV, FLAC and Ogg Vorbis audio with OpenAI's Whisper model, run on CPU inside the Actor. Every file gives you a transcript with `[hh:mm:ss]` paragraph stamps, SRT and WebVTT subtitles, a segments JSON with optional word timings, and RAG-ready chunks that carry their start and end time in seconds, so a search hit can point to the moment it was said. Give file links, a key-value store of uploads, or a podcast RSS feed. No API key and no outside AI service: the audio never leaves your run.

### What it outputs

- **Transcript row per file** in the dataset: status, duration, detected language with its probability, minutes billed and the events charged, the full plain text and links to the files below.
- **Markdown transcript** (`.md`): paragraphs with `[hh:mm:ss]` stamps, split at pauses.
- **Subtitles**: SRT (`.srt`) and WebVTT (`.vtt`), one cue per Whisper segment, split where the speaker pauses for a second or more.
- **Segments JSON** (`-segments.json`): start, end and text of every segment, plus per-word start, end and probability when `wordTimestamps` is on.
- **RAG chunks**: one dataset row per chunk, cut on segment boundaries, with `time_start_s`, `time_end_s`, character offsets into the Markdown transcript and a stable `chunk_id`.
- **Estimate mode**: duration, billable minutes and the projected price of each file, without transcribing or charging anything.
- **Honest failures.** Broken, unsupported, oversized or unreachable files get a status row with an error code and are never charged.
- **No AI service.** Everything runs inside the Actor's container: Whisper base or tiny (CTranslate2 int8 on CPU), Silero voice activity detection and the miniaudio decoders. Nothing is sent to a language model or a third-party API.

### How to use it

1. Paste direct links to audio files (MP3, WAV, FLAC or Ogg Vorbis) into **Audio file URLs**, or give a **podcast RSS feed** to transcribe its newest episodes.
2. Or pick a **key-value store** that holds your files (upload them in Apify Console under Storage), optionally naming the record keys to use. Without keys, the run reads the records the store holds when the run starts; records added later are not included.
3. Choose the model (`accurate` or `fast`) and the outputs, or leave the defaults, then start the run.
4. Open the **Output** tab. The *Transcripts* view has one row per file with links to its files; the *Chunks* view lists the RAG chunks with their times.

Starting the Actor with no input transcribes a 16-second bundled synthetic sample so you can see the output format first. The sample is charged none of this Actor's events; Apify's standard Actor start fee still applies, as it does to every run.

#### From code or an AI agent

Run it through the Apify API and get the dataset rows back in one call (set `APIFY_TOKEN` to your API token from Console > Settings > API & Integrations):

```bash
curl -X POST "https://api.apify.com/v2/acts/bongo-seakhoa~audio-to-text-rag-chunks/run-sync-get-dataset-items"   -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json"   -d '{"sources": [{"url": "https://example.com/episode-12.mp3"}]}'
```

The synchronous endpoint waits at most 5 minutes, which fits a few minutes of audio. For longer files, start the run and wait for it with the Python client (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("bongo-seakhoa/audio-to-text-rag-chunks").call(
    run_input={"sources": [{"url": "https://example.com/episode-12.mp3"}]}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["record_type"] == "chunk":
        print(item["time_start_s"], item["text"][:80])
```

AI agents can call the Actor as a tool through Apify's MCP server (`https://mcp.apify.com`) by adding `bongo-seakhoa/audio-to-text-rag-chunks` to the server's Actors.

### Input

```json
{
    "sources": [{ "url": "https://example.com/episode-12.mp3" }],
    "rssFeedUrl": "https://example.com/podcast/feed.xml",
    "rssMaxEpisodes": 3,
    "model": "accurate",
    "language": "auto",
    "wordTimestamps": false,
    "outputs": ["transcript", "segments", "srt", "vtt", "chunks"],
    "chunkSize": 1500,
    "chunkOverlap": 150,
    "maxMinutesPerFile": 180,
    "mode": "transcribe"
}
```

| Field | Default | What it does |
|---|---|---|
| `sources` | `[]` | Direct links to audio files, at most 500. Redirects are followed and every hop is checked. Linking a remote text file of URLs (`requestsFromUrl`) is not supported: paste the URLs. |
| `keyValueStoreId` | none | A key-value store with audio files. Without `keyValueStoreKeys`, every record whose key ends in `.mp3`, `.wav`, `.flac`, `.ogg` or `.oga`, or whose content type is audio, is used (up to 1,000). |
| `keyValueStoreKeys` | `[]` | Record keys to use from that store. |
| `rssFeedUrl` | none | A public podcast RSS 2.0 feed. Its newest episodes by publication date are transcribed from their audio enclosures. |
| `rssMaxEpisodes` | `5` | How many of the newest episodes to take (1-100). |
| `model` | `accurate` | `accurate` = Whisper base, `fast` = Whisper tiny (several times faster, less accurate, cheaper per minute). |
| `language` | `auto` | `auto` detects the language from the first speech; or force one of Whisper's 99 language codes (`en`, `de`, `es` ...). |
| `wordTimestamps` | `false` | Adds per-word times to the segments JSON. |
| `vad` | `true` | Skips silence with Silero voice activity detection before transcribing. Billing is by audio duration either way. |
| `mode` | `transcribe` | `estimate` downloads each file, reads only its duration and shows minutes and projected price, charging none of this Actor's events. |
| `outputs` | all five | Any of `transcript`, `segments`, `srt`, `vtt`, `chunks`. The plain text is always in the transcript row. |
| `chunkSize` | `1500` | Maximum characters per chunk (200-20,000). |
| `chunkOverlap` | `150` | Characters of whole trailing segments repeated in the next chunk, at most half of `chunkSize`. |
| `maxMinutesPerFile` | `180` | Longer files are cut here and marked partial (1-600). |
| `maxFileSizeMb` | `500` | Larger files fail with `FILE_TOO_LARGE` (1-2,000, and never more than a quarter of the run's memory: 512 MB at the default 2 GB). |
| `perFileTimeoutSecs` | derived | Empty: 2 minutes plus 3 times the expected transcription time of that file, at most 7,200 s. Set 60-7,200 to override. |

### Output

The dataset holds two kinds of rows, told apart by `record_type`. Filter on it when you read the dataset through the API. The examples below are rows of the bundled sample, trimmed where marked with `...`.

A transcript row (`record_type: "transcript"`):

```json
{
    "record_type": "transcript",
    "document_id": "cd841e3f564be4a6",
    "document_index": 0,
    "source": "bundled-sample:sample.mp3",
    "source_type": "sample",
    "status": "ok",
    "error_code": null,
    "file_name": "sample.mp3",
    "format": "mp3",
    "model": "accurate",
    "duration_s": 16.452,
    "minutes_billed": 0,
    "language": "en",
    "language_probability": 0.9891,
    "text": "The community library opens at 9 in the morning on weekdays and closes at 6 in the evening. Visitors can borrow up to 6 books at a time. ...",
    "transcript_url": "https://api.apify.com/v2/key-value-stores/.../records/file0001-cd841e3f564be4a6.md",
    "srt_url": "https://api.apify.com/v2/key-value-stores/.../records/file0001-cd841e3f564be4a6.srt",
    "vtt_url": "https://api.apify.com/v2/key-value-stores/.../records/file0001-cd841e3f564be4a6.vtt",
    "segments_url": "https://api.apify.com/v2/key-value-stores/.../records/file0001-cd841e3f564be4a6-segments.json",
    "segment_count": 3,
    "chunk_count": 1,
    "warnings": [],
    "charged_events": {},
    "elapsed_ms": 5593,
    "realtime_factor": 0.34
}
```

A chunk row (`record_type: "chunk"`):

```json
{
    "record_type": "chunk",
    "document_id": "cd841e3f564be4a6",
    "chunk_id": "14c0ad9be8f7fde2c5057026",
    "chunk_index": 0,
    "text": "[00:00:00] The community library opens at 9 in the morning on weekdays and closes at 6 in the evening. ...",
    "char_start": 0,
    "char_end": 290,
    "heading_path": [],
    "page_start": null,
    "page_end": null,
    "approx_tokens": 73,
    "time_start_s": 0.0,
    "time_end_s": 16.452,
    "source": "bundled-sample:sample.mp3",
    "document_index": 0
}
```

The SRT file of the same sample starts:

```
1
00:00:00,000 --> 00:00:06,400
The community library opens at 9 in the morning on weekdays and closes at 6 in the evening. Visitors can
```

Every chunk row has `document_id`, `chunk_id`, `chunk_index`, `text`, `char_start`, `char_end`, `heading_path`, `page_start`, `page_end` and `approx_tokens`, the same fields as the other Actors listed below, so their chunks can share one vector index. Audio has no pages, so `page_start` and `page_end` are always `null`; the position in the recording is in `time_start_s` and `time_end_s`. `markdown[char_start:char_end]` of the transcript file is exactly the chunk's `text`.

`minutes_billed` is what a file is billed for in minutes on a pay-per-event run (0 for the sample, estimate mode and failed files). `charged_events` lists the events actually charged for the row, with their counts, and is the authoritative record.

Row `status` is `ok`, `partial` (some audio was not transcribed: the warnings say why), `failed` (nothing transcribed; `error_code` says why) or `skipped` (not started: `CHARGE_LIMIT` when your maximum charge was reached, `TIMEOUT` when the run was about to time out). If Apify restarts a run while a file is being charged, that file is not processed again: its row carries a `BILLING_UNCERTAIN_AFTER_RESTART` warning, and its `charged_events` may not list every charge made before the restart. A restart just after a file's chunk rows were saved can repeat those rows with the same `chunk_id` (the file is charged once), so dedupe chunks by `chunk_id`. The run's key-value store also gets a `SUMMARY` record with the counts for the whole run.

Error codes: `UNSUPPORTED_FORMAT` (with the name of what was found and a conversion hint), `BLOCKED_HOST`, `BLOCKED_DESTINATION`, `RSS_PARSE_ERROR`, `DOWNLOAD_FAILED`, `FILE_TOO_LARGE`, `AUDIO_DECODE_ERROR`, `INVALID_INPUT`, `TIMEOUT`, `OUT_OF_MEMORY`, `WORKER_CRASHED`, `INTERNAL_ERROR`. Warning codes: `CHARGE_LIMIT_MINUTES`, `TIME_LIMIT`, `TRUNCATED_AT_MAX_MINUTES` and `DECODE_INCOMPLETE` (these make a file partial), and `NO_SPEECH_DETECTED`, `LOW_LANGUAGE_CONFIDENCE`, `POSSIBLE_REPETITION`.

### Pricing

This Actor is priced per event: you pay for what was transcribed.

| Event | Price | When it is charged |
|---|---|---|
| `audio-file-processed` | $0.005 | Once per file that was decoded and transcribed (status `ok` or `partial`). |
| `audio-minute-accurate` | $0.03 | Per started minute of audio transcribed in that file with the `accurate` model. |
| `audio-minute-fast` | $0.02 | Per started minute of audio transcribed in that file with the `fast` model. |

Minutes are counted per file and rounded up: a 10-second clip is 1 minute plus the file fee, and a 45 min 20 s episode is 46 minutes. A file cut by your maximum charge, `maxMinutesPerFile` or the time limit is billed only for the minutes actually transcribed. A file that decodes but holds no speech (silence, music only) is still transcribed and billed; its row says `NO_SPEECH_DETECTED`.

Apify adds the Actor start fee (`apify-actor-start`) to every run: $0.00005 per GB of run memory, so $0.0001 at the default 2 GB. Chunks, files and dataset rows are not charged separately: this Actor does not use the `apify-default-dataset-item` event.

Worked examples, at the default 2 GB:

- A 45-minute podcast episode on `accurate`: 1 x $0.005 + 45 x $0.03 + $0.0001 start fee = $1.3551.
- The same episode on `fast`: 1 x $0.005 + 45 x $0.02 + $0.0001 = $0.9051.
- Ten 30-second voice notes on `accurate` in one run: 10 x $0.005 + 10 x $0.03 + $0.0001 = $0.3501 (each file is at least 1 minute).

Never charged by this Actor: files that fail (unsupported, too large, unreachable, undecodable), files skipped at your maximum charge or the run timeout, the bundled sample, and estimate mode. Only Apify's start fee applies to those runs.

**Your maximum charge is respected.** Before each file the Actor checks what is left of your run's maximum total charge, transcribes only the minutes it can charge for, and keeps one minute's price unspent below your limit. A long file is cut at the affordable minute and marked `partial` with `CHARGE_LIMIT_MINUTES`; a file that cannot be afforded at all, and every file after it, is listed as `skipped` with `CHARGE_LIMIT` and is not charged. The run normally finishes as *Succeeded*. Rerun with a higher limit for the rest.

### Limits: read before you buy

- **Formats**: only MP3, WAV, FLAC and Ogg Vorbis are accepted, detected from the file's bytes, not its name. M4A/AAC (iPhone Voice Memos, Zoom recordings), Opus (WhatsApp voice notes), WebM and video files are refused with `UNSUPPORTED_FORMAT`, because the only decoders for them are under GPL or LGPL licences. Convert them first, for example `ffmpeg -i input.m4a -ac 1 -ar 16000 output.mp3`. A WAV whose recorder stopped before writing its header sizes fails with `AUDIO_DECODE_ERROR` and a hint to re-save it.
- **No social or streaming links**: YouTube, TikTok, Instagram, Vimeo, X/Twitter, Facebook, Twitch, SoundCloud and Spotify links (and their short links and media CDNs) are refused by design with `BLOCKED_HOST`, also when a redirect leads there. Only process audio you have the rights to, and that includes podcast feeds.
- **Accuracy**: Whisper base and tiny are the small Whisper models. They trail the larger ones, especially outside English, with accents, crosstalk, noise and specialist terms. Whisper can invent or repeat text on music, silence or noise (`POSSIBLE_REPETITION` flags the obvious cases). Review transcripts before relying on them.
- **No speaker labels and no translation**: there is no diarization (who said what) and the transcript stays in the spoken language.
- **Speed**: measured on Apify at the default 2 GB on synthetic speech clips of up to 4.4 minutes (clean, over music and in noise), `accurate` took about 20-26 s of processing per audio minute and `fast` about 8-20 s (slowest in noise), plus about 10 s per file to start the model. From those figures, a 1-hour file would take roughly 20-26 minutes on `accurate`; that is an estimate, since no longer file was measured. Real recordings with accents, crosstalk or noise can take longer. 4 GB is about 1.5 times faster; 1 GB is about half as fast. The Actor's default run timeout is 1 hour, which fits roughly 2 hours of audio on `accurate`; raise the run timeout for bigger batches. When the run or a file's time limit is reached, the transcript so far is kept, marked `partial` (`TIME_LIMIT`) and billed only for the minutes done, and files not yet started are listed as `skipped` and not charged.
- **Word timestamps** are approximate (about 0.2-0.5 s).
- **Language detection** looks at the first speech in the file. Short or noisy clips can be misdetected (`LOW_LANGUAGE_CONFIDENCE`); set `language` when you know it.
- **Files run one after another**, not in parallel. The run's disk is at least twice its memory.
- **Podcast feeds**: public RSS 2.0 only (no login, no Atom). Feeds with DTDs or entity declarations are refused for safety.
- **Links**: only public http(s) addresses are fetched, and every redirect is checked the same way. Links to private, local or cloud-metadata addresses, and links carrying a user name or password, fail with `BLOCKED_DESTINATION` and are not charged.
- **Per run**: at most 500 listed URLs, up to 1,000 records read from a key-value store and up to 100 feed episodes; files up to `maxFileSizeMb` but never more than a quarter of the run's memory.

### FAQ

**Is my audio sent to an AI service?** No. Whisper runs inside the Actor's own container on CPU, with model weights baked into the image. Nothing is sent to OpenAI or any other API.

**Why is a file `partial`?** Some of its audio was not transcribed: your maximum charge (`CHARGE_LIMIT_MINUTES`), the time limit (`TIME_LIMIT`), `maxMinutesPerFile` (`TRUNCATED_AT_MAX_MINUTES`) or a file that is damaged or cut off towards the end (`DECODE_INCOMPLETE`: the decoder stopped early, or the audio ends well before the length its header declares). You pay only for the minutes transcribed.

**Can I transcribe a YouTube video or a Spotify episode?** No, by design. Use the podcast's public RSS feed or a direct file link instead, for audio you have the rights to.

**My file is M4A or Opus.** Convert it to MP3, WAV or FLAC first (see Limits). The Actor refuses those formats rather than ship GPL or LGPL decoders.

**How do I check the price before a big batch?** Run with `mode: "estimate"`. Each file's row shows its duration, the minutes that would be billed and the projected price, and nothing is charged except Apify's start fee.

**Can I read the output from code?** Yes. See "From code or an AI agent" above: read the dataset items and filter on `record_type`, or download the files from the run's key-value store.

**Something does not work.** Open an issue on the Actor's Issues tab with the run link and, if you can share it, a file that shows the problem. Issues are read on a best-effort basis; there is no guaranteed response time.

### Privacy and data retention

The Actor reads only the URLs, feed and key-value store records you give it. Your audio is processed inside your run and is not sent anywhere else. The log contains counts, status and error codes, never file content, transcripts or URLs. The Actor keeps nothing after the run ends: the outputs live in your run's dataset and key-value store under your Apify account, and Apify's storage retention applies to them.

### More Actors from the same developer

These Actors share one output format for chunks, so their results can go into the same index:

- [PDF to Markdown & RAG Chunks](https://apify.com/bongo-seakhoa/pdf-to-markdown-rag-chunks): PDFs, tables to CSV, offline OCR.

### About the sample and the tests

The bundled sample and every test file used to develop this Actor are synthetic: generated for the purpose and labelled synthetic (see `sample/PROVENANCE.md` in the source). The sample is computer-generated speech (CMU Flite) reading a three-sentence script written for it. No third-party recordings were used.

### Licences

The Actor is proprietary software by Bongo Seakhoa. It is built on open-source components under permissive licences (faster-whisper, CTranslate2, the OpenAI Whisper weights as converted by Systran, Silero VAD, miniaudio and ONNX Runtime under MIT; Hugging Face tokenizers under Apache-2.0, among others). certifi (MPL-2.0) is included unmodified. The CTranslate2 Linux wheel also contains Intel oneMKL under the Intel Simplified Software License and the GCC runtime library libgomp under GPL-3.0 with the GCC Runtime Library Exception, both unmodified. No FFmpeg, PyAV or libsndfile is used. The full list and licence texts are in the `THIRD_PARTY_NOTICES` file shipped with the Actor image.

# Actor input Schema

## `sources` (type: `array`):

Direct links to MP3, WAV, FLAC or Ogg Vorbis files (http or https), at most 500. Redirects are followed and checked. Links to YouTube, TikTok, Instagram, Vimeo, X/Twitter, Facebook, Twitch, SoundCloud and Spotify are refused by design. Linked text files of URLs are not supported; paste the URLs.

## `keyValueStoreId` (type: `string`):

Pick a key-value store that holds audio files. Without record keys below, every record whose key ends in .mp3, .wav, .flac, .ogg or .oga (or whose content type is audio) is transcribed, up to 1,000.

## `keyValueStoreKeys` (type: `array`):

Keys of audio records in the store picked above. Leave empty to use every audio record.

## `rssFeedUrl` (type: `string`):

A public podcast RSS 2.0 feed. Its newest episodes (by publication date) are transcribed from their audio enclosures. Feeds that need a login are not supported. Only process audio you have the rights to.

## `rssMaxEpisodes` (type: `integer`):

How many of the feed's newest episodes to transcribe.

## `model` (type: `string`):

'accurate' uses Whisper base; 'fast' uses Whisper tiny (several times faster, less accurate, cheaper per minute). Both are multilingual and run on CPU inside the Actor.

## `language` (type: `string`):

'auto' detects the spoken language from the first speech in the file. Set an ISO code (for example 'en', 'de', 'es') when you know it: detection can be wrong on short or noisy clips.

## `wordTimestamps` (type: `boolean`):

Adds start and end times for every word to the segments JSON file. They are approximate (about 0.2-0.5 s).

## `vad` (type: `boolean`):

Runs Silero VAD first and transcribes only the parts with speech: faster, and fewer made-up words on silence and music. Billing is by audio duration either way.

## `mode` (type: `string`):

'transcribe' produces the transcript and the files. 'estimate' downloads each file and only reads its duration and shows the minutes and price a transcription would cost. Estimate charges none of this Actor's events (Apify's standard Actor start fee still applies).

## `outputs` (type: `array`):

Which outputs to produce. The plain transcript text is always in the file's dataset row. These add the Markdown transcript with \[hh:mm:ss] stamps, the segments JSON, SRT and WebVTT subtitle files, and RAG chunk rows.

## `chunkSize` (type: `integer`):

Maximum characters per RAG chunk. Chunks end on segment boundaries, so most are a little shorter.

## `chunkOverlap` (type: `integer`):

Up to this many characters of whole trailing segments are repeated at the start of the next chunk. At most half the chunk size.

## `maxMinutesPerFile` (type: `integer`):

Longer files are cut here and marked partial (TRUNCATED_AT_MAX_MINUTES); you pay only for the minutes transcribed.

## `maxFileSizeMb` (type: `integer`):

Larger files fail with FILE_TOO_LARGE and are not charged. The limit is also capped at a quarter of the run's memory (512 MB at the default 2 GB).

## `perFileTimeoutSecs` (type: `integer`):

Leave empty to let the Actor set it from the file's duration and the model (2 minutes plus 3 times the expected time, at most 7,200 s). When a file reaches 80% of it, the transcript so far is kept, marked partial (TIME_LIMIT) and billed only for the minutes transcribed.

## Actor input object example

```json
{
  "sources": [],
  "keyValueStoreKeys": [],
  "rssMaxEpisodes": 5,
  "model": "accurate",
  "language": "auto",
  "wordTimestamps": false,
  "vad": true,
  "mode": "transcribe",
  "outputs": [
    "transcript",
    "segments",
    "srt",
    "vtt",
    "chunks"
  ],
  "chunkSize": 1500,
  "chunkOverlap": 150,
  "maxMinutesPerFile": 180,
  "maxFileSizeMb": 500
}
```

# Actor output Schema

## `results` (type: `string`):

One row per audio file (record_type 'transcript') and per RAG chunk ('chunk').

## `files` (type: `string`):

Markdown transcript, SRT, WebVTT and segments JSON per file, plus the SUMMARY record, in the run's key-value store.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("bongo-seakhoa/audio-to-text-rag-chunks").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("bongo-seakhoa/audio-to-text-rag-chunks").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call bongo-seakhoa/audio-to-text-rag-chunks --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bongo-seakhoa/audio-to-text-rag-chunks"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/sOBb15DPCyorhaXpw/builds/Di0Tf2gUVD06vLtho/openapi.json
