# TikTok Live Recorder (`maximedupre/tiktok-live-recorder`) Actor

Record one active public TikTok Live broadcast as stored MP4 segments with a matching row for each segment. Choose a username, profile or live URL, or live-room ID, set a limit or record until the broadcast ends, and get room, creator, audience, permission, stream, and delivered interaction data.

- **URL**: https://apify.com/maximedupre/tiktok-live-recorder.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Videos, Social media, Developer tools
- **Stats:** 2 total users, 1 monthly users, 85.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 recording seconds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### 🎥 Capture TikTok LIVE as MP4 segments

Developers and data teams can record one active public TikTok Live broadcast and get stored MP4 segments with a matching dataset row for each completed segment. Each row keeps the room, stream session, creator, audience, commerce and interaction permissions, delivered interactions, selected stream quality, and available variants so you can archive or process live video with its context.

- Use [**Automatically record TikTok Live streams**](https://apify.com/maximedupre/tiktok-live-recorder/examples/automatically-record-tiktok-live-streams) to capture an active public broadcast as MP4 segments while it is live.
- Follow [**How to record TikTok Live on Android**](https://apify.com/maximedupre/tiktok-live-recorder/examples/how-to-record-tiktok-live-on-android) when your workflow starts with a public TikTok username, profile URL, or live-room URL.
- Follow [**How to record TikTok Live on iPhone**](https://apify.com/maximedupre/tiktok-live-recorder/examples/how-to-record-tiktok-live-on-iphone) to save structured segment data for a mobile-led workflow.
- Run [**TikTok Live Recorder Online**](https://apify.com/maximedupre/tiktok-live-recorder/examples/tiktok-live-recorder-online) when you need downloadable MP4 segments and structured room data in an Apify run.
- Use [**How to record TikTok Live on PC**](https://apify.com/maximedupre/tiktok-live-recorder/examples/how-to-record-tiktok-live-on-pc) to send completed segment files and rows into your next data step.

#### 📦 TikTok LIVE segment data

Each completed segment produces one stored MP4 file and one matching Dataset row. The row keeps source values when TikTok provides them, including room and stream identity, creator details, audience counts, permissions, delivered interactions, and stream variants.

#### ▶️ Start a TikTok LIVE capture

**Quick start**

1. Choose **Username**, **Profile or live URL**, or **Live-room ID** and fill only the matching field.
2. Set **Maximum capture time (seconds)**, choose **Recording quality**, and decide whether to turn on **Wait for the live to start**.
3. Start the run. Open the Dataset for segment rows and the run's default Key-Value Store for stored MP4 files.

**Shorten the run**

Use a positive maximum capture time to stop capture sooner. Keep **Wait for the live to start** off when you do not want to wait at startup. Automatic recording quality uses the best quality exposed by the live stream.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `discoveryMethod` | string | Required. Select `username`, `profileOrLiveUrl`, or `liveRoomId` to choose how to identify one public TikTok Live broadcast. |
| `username` | string | Enter one public TikTok username when `discoveryMethod` is `username`. |
| `profileOrLiveUrl` | string | Enter one TikTok profile URL or live-room URL when `discoveryMethod` is `profileOrLiveUrl`. |
| `liveRoomId` | string | Enter one TikTok Live room identifier when `discoveryMethod` is `liveRoomId`. |
| `maxDurationSeconds` | integer | Set a positive number of seconds to stop capture. Leave it empty to record until the live broadcast ends. The run then returns all available results until the source is exhausted. |
| `recordingQuality` | string | Choose a quality exposed by the live stream. Use `auto` for the best available quality, or request a suggested quality such as `1080p`, `720p`, `480p`, or `360p`. |
| `waitForLive` | boolean | Turn this on to wait when the target is not live at run start. With it off, the run does not wait for a live broadcast to start. |

**Example input**

This is the public input from a successful default-input run.

```json
{
  "discoveryMethod": "username",
  "username": "jimmieislive",
  "maxDurationSeconds": 15,
  "recordingQuality": "auto",
  "waitForLive": false
}
```

#### 🧾 Output

**Run output**

| Field | Type | What it does |
| --- | --- | --- |
| `datasetUrl` | string (URL) | Opens the Dataset with one row for each completed MP4 segment and its captured data. |

**Dataset row**

Each Dataset row has one shape. Nested paths below use dotted names so you can map the row into your own data model. Optional values may be empty or absent when TikTok does not expose them.

| Field | Type | What it does |
| --- | --- | --- |
| `segment` | object | Details for one completed video segment. |
| `segment.outcome` | string | Reports `completed` for a completed segment. |
| `segment.number` | integer | One-based segment order in the recording. |
| `segment.startedAt` | string | Source time when capture of this segment started. |
| `segment.endedAt` | string | Source time when capture of this segment ended. |
| `segment.durationSeconds` | number | Captured segment length in seconds. |
| `segment.file` | object | Details for the stored MP4 file for this segment. |
| `segment.file.downloadUrl` | string | URL for downloading the stored segment file. |
| `segment.file.fileName` | string | Name of the stored segment file. |
| `segment.file.format` | string | File format, which is `mp4`. |
| `segment.file.delivery` | string | File delivery method, which is `stored`. |
| `room` | object | TikTok Live room linked to this segment. |
| `room.id` | string | TikTok Live room identifier. |
| `room.title` | string | Title shown for the live room, when available. |
| `room.visibility` | string | Visibility reported by TikTok for the live room, when available. |
| `room.state` | string | Room state reported by TikTok, when available. |
| `room.startedAt` | string | Source time when the live room started, when available. |
| `streamSession` | object | Stream session that delivered this segment. |
| `streamSession.id` | string | Source stream-session identifier. |
| `streamSession.startedAt` | string | Source time when the stream session started, when available. |
| `streamSession.endedAt` | string | Source time when the stream session ended, when available. |
| `creator` | object | Available profile details for the live creator. |
| `creator.id` | string | Creator identifier reported by TikTok, when available. |
| `creator.username` | string | Creator username, when available. |
| `creator.displayName` | string | Creator name shown to viewers, when available. |
| `creator.bio` | string | Creator biography, when available. |
| `creator.avatarUrl` | string | Creator profile image URL, when available. |
| `creator.verified` | boolean | Whether TikTok marks the creator as verified, when available. |
| `audience` | object | Audience and engagement measures reported during capture. |
| `audience.viewerCount` | integer | Number of viewers reported by TikTok, when available. |
| `audience.likeCount` | integer | Number of likes reported by TikTok, when available. |
| `audience.commentCount` | integer | Number of comments reported by TikTok, when available. |
| `audience.shareCount` | integer | Number of shares reported by TikTok, when available. |
| `audience.followCount` | integer | Number of follows reported by TikTok, when available. |
| `audience.giftCount` | integer | Number of gifts reported by TikTok, when available. |
| `audience.fanActivityCount` | integer | Fan activity measure reported by TikTok, when available. |
| `commerce` | object | Commerce and interaction permissions reported by TikTok. |
| `commerce.shopEnabled` | boolean | Whether TikTok reports a shop for the live room, when available. |
| `commerce.businessAccount` | boolean | Whether TikTok marks the creator account as a business account, when available. |
| `commerce.interactionPermissions` | object | Permissions for interactions reported by TikTok. |
| `commerce.interactionPermissions.comments` | boolean | Whether comments are allowed, when available. |
| `commerce.interactionPermissions.gifts` | boolean | Whether gifts are allowed, when available. |
| `commerce.interactionPermissions.likes` | boolean | Whether likes are allowed, when available. |
| `commerce.interactionPermissions.shares` | boolean | Whether shares are allowed, when available. |
| `commerce.interactionPermissions.follows` | boolean | Whether follows are allowed, when available. |
| `interactions` | array of objects | Timestamped live interactions delivered during capture. |
| `interactions[].id` | string | Source interaction identifier, when available. |
| `interactions[].occurredAt` | string | Source time when the interaction occurred. |
| `interactions[].eventType` | string | Type of live interaction. |
| `interactions[].participant` | object | Participant context reported for the interaction, when available. |
| `interactions[].participant.id` | string | Participant identifier, when available. |
| `interactions[].participant.username` | string | Participant username, when available. |
| `interactions[].participant.displayName` | string | Participant name shown for the interaction, when available. |
| `interactions[].message` | string | Text attached to the interaction, when available. |
| `interactions[].gift` | object | Gift details attached to the interaction, when available. |
| `interactions[].gift.id` | string | Gift identifier, when available. |
| `interactions[].gift.name` | string | Gift name, when available. |
| `interactions[].gift.count` | integer | Number of gifts in the interaction, when available. |
| `interactions[].gift.diamondCount` | integer | Gift diamond count, when available. |
| `interactions[].amount` | number | Numeric amount attached to the interaction, when available. |
| `interactions[].currency` | string | Currency for the interaction amount, when available. |
| `interactions[].likeCount` | integer | Like count attached to the interaction, when available. |
| `interactions[].shareCount` | integer | Share count attached to the interaction, when available. |
| `interactions[].followCount` | integer | Follow count attached to the interaction, when available. |
| `stream` | object | Selected stream quality and variants exposed during capture. |
| `stream.selectedQuality` | string | Stream quality used for this segment. |
| `stream.variants` | array of objects | Stream-quality variants exposed by TikTok during capture. |
| `stream.variants[].quality` | string | Quality label for the stream variant. |
| `stream.variants[].width` | integer | Stream width in pixels, when available. |
| `stream.variants[].height` | integer | Stream height in pixels, when available. |
| `stream.variants[].bitrateKbps` | number | Stream bitrate in kilobits per second, when available. |
| `stream.variants[].codec` | string | Stream codec, when available. |
| `stream.variants[].format` | string | Format of the stream variant, when available. |

**Example dataset row**

This is one complete row from a successful current-beta run. The values are shown as returned.

```json
{
  "segment": {
    "outcome": "completed",
    "number": 1,
    "startedAt": "2026-08-29T17:44:14.710Z",
    "endedAt": "2026-08-29T17:44:35.404Z",
    "durationSeconds": 15.044,
    "file": {
      "downloadUrl": "https://api.apify.com/v2/key-value-stores/Keb76OsQeHtevPM8c/records/live-7679487266922334998-1.mp4?signature=1i8YTBMGUctHxkNz7USrf",
      "fileName": "live-7679487266922334998-1.mp4",
      "format": "mp4",
      "delivery": "stored"
    }
  },
  "room": {
    "id": "7679487266922334998",
    "title": "Je parle juste fort...",
    "visibility": "public",
    "state": "live",
    "startedAt": "2026-08-29T16:13:11.000Z"
  },
  "streamSession": {
    "id": "1272913494955525453",
    "startedAt": "2026-08-29T16:13:11.000Z",
    "endedAt": "2026-08-29T16:13:11.000Z"
  },
  "interactions": [
    {
      "occurredAt": "2026-08-29T17:44:14.774Z",
      "eventType": "like",
      "id": "7679510850956461077",
      "participant": {
        "id": "7267779356586902530",
        "username": "hideya721",
        "displayName": "🐇ひでや🐇"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:15.305Z",
      "eventType": "like",
      "id": "7679510853074338848",
      "participant": {
        "id": "6852399814992086022",
        "username": "papaceliba",
        "displayName": "papa celiba liege 🇧🇪"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:15.813Z",
      "eventType": "chat",
      "id": "7679510817008388866",
      "participant": {
        "id": "6933335443619775493",
        "username": "sp3cii",
        "displayName": "SPECi 🦁"
      },
      "message": "@Enzo you have just reached Level: 47!"
    },
    {
      "occurredAt": "2026-08-29T17:44:16.334Z",
      "eventType": "like",
      "id": "7679510857952330017",
      "participant": {
        "id": "7105907614987289606",
        "username": "hala.madridrodrygo11",
        "displayName": "Hala.Madridrodrygo11"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:16.404Z",
      "eventType": "room-user-seq",
      "id": "7679510858890199310"
    },
    {
      "occurredAt": "2026-08-29T17:44:17.455Z",
      "eventType": "chat",
      "id": "7679510830858324769",
      "participant": {
        "id": "7508659353085756438",
        "username": "adawong.officiel",
        "displayName": "💃🏻 Ada Wong 💃🏻"
      },
      "message": "GO COEUR DU JOUR"
    },
    {
      "occurredAt": "2026-08-29T17:44:18.234Z",
      "eventType": "like",
      "id": "7679510865229644065",
      "participant": {
        "id": "7105907614987289606",
        "username": "hala.madridrodrygo11",
        "displayName": "Hala.Madridrodrygo11"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:18.250Z",
      "eventType": "room-user-seq",
      "id": "7679510867134022669"
    },
    {
      "occurredAt": "2026-08-29T17:44:18.729Z",
      "eventType": "like",
      "id": "7679510868203569941",
      "participant": {
        "id": "7267779356586902530",
        "username": "hideya721",
        "displayName": "🐇ひでや🐇"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:18.849Z",
      "eventType": "member",
      "id": "7679510862801980192",
      "participant": {
        "id": "7039741461541520389",
        "username": "logan25108",
        "displayName": "Logan adt"
      }
    },
    {
      "occurredAt": "2026-08-29T17:44:20.518Z",
      "eventType": "room-user-seq",
      "id": "7679510876497281549"
    },
    {
      "occurredAt": "2026-08-29T17:44:20.660Z",
      "eventType": "social",
      "id": "7679510868379929377",
      "participant": {
        "id": "7587838597332960278",
        "username": "adele.0120",
        "displayName": "★Adèle★"
      },
      "followCount": 156959
    },
    {
      "occurredAt": "2026-08-29T17:44:20.859Z",
      "eventType": "like",
      "id": "7679510876935799841",
      "participant": {
        "id": "7105907614987289606",
        "username": "hala.madridrodrygo11",
        "displayName": "Hala.Madridrodrygo11"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:21.286Z",
      "eventType": "like",
      "id": "7679510879456477729",
      "participant": {
        "id": "6852399814992086022",
        "username": "papaceliba",
        "displayName": "papa celiba liege 🇧🇪"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:22.669Z",
      "eventType": "room-user-seq",
      "id": "7679510886314197261"
    },
    {
      "occurredAt": "2026-08-29T17:44:23.195Z",
      "eventType": "member",
      "id": "7679510878913137440",
      "participant": {
        "id": "7484342416213525526",
        "username": "spider15110",
        "displayName": "H'🕷"
      }
    },
    {
      "occurredAt": "2026-08-29T17:44:23.340Z",
      "eventType": "chat",
      "id": "7679510875182467873",
      "participant": {
        "id": "6805305328239903749",
        "username": "ninimnms",
        "displayName": "🌼 ℕ𝕚𝕟𝕚 🏉🌼"
      },
      "message": "!score"
    },
    {
      "occurredAt": "2026-08-29T17:44:23.364Z",
      "eventType": "like",
      "id": "7679510887623033888",
      "participant": {
        "id": "7105907614987289606",
        "username": "hala.madridrodrygo11",
        "displayName": "Hala.Madridrodrygo11"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:24.224Z",
      "eventType": "chat",
      "id": "7679510868794690326",
      "participant": {
        "id": "6933335443619775493",
        "username": "sp3cii",
        "displayName": "SPECi 🦁"
      },
      "message": "@🌼 ℕ𝕚𝕟𝕚 🏉🌼 Commands:"
    },
    {
      "occurredAt": "2026-08-29T17:44:24.254Z",
      "eventType": "like",
      "id": "7679510890974200608",
      "participant": {
        "id": "7105907614987289606",
        "username": "hala.madridrodrygo11",
        "displayName": "Hala.Madridrodrygo11"
      },
      "likeCount": 6
    },
    {
      "occurredAt": "2026-08-29T17:44:24.381Z",
      "eventType": "chat",
      "id": "7679510856082115350",
      "participant": {
        "id": "6933335443619775493",
        "username": "sp3cii",
        "displayName": "SPECi 🦁"
      },
      "message": "@🌼 ℕ𝕚𝕟𝕚 🏉🌼 you have 161 007 Points (Level: 154)."
    },
    {
      "occurredAt": "2026-08-29T17:44:25.146Z",
      "eventType": "room-user-seq",
      "id": "7679510897030791437"
    },
    {
      "occurredAt": "2026-08-29T17:44:26.218Z",
      "eventType": "room-user-seq",
      "id": "7679510901325939725"
    },
    {
      "occurredAt": "2026-08-29T17:44:27.636Z",
      "eventType": "like",
      "id": "7679510906367296545",
      "participant": {
        "id": "6852399814992086022",
        "username": "papaceliba",
        "displayName": "papa celiba liege 🇧🇪"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:28.009Z",
      "eventType": "room-user-seq",
      "id": "7679510908457927693"
    },
    {
      "occurredAt": "2026-08-29T17:44:29.601Z",
      "eventType": "like",
      "id": "7679510913980679200",
      "participant": {
        "id": "6852399814992086022",
        "username": "papaceliba",
        "displayName": "papa celiba liege 🇧🇪"
      },
      "likeCount": 8
    },
    {
      "occurredAt": "2026-08-29T17:44:30.595Z",
      "eventType": "room-user-seq",
      "id": "7679510919822836750"
    },
    {
      "occurredAt": "2026-08-29T17:44:31.809Z",
      "eventType": "like",
      "id": "7679510924264931873",
      "participant": {
        "id": "7105907614987289606",
        "username": "hala.madridrodrygo11",
        "displayName": "Hala.Madridrodrygo11"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:31.864Z",
      "eventType": "like",
      "id": "7679510924582978580",
      "participant": {
        "id": "7267779356586902530",
        "username": "hideya721",
        "displayName": "🐇ひでや🐇"
      },
      "likeCount": 15
    },
    {
      "occurredAt": "2026-08-29T17:44:31.995Z",
      "eventType": "room-user-seq",
      "id": "7679510925774684430"
    },
    {
      "occurredAt": "2026-08-29T17:44:32.594Z",
      "eventType": "member",
      "id": "7679510921299856161",
      "participant": {
        "id": "7668012839965475862",
        "username": "vexaz016",
        "displayName": "vexazthedark"
      }
    },
    {
      "occurredAt": "2026-08-29T17:44:33.622Z",
      "eventType": "like",
      "id": "7679510931902235168",
      "participant": {
        "id": "7105907614987289606",
        "username": "hala.madridrodrygo11",
        "displayName": "Hala.Madridrodrygo11"
      },
      "likeCount": 15
    }
  ],
  "stream": {
    "selectedQuality": "720p",
    "variants": [
      {
        "quality": "720p",
        "width": 720,
        "height": 1280,
        "bitrateKbps": 1800,
        "codec": "h264",
        "format": "flv"
      }
    ]
  },
  "creator": {
    "id": "6933335443619775493",
    "username": "sp3cii",
    "displayName": "SPECi 🦁",
    "bio": "RECORD PERSO 3.2M💎\n12x🏆29x🥈22x🥉 | 10x 🥇Arène Gaming \n1x TOP 1 QUOTIDIEN 🥇\n3x TOP 1 Populaire ❤️\nTeam Rouge :18 vs Team Verte :3",
    "avatarUrl": "https://p16-common-sign.tiktokcdn.com/tos-maliva-avt-0068/3b5c3b26329474ad9e0e0271d51366f7~tplv-tiktokx-cropcenter:100:100.webp?dr=14579&refresh_token=6be1bc0c&x-expires=1788195600&x-signature=5hlpp7Pa3OOg3Qtnif1Ml8GrIJc%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=fdd36af4&idc=my2",
    "verified": false
  },
  "audience": {
    "viewerCount": 56,
    "likeCount": 0,
    "commentCount": 0,
    "shareCount": 0,
    "followCount": 0,
    "giftCount": 0,
    "fanActivityCount": 0
  },
  "commerce": {
    "shopEnabled": false,
    "businessAccount": false,
    "interactionPermissions": {
      "comments": true,
      "gifts": true,
      "likes": true,
      "shares": true,
      "follows": true
    }
  }
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. The prices below are the current tier prices for the two buyer-facing events.

| Event | Price |
| --- | --- |
| Recording second | $0.0005 per successfully captured second on FREE and BRONZE tiers; $0.00045 on SILVER, GOLD, PLATINUM, and DIAMOND tiers. |
| Live interaction | $0.00001 per timestamped interaction delivered during capture. |

A charge applies only when the relevant video second is successfully captured or an interaction is delivered during capture. Prices can change, so check the [current pricing page](https://apify.com/maximedupre/tiktok-live-recorder/pricing) before a long run.

#### 🔌 Integrations

Call the Actor through the Apify API, then read the Dataset URL and stored MP4 file links from the run. Export the Dataset or pass its rows to your own workflow. One run captures one broadcast.

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What does one Dataset row represent?

One row represents one completed MP4 segment. It includes the segment file details and the room, stream session, creator, audience, permission, interaction, and stream data available for that segment.

##### Can I record a TikTok Live after it ends?

No. The target must be an active public TikTok Live broadcast. Ended posts, replays, and inaccessible rooms are outside this Actor.

##### What happens if the target is not live when the run starts?

Turn on **Wait for the live to start** if you want the run to wait at startup. With it off, the run does not wait for a live broadcast to start.

##### What happens when I leave Maximum capture time empty?

The Actor records until the live broadcast ends. The run then returns all available results until the source is exhausted.

##### Can I choose the recording quality?

Yes. Choose a quality exposed by the stream, or use `auto` for the best available quality. The available variants are also reported in `stream.variants`.

##### Does the Actor capture chat and gifts?

It saves delivered interaction events such as chat, likes, follows, members, and gifts when TikTok sends them during capture. It cannot guarantee an event type that the source does not deliver.

##### Why is a room, creator, or audience value empty?

TikTok may not expose every optional value for every room. The Actor keeps available source data and does not invent a missing value.

##### Can one run monitor several accounts?

No. One run captures one public TikTok Live broadcast. Start separate runs when you need separate targets.

##### Can I use this for other live platforms?

No. This Actor is for public TikTok Live broadcasts. It does not capture YouTube Live, Twitch, Instagram Live, or other platforms.

### 📝 Changelog

**0.0: Initial release**

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~tiktok-live-recorder/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [TikTok Live Search Scraper](https://apify.com/maximedupre/tiktok-live-search-scraper) finds active public rooms by keyword before you select one to record.
- [TikTok Creator Analytics Scraper](https://apify.com/maximedupre/tiktok-creator-analytics-scraper) reviews a creator's public audience and recent post metrics beside a live capture.
- [TikTok Video Downloader](https://apify.com/maximedupre/tiktok-video-downloader) fetches direct media links from finished public TikTok video URLs after a broadcast.
- [TikTok Transcript Scraper](https://apify.com/maximedupre/tiktok-transcript-scraper) extracts public captions from saved TikTok videos for searchable text.
- [TikTok Live Status Monitor - Stream URLs \[NO LOGIN\] ✅](https://apify.com/unseenuser/tiktok-live-status-scraper) checks whether a handle is live and shows source stream URLs before recording.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `discoveryMethod` (type: `string`):

Choose how to identify the one public TikTok Live broadcast for this run.

## `username` (type: `string`):

Enter one public TikTok username. Use this field when the method is Username.

## `profileOrLiveUrl` (type: `string`):

Enter one TikTok profile URL or live-room URL. Use this field when the method is Profile or live URL.

## `liveRoomId` (type: `string`):

Enter one TikTok Live room identifier. Use this field when the method is Live-room ID.

## `maxDurationSeconds` (type: `integer`):

Set a positive number of seconds to stop capture. Leave this empty to record until the live broadcast ends; the run then returns all available results until the source is exhausted.

## `recordingQuality` (type: `string`):

Choose a quality exposed by the live stream. Automatic uses the best available quality.

## `waitForLive` (type: `boolean`):

Turn this on to wait when the target is not live at run start. With it off, the run does not wait for a live broadcast to start.

## Actor input object example

```json
{
  "discoveryMethod": "username",
  "username": "jimmieislive",
  "maxDurationSeconds": 15,
  "recordingQuality": "auto",
  "waitForLive": false
}
```

# Actor output Schema

## `datasetUrl` (type: `string`):

Open one dataset row for each completed MP4 segment and its captured room, stream, creator, audience, permission, and interaction data.

# 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 = {
    "discoveryMethod": "username",
    "username": "jimmieislive",
    "maxDurationSeconds": 15
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/tiktok-live-recorder").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 = {
    "discoveryMethod": "username",
    "username": "jimmieislive",
    "maxDurationSeconds": 15,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/tiktok-live-recorder").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 '{
  "discoveryMethod": "username",
  "username": "jimmieislive",
  "maxDurationSeconds": 15
}' |
apify call maximedupre/tiktok-live-recorder --silent --output-dataset

```

## MCP server setup

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

```

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/A40pAx36GGBYwQPwe/builds/tPgHS4Xp2OAeOBo93/openapi.json
