# TikTok Video Transcript — AI Video to Text & SRT (`andronixmd/tiktok-video-transcript`) Actor

Get a TikTok transcript from any public video with AI speech-to-text, even without captions. Paste video or share links; get timestamped text, SRT/VTT subtitles for vertical video, speaker labels and RAG-ready JSONL. No login or API key. $0.013 per 1-minute video + $0.005 per run.

- **URL**: https://apify.com/andronixmd/tiktok-video-transcript.md
- **Developed by:** [Sergey Andronik](https://apify.com/andronixmd) (community)
- **Categories:** Social media, AI, Videos
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.20 / 1,000 audio minutes

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

Get a **TikTok transcript** from any public TikTok video, with timestamps, as JSON, SRT
or VTT. TikTok Video Transcript turns TikTok video to text with AI speech-to-text, so it
works whether or not the video has captions. Paste one link or a list of up to 1,000 and
get one result per video: the full text, timed segments, subtitle files laid out for
vertical video, optional speaker labels and optional RAG-ready passages for search,
summaries or content analysis. No TikTok login, cookies or speech-provider API key are
needed.

### What you get for each TikTok video

- **Transcript text** in `text`, plus `transcript_llm` with one line per segment, ready
  to paste into an LLM prompt.
- **Timestamps** per segment (`t0`, `t1` in seconds), or per word with
  `timestamps: "word"`.
- **SRT and VTT subtitles** in the result and as downloads in the run's key-value store
  (`transcript-000.srt`, `transcript-000.vtt`, numbered by input position).
- **Subtitle QA for short video:** cues laid out at 28 characters per line by default,
  with a report of lines that are too long, too fast or too short.
- **Readable paragraphs** in `paragraphs` (`start_s`, `end_s`, `speaker`, `text`) and as
  `transcript-000.txt` and `transcript-000.md` downloads, at no extra charge. See
  [Readable output](#readable-output).
- **Speaker labels** (S1, S2, …) with `diarize: true`.
- **RAG passages** with source URL and original-video seconds, inline as `rag_chunks`
  and as a `transcript-000.rag.jsonl` download, with `exportRag: true`.
- **Language detection**, or a language hint you set.
- **Billing per item:** every row shows which events were charged, so you can match the
  bill to the videos.

### How to get a TikTok transcript

1. **Paste your video URLs.** Use full `tiktok.com/@user/video/…` links or the short
   `vm.tiktok.com/…`, `vt.tiktok.com/…` and `tiktok.com/t/…` share links.
2. **Keep the defaults or adjust them.** The defaults give segment timestamps and the
   short-video subtitle layout. Add a language hint, speaker labels or RAG passages if
   you need them.
3. **Set a run budget.** In the run options, set a maximum charge for the run. The run
   stops before work it cannot pay for.
4. **Start the run and open the Dataset.** Each URL becomes one row. Export it as JSON,
   CSV or Excel, or read it through the API. Download SRT and VTT files from the run's
   key-value store.

### Input

```json
{
  "urls": ["https://www.tiktok.com/@bbcnews/video/7654853125945183510"],
  "timestamps": "segment",
  "subtitleProfile": "short"
}
```

| Field | What it does |
|---|---|
| `urls` | Up to 1,000 public TikTok video URLs. Required unless you set `datasetId`. |
| `datasetId` | Read URLs from another run's dataset. See [Chain from another Actor](#chain-from-another-actor). |
| `datasetUrlField`, `maxItems` | The dataset field that holds the URL (detected when empty), and how many rows to read (default 100, at most 1,000). |
| `language` | Optional language code such as `en`, `es` or `pt-BR`. Omit it for automatic detection. |
| `timestamps` | `none` (text only: no `segments`, `words`, SRT or VTT), `segment` (default) or `word`. |
| `subtitleProfile` | `short` (28 characters per line, 0.5–4 s cues) or `standard` (42 characters per line, 1–7 s cues). Longer segments are split into cues within their time range, and the subtitle QA report is added. When you leave it empty and timestamps are on, `short` is used. Needs segment or word timestamps, so leave it empty with `timestamps: "none"`. |
| `diarize` | Speaker labels. Billed at the speaker-label rate instead of the normal per-minute rate. |
| `exportRag` | Adds `rag_chunks` and a `.rag.jsonl` download. Needs segment or word timestamps. |

### Start from a profile

Put public profile URLs in **TikTok profiles** (`profileUrls`) to transcribe their newest videos:

```json
{
  "profileUrls": ["https://www.tiktok.com/@bbcnews"],
  "maxItemsPerSource": 10,
  "publishedAfter": "2026-10-01"
}
```

- Profile URLs look like `https://www.tiktok.com/@bbcnews`. The newest videos are listed and sorted by date, so pinned videos do not crowd out new ones.
- Each row adds `source_url`, `source_type` (`tiktok_profile`) and `source_title`.
- `publishedAfter` (YYYY-MM-DD, UTC) uses the exact upload time from the listing.
- TikTok's profile listing fails intermittently (in tests from one network on 2026-10-31, 4 of 10 attempts succeeded), so each profile is tried up to 3 times with a pause between tries.
- Rows of listed videos also carry `published_at`, the upload time from the listing.
- `maxItemsPerSource` (default 20, at most 200) limits how many of the newest items each source contributes. A run holds at most 1,000 items in total, counting `urls` and dataset rows.
- Each listed item is processed and charged exactly like a URL you submit. Listing itself is free.
- The example link in the URL list is processed and charged too: remove it when you want only listed items.
- Listed items run after `urls` and dataset rows, source by source in input order; an item already in the run is skipped.
- A source that cannot be listed becomes one error row with `source_url` and an `error` naming it (for example `profileUrls[1]: …`), and it is not charged. The other sources continue. If no source lists anything, the run fails before any charge.
- The listing is saved when the run starts, so a restarted run keeps the same items even if the source changed meanwhile.

### Scheduled runs: only new items

Turn on **Skip items processed by earlier runs** (`skipPreviouslyProcessed`) and run the
Actor on a [schedule](https://docs.apify.com/platform/schedules) to get only what is new
since the last run.

- The Actor keeps a key-value store named `polyglot-processed-tiktok` in your Apify
  account, or `polyglot-processed-tiktok--<memoryKey>` when you set **Memory name**
  (`memoryKey`), so separate schedules can keep separate memories. Other Actors keep
  their own stores, even with the same `memoryKey`. It records each item after the item
  is delivered and charged; failed items are tried again next time.
- It applies to every URL in the run: listed ones, dataset rows and the items listed
  from sources.
- When nothing is new, the run ends without any charge. Only error rows appear then, for
  sources or dataset rows that could not be used.
- If the store cannot be opened or read, the run stops before any charge, and the next
  scheduled run tries again. If an item's record cannot be written, the item is still
  delivered and the log says so; a later run may process and charge it again.
- Delete the store in Apify Console (Storage → Key-value stores) to start over. Do not run
  two runs with the same memory at the same time: both would process the same new items.

### Chain from another Actor

Run a TikTok scraper such as clockworks/tiktok-scraper first, then paste the dataset ID of that run into **Dataset ID**
(`datasetId`) to transcribe every one of its TikTok videos:

```json
{ "datasetId": "<dataset ID from the other run>", "maxItems": 200 }
```

- The Actor reads up to `maxItems` rows (default 100) with your own run's Apify token and
  takes each row's URL from `webVideoUrl`, `url`, `postUrl`, `videoUrl`, `inputUrl` or `link`, or from the field you name in `datasetUrlField`.
- Dataset URLs run after any `urls` you list, in dataset order; a dataset URL that is
  already in the run is skipped. A run takes at most 1,000 URLs in total.
- A row without a usable URL becomes an error item with its `dataset_row` index, and it is
  not charged. Items from the dataset also carry `dataset_row`, so you can join the results
  back to the source rows.
- The example link in the URL list is processed and charged too: remove it when you want only the dataset's items.

### Output example

A real result from an Apify run on 2026-10-30, trimmed: 3 of 12 segments, the text cut,
and the SRT, VTT and QA fields shortened.

```json
{
  "url": "https://www.tiktok.com/@bbcnews/video/7654853125945183510",
  "text": "If that's not a leader, I don't know what is. I think Harry Kane because he's a great leader, he's cool under pressure. …",
  "language": "en",
  "duration_s": 42.98,
  "engine": "groq/whisper-large-v3",
  "segments": [
    { "t0": 0, "t1": 2.08, "text": "If that's not a leader, I don't know what is." },
    { "t0": 2.3, "t1": 5.98, "text": "I think Harry Kane because he's a great leader, he's cool under pressure." },
    { "t0": 6.6, "t1": 8.04, "text": "Yeah, it's got to be Harry Kane for me." }
  ],
  "srt": "1\n00:00:00,000 --> 00:00:02,080\nIf that's not a leader, I\ndon't know what is.\n\n…",
  "subtitle_qa": { "profile": "short", "cue_count": 12, "issue_count": 18, "issues": [{ "cue_number": 1, "code": "reading_speed", "actual": 21.6, "limit": 20 }] },
  "usage": { "minutes": 1, "diarized": false, "platform_fetch": true },
  "billing": {
    "status": "paid",
    "events": [
      { "event": "platform-video-fetch", "requested_count": 1, "charged_count": 1, "state": "confirmed" },
      { "event": "audio-minute", "requested_count": 1, "charged_count": 1, "state": "confirmed" }
    ]
  }
}
```

Clips with little speech or loud music can have their language misdetected. If you know
the language, set it, for example `"language": "en"`.

Results also contain `vtt`, `transcript_llm`, `source_duration_s`, `start_time_s` and
`end_time_s`. A URL that fails returns a row with `url` and `error`. Very large results
may carry `result_record_key` instead of inline text; read that key from the run's
key-value store.

### Readable output

Every transcript row has `paragraphs`: the transcript in order, grouped into blocks you can
read. A paragraph starts at a speaker change, after a pause of 2 seconds or more, and
before it would pass 800 characters or 90 seconds. Once it holds 400 characters, the next
sentence end closes it. No text is dropped or reordered, and a segment is never split in
timed output. Each paragraph is `{ "start_s", "end_s", "speaker", "text" }`; `speaker` appears
only with `diarize: true`, and with `timestamps: "none"` there are no times and paragraphs
are cut at sentence ends by length alone. Rows without speech have no `paragraphs`.

The same paragraphs are saved to the run's key-value store, numbered by input position:

- `transcript-000.txt`: paragraphs separated by blank lines, with `S1:` style speaker labels.
- `transcript-000.md`: a title when known, a list with the source URL, language and duration (and the author name when known), then
  each paragraph with its `[mm:ss]` (or `[h:mm:ss]`) start time and bold speaker label.

When a row would pass the Dataset size limit, `paragraphs` is left out of the row first
(the text stays) and the downloads still hold it. Both downloads are free, like SRT and VTT.

### How much does a TikTok transcript cost?

Pay per event, with no subscription. These are the Free-plan prices; paid Apify plans
get lower per-minute prices. The [Pricing tab](https://apify.com/andronixmd/tiktok-video-transcript/pricing)
shows the current prices for your plan.

| Event | Price | When |
|---|---:|---|
| Run setup | $0.005 | Once per run. |
| TikTok video download | $0.005 | Per video whose audio was downloaded. |
| Audio minute | $0.008 | Per started minute of video, after transcription succeeds. |
| Diarized audio minute | $0.016 | Per started minute with speaker labels, instead of the audio minute. |

Worked examples, without speaker labels:

| Video length | 1 URL in a run | 100 URLs in a run |
|---|---:|---:|
| 1 minute or shorter | $0.005 + $0.005 + $0.008 = **$0.018** | $0.005 + 100 × $0.013 = **$1.305** |
| 3 minutes | $0.005 + $0.005 + 3 × $0.008 = **$0.034** | $0.005 + 100 × $0.029 = **$2.905** |
| 10 minutes | $0.005 + $0.005 + 10 × $0.008 = **$0.090** | $0.005 + 100 × $0.085 = **$8.505** |

With speaker labels, a 1-minute video costs $0.026 alone, and 100 of them cost
$0.005 + 100 × $0.021 = $2.105.

- Minutes are rounded up once per video, and silence counts. A 61-second video is
  2 minutes.
- A video with no detected speech (only music, silence or noise) returns
  `no_speech: true` with empty text and is not charged minutes, up to 30 such minutes per
  run; after that its minutes are charged. The download fee still applies.
- Put many URLs in one run: the run setup fee is paid once per run, not per video.
- A failed download is not charged, and neither is a download that is not a playable
  audio or video file. A successful download stays charged if the transcription fails
  afterwards.
- Apify's own small run-start event is separate and is shown on the Pricing tab.

### Use it from the API

Start a run with the [Apify API client for JavaScript](https://docs.apify.com/api/client/js/)
and read the results:

```js
import { ApifyClient } from 'apify-client'

const client = new ApifyClient({ token: process.env.APIFY_TOKEN })
const run = await client.actor('andronixmd/tiktok-video-transcript').call(
  { urls: ['https://www.tiktok.com/@bbcnews/video/7654853125945183510'] },
  { maxTotalChargeUsd: 0.1 },
)
const { items } = await client.dataset(run.defaultDatasetId).listItems()
for (const item of items) console.log(item.url, item.error ?? item.text)
```

Or start one run over HTTP:

```sh
curl -X POST \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"urls":["https://www.tiktok.com/@bbcnews/video/7654853125945183510"]}' \
  'https://api.apify.com/v2/actors/andronixmd~tiktok-video-transcript/runs?maxTotalChargeUsd=0.1'
```

The Actor also works from n8n and other automation tools through Apify's integrations.

#### Use it from an AI agent (MCP)

Connect your agent to `https://mcp.apify.com`. It can find this Actor with `search-actors`, or
call it by name, `andronixmd/tiktok-video-transcript`, with `call-actor`. Use `fetch-actor-details` first for the
input schema and pricing. Every call starts a new paid run, so always set
`callOptions.maxTotalChargeUsd` and keep the `urls` list short:

```json
{ "actor": "andronixmd/tiktok-video-transcript", "input": { "urls": ["https://www.tiktok.com/@bbcnews/video/7654853125945183510"], "timestamps": "segment", "subtitleProfile": "short" }, "callOptions": { "maxTotalChargeUsd": 0.1 } }
```

`call-actor` returns the run status and storage IDs, not the results. Read the rows with
`get-dataset-items` and the run's dataset ID. The fields to use are `text`, `paragraphs` and `error`.

With an Apify account, use your API token or MCP OAuth. Without one, an agent can buy a prepaid token from [Apify AGI](https://agi.apify.com) over
x402 or MPP and use it as the Bearer token. It starts at $1, the balance is a hard spending cap,
and the token expires after 14 days. This is experimental; see
[agentic payments](https://docs.apify.com/agents/payments).

### Limitations

- **Public videos only.** Private, friends-only, age-restricted, region-blocked and
  removed videos, and anything that needs a login, are not supported. The Actor uses no
  accounts or cookies and does not try to get around TikTok's access checks.
- **Videos and profiles.** Hashtag, search, sound, photo-post and live URLs are not
  accepted; profiles go in `profileUrls`. Profile listing from Apify's servers has not
  been tested at scale. One URL in a wrong format rejects the whole input before the run starts. A short link
  that has expired or leads to something other than a video fails for that item only.
- **Not every public video will download.** TikTok limits access from some networks and
  regions and changes its site often, so some URLs return an error row instead of a
  transcript. Check each row's `error` and `billing` fields and retry failed URLs later.
- **Spoken audio only.** Text drawn into the picture is not read. When TikTok lists the
  licensed music as a separate track, that track is not transcribed.
- **Music-only videos** can come back with lyrics or artefacts like the one in the
  example above, which are billed as speech. A video detected as having no speech is
  billed its minutes only after the run's 30 free no-speech minutes.

### FAQ

**Does it use TikTok's captions?**
No. It transcribes the audio, so it also works on videos without captions or
subtitles.

**Which languages does it support?**
It detects the language automatically, and the supported languages depend on the
speech engine. For short clips with music, a language hint such as `en`, `es` or `de`
gives better results.

**Can I transcribe a whole TikTok profile or hashtag?**
A profile, yes: put it in `profileUrls` and set `maxItemsPerSource`. Hashtags, no.

**Can I get SRT subtitles for a TikTok video?**
Yes. With segment or word timestamps (segment is the default), each result contains
`srt` and `vtt`, and the files are saved in the run's key-value store.

**What happens if a video fails?**
You get a row with `url` and `error`. A failed download is not charged.

**Do you store my transcripts or audio?**
Results stay in your Apify run storage, under your account's access and retention
settings. The audio is sent to the speech-to-text provider that transcribes it. Only
submit videos you are allowed to process.

### Related Actors

- [TikTok Video Scraper](https://apify.com/andronixmd/tiktok-scraper): views, likes,
  hashtags, author and music for the same URLs, without the transcript, for $0.002 per
  video. Submit the same URLs to both and join the results on `url`.
- [Instagram Reel Transcript](https://apify.com/andronixmd/instagram-reel-transcript):
  the same transcript output for Instagram Reels.
- [YouTube Transcript](https://apify.com/andronixmd/youtube-transcript): YouTube
  captions, with AI speech-to-text when a video has none.
- [Audio & Video Transcriber](https://apify.com/andronixmd/speech-to-text-transcriber):
  podcasts, audio and video files and other sites.

# Actor input Schema

## `urls` (type: `array`):

Public TikTok video links, one transcript per URL. Accepted forms: tiktok.com/@user/video/<id>, vm.tiktok.com/<code>, vt.tiktok.com/<code> and tiktok.com/t/<code>. Profile URLs go in TikTok profiles below; photo, tag, sound and live URLs are rejected. Submit up to 1,000 URLs, or leave this list empty and fill in TikTok profiles or Dataset ID below.

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

Optional BCP-47 language code, for example en, ru or pt-BR, that guides recognition. Omit it for automatic language detection; an empty string is invalid. Detection and language support depend on the speech engine.

## `timestamps` (type: `string`):

Choose no timestamps, segment timestamps (subtitle-style lines) or word timestamps. Segment and word output includes SRT and VTT when valid cues are available. Subtitle profiles and RAG passages need segment or word timing. Timed lines are in the segments array (word timing in words): read the whole field (fields=segments), because dotted paths such as segments.t0 return nothing.

## `subtitleProfile` (type: `string`):

Caption layout and an advisory QA report. Short video (28 characters per line, 0.5–4 s cues) suits vertical clips and is the default whenever timestamps are on and this field is empty. Requires segment or word timestamps: clear it when you choose no timestamps. Cues over the line or duration limits are split inside their segment's time range; segments keep their original times, and warnings do not stop transcription.

## `diarize` (type: `boolean`):

Identify speakers (S1, S2, …). Billed at the premium per-minute rate. Whole-video labels are S1/S2; independently processed chunks use C1_S1/C2_S1, so read speaker_scope in each result.

## `exportRag` (type: `boolean`):

Return rag_chunks and transcript-NNN.rag.jsonl with passage text, original-video seconds, source URL and versioned document identity. Requires segment or word timestamps. Embeddings and indexing remain downstream steps.

## `profileUrls` (type: `array`):

Public profile URLs such as https://www.tiktok.com/@bbcnews. The newest videos are listed (pinned videos are sorted by date), and each is processed exactly like a video URL above; each row names the profile it came from. TikTok profile listings fail intermittently, so each is tried up to 3 times; a profile that still fails becomes an error row that is not charged. Up to 100 profiles. The example URL above is processed and charged too: remove it if you want only listed videos.

## `maxItemsPerSource` (type: `integer`):

List at most this many of the newest videos from each source (up to 200). Each listed item is processed and billed like a URL you submit; listing itself is free. A run holds at most 1,000 items in total, counting URLs and dataset rows.

## `publishedAfter` (type: `string`):

Optional date as YYYY-MM-DD (UTC). Items published before this day are left out. TikTok listings give exact dates.

## `datasetId` (type: `string`):

The example URL above is processed and charged too: remove it if you want only the dataset's items. Pick the dataset, or paste its ID, from a TikTok Scraper run (for example clockworks/tiktok-scraper) to transcribe every video it found. The Actor reads the rows with your run's own token and processes each row's URL like a URL above, after the listed URLs. Rows without a usable URL become uncharged error items. A named dataset works as username~dataset-name.

## `datasetUrlField` (type: `string`):

Optional. The row field that holds the URL, for example webVideoUrl, or a dotted path such as video.url. Leave it empty to use the first accepted URL from webVideoUrl, url, postUrl, videoUrl, inputUrl or link.

## `maxItems` (type: `integer`):

Read at most this many dataset rows, in dataset order. A run processes at most 1,000 URLs in total, counting the list above.

## `skipPreviouslyProcessed` (type: `boolean`):

Remember every item that was delivered and charged, in a key-value store in your Apify account, and skip those items in later runs. Use it with a schedule to get only new videos or episodes. Items that failed are tried again next time. When every item was already processed, the run ends without any charge. If the store cannot be read, the run stops before any charge and the next run tries again.

## `memoryKey` (type: `string`):

Optional. Keeps a separate memory for this schedule, for example my-weekly-podcasts. The store is named polyglot-processed-tiktok--<name>, and other Actors never share it; without a name every run of this Actor shares polyglot-processed-tiktok. Delete the store in Apify Console (Storage, Key-value stores) to start over. Used only with the option above.

## Actor input object example

```json
{
  "urls": [
    "https://www.tiktok.com/@bbcnews/video/7654853125945183510"
  ],
  "timestamps": "segment",
  "subtitleProfile": "short",
  "diarize": false,
  "exportRag": false,
  "maxItemsPerSource": 20,
  "maxItems": 100,
  "skipPreviouslyProcessed": false
}
```

# Actor output Schema

## `transcripts` (type: `string`):

One Dataset item per processed URL, with transcript text, source timestamps, conditional products, confirmed billing and errors. Oversized items link to their full saved result via result_record_key.

## `downloads` (type: `string`):

Plain-text (.txt) and Markdown (.md) transcripts in paragraphs, SRT/VTT files when timed cues are available, subtitle-qa.json when subtitleProfile is selected and JSONL when exportRag is enabled. Keys use the zero-based input position, for example transcript-000.txt. Unavailable downloads are reported in artifact_errors.

## `savedResults` (type: `string`):

The item- collection includes signed item-NNN-result records and processing journals. A result record wraps the complete item in value; use result_record_key when a Dataset row contains only metadata. Access follows run-storage permissions.

# 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 = {
    "urls": [
        "https://www.tiktok.com/@bbcnews/video/7654853125945183510"
    ],
    "subtitleProfile": "short"
};

// Run the Actor and wait for it to finish
const run = await client.actor("andronixmd/tiktok-video-transcript").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 = {
    "urls": ["https://www.tiktok.com/@bbcnews/video/7654853125945183510"],
    "subtitleProfile": "short",
}

# Run the Actor and wait for it to finish
run = client.actor("andronixmd/tiktok-video-transcript").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 '{
  "urls": [
    "https://www.tiktok.com/@bbcnews/video/7654853125945183510"
  ],
  "subtitleProfile": "short"
}' |
apify call andronixmd/tiktok-video-transcript --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,andronixmd/tiktok-video-transcript"
        }
    }
}
```

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/NKrD8JqaJWJgpGqea/builds/qpq1Bgpnmg7rpEaaJ/openapi.json
