{
  "data": {
    "id": "V7DLKNWIr01GAst7i",
    "actId": "wec60fCwOTbQwAqg7",
    "userId": "IYgBDiXtHOijAaUel",
    "startedAt": "2026-11-10T08:44:46.470Z",
    "finishedAt": "2026-11-10T08:44:50.440Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 3881,
      "runTimeSecs": 3.881,
      "computeUnits": 0.0043122222222222225,
      "imageSizeBytes": 3192018432
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "QYo53EZkJk0prePWY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"TikTok LIVE Room Status & Event Capture Input\",\n  \"description\": \"Check TikTok creators for a LIVE broadcast and export room metadata, playback URLs, host and audience stats — or attach to a live room and capture chat, gifts, likes, follows, joins and viewer-count updates. No login, cookie or API key is needed.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"mode\": {\n      \"title\": \"Mode\",\n      \"type\": \"string\",\n      \"description\": \"What to collect. 'Room status' returns one row per creator (live or offline). 'Live events' attaches to a live room and returns one row per chat/gift/like/follow/share/join/viewer event.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"roomStatus\",\n        \"liveEvents\"\n      ],\n      \"enumTitles\": [\n        \"Room status (one row per creator)\",\n        \"Live events (real-time chat and audience events)\"\n      ],\n      \"default\": \"roomStatus\",\n      \"prefill\": \"roomStatus\"\n    },\n    \"usernames\": {\n      \"title\": \"Usernames\",\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"description\": \"TikTok creators to monitor: bare usernames, @handles, profile URLs or LIVE URLs. Duplicates are removed. The prefill checks the National Geographic account.\",\n      \"editor\": \"stringList\",\n      \"prefill\": [\n        \"natgeo\"\n      ],\n      \"sectionCaption\": \"Creators to check\",\n      \"sectionDescription\": \"Add one entry per creator. Both bare handles and full TikTok URLs are accepted.\"\n    },\n    \"liveUrls\": {\n      \"title\": \"LIVE URLs\",\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"description\": \"Direct TikTok URLs such as https://www.tiktok.com/@creator/live (or a profile URL). An alternative to usernames; both lists are merged.\",\n      \"editor\": \"stringList\"\n    },\n    \"includeOffline\": {\n      \"title\": \"Include offline creators\",\n      \"type\": \"boolean\",\n      \"description\": \"When on, every valid creator produces a row even when they are not LIVE (status 'offline', with public profile data). This makes scheduled watchlists and the daily test reliable (mode=roomStatus; ignored in live-events mode).\",\n      \"default\": false,\n      \"prefill\": true\n    },\n    \"includeStreamUrls\": {\n      \"title\": \"Include stream URLs\",\n      \"type\": \"boolean\",\n      \"description\": \"Add the HLS/FLV playback URL map (and its expiry) for LIVE creators (mode=roomStatus). These URLs are signed by TikTok and stop working when the signature or the stream ends.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"connectionDuration\": {\n      \"title\": \"Connection duration (seconds)\",\n      \"type\": \"integer\",\n      \"description\": \"How long to stay attached to each LIVE room and collect events (mode=liveEvents). A short window is enough for a status check; events need a longer window.\",\n      \"default\": 60,\n      \"minimum\": 10,\n      \"maximum\": 3600,\n      \"prefill\": 10,\n      \"sectionCaption\": \"Live event capture (mode=liveEvents)\",\n      \"sectionDescription\": \"These settings apply only when Mode is 'Live events'.\"\n    },\n    \"eventCap\": {\n      \"title\": \"Event cap\",\n      \"type\": \"integer\",\n      \"description\": \"Stop collecting from a stream after this many events. Applies per stream (mode=liveEvents).\",\n      \"default\": 500,\n      \"minimum\": 1,\n      \"maximum\": 10000,\n      \"prefill\": 100\n    },\n    \"eventTypes\": {\n      \"title\": \"Event types\",\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\",\n        \"enum\": [\n          \"all\",\n          \"chat\",\n          \"gift\",\n          \"like\",\n          \"follow\",\n          \"share\",\n          \"join\",\n          \"stats\",\n          \"other\"\n        ],\n        \"enumTitles\": [\n          \"All events\",\n          \"Chat messages\",\n          \"Gifts\",\n          \"Likes\",\n          \"Follows\",\n          \"Shares\",\n          \"Joins\",\n          \"Viewer counts\",\n          \"Other message types\"\n        ]\n      },\n      \"description\": \"Which event categories to keep (mode=liveEvents). 'All' keeps every category. 'Other' keeps TikTok message types that do not map to a named category.\",\n      \"editor\": \"select\",\n      \"default\": [\n        \"all\"\n      ],\n      \"prefill\": [\n        \"all\"\n      ]\n    }\n  },\n  \"required\": [\n    \"mode\"\n  ]\n}",
    "readme": "# TikTok LIVE Room Status & Event Capture\n\nCheck whether TikTok creators are live right now and export the room's title, viewer counters, playback URLs, host profile and audience stats — or attach to a live room and capture its chat, gifts, likes, follows, joins and viewer-count updates as they happen.\n\nEverything works **cookielessly**. There is no login step, no cookie to paste, no API key and no proxy setup.\n\n## What this actor does\n\n- **Room status mode (default):** one row per creator. Live creators get the full room snapshot; offline creators get a clearly labelled status row when \"Include offline creators\" is on.\n- **Live events mode:** attaches to a live room's public event stream and pushes one row per chat message, gift, like, follow, join or viewer-count update.\n- **Trustworthy live detection:** TikTok keeps serving an ended room's title, playback URLs and viewer numbers, sometimes for months. This actor checks the room's live status code and the real-time `check_alive` endpoint, so an ended stream is not reported as live.\n- **Signed playback URLs:** HLS and FLV links at every quality TikTok exposes (both standard and HEVC stream data are merged), plus the earliest signature expiry when it can be parsed.\n- **No credentials, no paid proxy:** a direct connection is tried first, then the free Apify datacenter pool. No residential proxy, no third-party proxy, no user-supplied cookie.\n\n## Modes\n\n### Room status (default)\n\nOne row per supplied creator:\n\n- **Live:** `isLive: true`, `status: \"live\"`, room id, title, start time, live duration, current/total viewers, likes, shares, comments, follows, gift viewers, stream URLs and their expiry, cover images, host profile and follower stats.\n- **Offline:** `isLive: false`, `status: \"offline\"`, the public profile (bio, avatar, follower/following/heart/video counts, bio link) and the most recent stream's title/start time when TikTok still exposes it. Viewer counters are deliberately omitted for offline creators.\n- **Not found:** `status: \"notFound\"` when TikTok has no such account. `isLive` is omitted because the actor has no live evidence either way.\n- **Unavailable:** `status: \"unavailable\"` with a short `error` when TikTok returns a bot check or an unreadable answer. This is never reported as offline, and `isLive` is omitted.\n\n### Live events\n\nAttaches to one live room at a time and emits events until `connectionDuration` seconds or `eventCap` events. Event types: `chat`, `gift`, `like`, `follow`, `share`, `join`, `stats`, and `other` for TikTok message types that do not map to a named category. Replayed messages are deduplicated by message id.\n\nLive events are ephemeral: TikTok exposes no chat history, so you only receive what arrives while the actor is attached.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `mode` | select | `roomStatus` | `roomStatus` (one row per creator) or `liveEvents` (real-time events) |\n| `usernames` | array | prefill `[\"natgeo\"]` | Bare handles, `@handles`, profile URLs or LIVE URLs |\n| `liveUrls` | array | – | Direct TikTok URLs; merged with `usernames` |\n| `includeOffline` | boolean | `false` (prefill `true`) | Emit a status row for offline/not-found/unavailable creators. Ignored in live-events mode |\n| `includeStreamUrls` | boolean | `true` | Add HLS/FLV playback URLs and their expiry for live creators (room-status mode) |\n| `connectionDuration` | integer | `60` (prefill `10`) | Seconds to stay attached per live room, in live-events mode |\n| `eventCap` | integer | `500` (prefill `100`) | Stop after this many events per stream, in live-events mode |\n| `eventTypes` | multi-select | `[\"all\"]` | Which event categories to keep |\n\n### Example: check a watchlist\n\n```json\n{\n  \"mode\": \"roomStatus\",\n  \"usernames\": [\"natgeo\", \"bbcnews\", \"cnn\"],\n  \"includeOffline\": true,\n  \"includeStreamUrls\": true\n}\n```\n\n### Example: capture a stream's chat and gifts\n\n```json\n{\n  \"mode\": \"liveEvents\",\n  \"usernames\": [\"creator_handle\"],\n  \"connectionDuration\": 120,\n  \"eventCap\": 1000,\n  \"eventTypes\": [\"chat\", \"gift\", \"stats\"]\n}\n```\n\n### Example: mix handles and URLs\n\n```json\n{\n  \"mode\": \"roomStatus\",\n  \"usernames\": [\"@natgeo\"],\n  \"liveUrls\": [\"https://www.tiktok.com/@tiktok/live\"]\n}\n```\n\n## Output per room-status row\n\n- `recordType`, `isLive`, `status`\n- `roomId`, `liveUrl`, `sourceUrl`\n- `liveTitle`, `liveStatus`, `liveRoomMode`\n- `startTime`, `startedAt`, `liveDurationSeconds`\n- `totalViewers`, `currentViewers`\n- `likeCount`, `diggCount`, `shareCount`, `commentCount`, `followCount`, `giftUvCount`, `watchUserCount`, `roomFollowCount`, `totalUser`\n- `coverUrl`, `squareCoverUrl`, `hashtagId`, `gameTagId`, `isPaidEvent`, `isSubscriberOnly`, `streamId`\n- `streamUrls`, `streamUrlExpiresAt`\n- `hostUsername`, `hostUserId`, `hostSecUid`, `hostDisplayName`, `hostVerified`, `hostBio`, `hostBioLink`, `hostAvatarUrl`, `hostFollowerCount`, `hostFollowingCount`, `hostHeartCount`, `hostVideoCount`, `hostPrivateAccount`, `hostIsOrganization`, `hostLanguage`\n- Offline-only: `lastLiveTitle`, `lastLiveStartTime`, `lastLiveStartedAt`, `lastLiveStatus`\n- `checkAlive` when TikTok answered the real-time check\n- `scrapedAt`\n\nMissing values are omitted, never filled with `null`, empty strings or placeholders.\n\n## Output per live-event row\n\n- `recordType`, `isLive`, `status`, `roomId`, `hostUsername`, `liveUrl`, `sourceUrl`\n- `eventType`, `receivedAt`, `eventTimestamp`, `msgId`\n- `user`: `id`, `secUid`, `username`, `displayName`, `avatarUrl`, `verified`\n- `payload`:\n  - chat: `text`, `emotes`, `contentLanguage`\n  - gift: `giftName`, `giftId`, `giftCount`, `giftDiamondCount`, `giftTotalDiamonds`, `repeatEnd`\n  - like: `likeCount`, `totalLikes`\n  - stats: `viewerCount`\n  - join: `actionId`\n  - follow/share: `action`, `shareType`, `shareTarget`, `shareCount`, `followCount` (the last two are cumulative room/host counters reported with the event)\n  - other: `rawMethod`, `payloadSize`\n- `scrapedAt`\n\n## Use cases\n\n- **Go-live alerts:** poll a creator roster and diff `isLive` between runs.\n- **Audience snapshots:** compare viewer counts, likes, shares, follows and gift activity across streams.\n- **Creator research:** keep a current record of who is live, under what title, and with how many viewers.\n- **Community management:** capture your own stream's chat and gifts for moderation or a highlight reel.\n- **Live-commerce research:** follow a set of sellers and record their stream metadata over time.\n\n## FAQ\n\n**Do I need a TikTok account or cookie?**\nNo. Room status and live events are read from the same public surfaces any logged-out viewer sees. Authentication is only required to *post* messages, which this actor never does.\n\n**Why did a creator come back as offline even though their page shows a room title?**\nTikTok keeps the previous room's metadata after a stream ends. The actor checks the room's live status and the real-time `check_alive` endpoint; if neither confirms a broadcast, the creator is reported as offline with `lastLive*` fields for the ended room.\n\n**What happens when a creator isn't live?**\nWith \"Include offline creators\" on, you get one status row with their public profile. With it off, the creator is skipped — the old behaviour. In live-events mode an offline creator produces no event rows and a clear log line.\n\n**Do the stream URLs keep working?**\nThey are signed by TikTok and expire. The actor emits `streamUrlExpiresAt` when it can parse the signature's expiry. Re-run for fresh links.\n\n**Can I capture chat history?**\nNo. TikTok exposes no endpoint for past chat messages. Live-events mode captures what arrives while it is attached.\n\n**Are events region-dependent?**\nYes. TikTok's live rooms and viewer counts are relative to the connection's region. If a room is region-restricted, the actor reports it as `unavailable` rather than guessing.\n\n**Can I monitor many creators in one run?**\nYes. In room-status mode each creator is checked in turn and gets one row. In live-events mode each live creator is captured for `connectionDuration` seconds, so total runtime grows with the list.\n\n**Does this actor discover live streams by keyword or record video?**\nNo. It is a creator-status and event-capture actor. Keyword/category discovery, rankings, top-gifter leaderboards and recording are separate jobs and are not part of this actor.\n\n**Is this affiliated with TikTok?**\nNo. It is an independent third-party tool that reads public LIVE data. Use it only for public data and in line with TikTok's terms and applicable law.\n\n## Limitations\n\n- Chat history does not exist upstream; live events are only what arrives while attached.\n- Playback, cover and avatar URLs are signed and expire. Some CDNs reject HTTP `HEAD` probes; playback itself works with a normal media request.\n- Engagement counters (likes, shares, comments, follows, gift viewers) come from TikTok's room-enter response. A region-restricted room can withhold that response; the counters are then omitted rather than fabricated.\n- Some rooms are region-restricted; the actor labels them `unavailable` instead of inventing data.\n- Private accounts, private analytics, sending messages, recording and keyword discovery are out of scope.\n- TikTok can change its internal page state or Webcast protocol without notice. The actor fails soft (status rows/log lines) rather than fabricating fields.\n\n## Data source\n\nPublic TikTok LIVE pages (`/@creator/live`), public profile pages, the real-time room `check_alive` endpoint, and the public Webcast event stream. No account, cookie, API key or proxy input is used.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "tiktok-live-room-status-and-chat-capture-tool",
      "title": "TikTok LIVE Room Status & Chat Capture Tool",
      "description": "Check TikTok creators for a LIVE broadcast and export room status, viewer counts, playback URLs, host profile and audience stats — or capture real-time chat, gifts, likes, follows, joins and viewer-count updates. No login, cookie or API key.",
      "version": "1.1",
      "buildTag": "latest",
      "dockerfile": "./Dockerfile",
      "readme": "# TikTok LIVE Room Status & Event Capture\n\nCheck whether TikTok creators are live right now and export the room's title, viewer counters, playback URLs, host profile and audience stats — or attach to a live room and capture its chat, gifts, likes, follows, joins and viewer-count updates as they happen.\n\nEverything works **cookielessly**. There is no login step, no cookie to paste, no API key and no proxy setup.\n\n## What this actor does\n\n- **Room status mode (default):** one row per creator. Live creators get the full room snapshot; offline creators get a clearly labelled status row when \"Include offline creators\" is on.\n- **Live events mode:** attaches to a live room's public event stream and pushes one row per chat message, gift, like, follow, join or viewer-count update.\n- **Trustworthy live detection:** TikTok keeps serving an ended room's title, playback URLs and viewer numbers, sometimes for months. This actor checks the room's live status code and the real-time `check_alive` endpoint, so an ended stream is not reported as live.\n- **Signed playback URLs:** HLS and FLV links at every quality TikTok exposes (both standard and HEVC stream data are merged), plus the earliest signature expiry when it can be parsed.\n- **No credentials, no paid proxy:** a direct connection is tried first, then the free Apify datacenter pool. No residential proxy, no third-party proxy, no user-supplied cookie.\n\n## Modes\n\n### Room status (default)\n\nOne row per supplied creator:\n\n- **Live:** `isLive: true`, `status: \"live\"`, room id, title, start time, live duration, current/total viewers, likes, shares, comments, follows, gift viewers, stream URLs and their expiry, cover images, host profile and follower stats.\n- **Offline:** `isLive: false`, `status: \"offline\"`, the public profile (bio, avatar, follower/following/heart/video counts, bio link) and the most recent stream's title/start time when TikTok still exposes it. Viewer counters are deliberately omitted for offline creators.\n- **Not found:** `status: \"notFound\"` when TikTok has no such account. `isLive` is omitted because the actor has no live evidence either way.\n- **Unavailable:** `status: \"unavailable\"` with a short `error` when TikTok returns a bot check or an unreadable answer. This is never reported as offline, and `isLive` is omitted.\n\n### Live events\n\nAttaches to one live room at a time and emits events until `connectionDuration` seconds or `eventCap` events. Event types: `chat`, `gift`, `like`, `follow`, `share`, `join`, `stats`, and `other` for TikTok message types that do not map to a named category. Replayed messages are deduplicated by message id.\n\nLive events are ephemeral: TikTok exposes no chat history, so you only receive what arrives while the actor is attached.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `mode` | select | `roomStatus` | `roomStatus` (one row per creator) or `liveEvents` (real-time events) |\n| `usernames` | array | prefill `[\"natgeo\"]` | Bare handles, `@handles`, profile URLs or LIVE URLs |\n| `liveUrls` | array | – | Direct TikTok URLs; merged with `usernames` |\n| `includeOffline` | boolean | `false` (prefill `true`) | Emit a status row for offline/not-found/unavailable creators. Ignored in live-events mode |\n| `includeStreamUrls` | boolean | `true` | Add HLS/FLV playback URLs and their expiry for live creators (room-status mode) |\n| `connectionDuration` | integer | `60` (prefill `10`) | Seconds to stay attached per live room, in live-events mode |\n| `eventCap` | integer | `500` (prefill `100`) | Stop after this many events per stream, in live-events mode |\n| `eventTypes` | multi-select | `[\"all\"]` | Which event categories to keep |\n\n### Example: check a watchlist\n\n```json\n{\n  \"mode\": \"roomStatus\",\n  \"usernames\": [\"natgeo\", \"bbcnews\", \"cnn\"],\n  \"includeOffline\": true,\n  \"includeStreamUrls\": true\n}\n```\n\n### Example: capture a stream's chat and gifts\n\n```json\n{\n  \"mode\": \"liveEvents\",\n  \"usernames\": [\"creator_handle\"],\n  \"connectionDuration\": 120,\n  \"eventCap\": 1000,\n  \"eventTypes\": [\"chat\", \"gift\", \"stats\"]\n}\n```\n\n### Example: mix handles and URLs\n\n```json\n{\n  \"mode\": \"roomStatus\",\n  \"usernames\": [\"@natgeo\"],\n  \"liveUrls\": [\"https://www.tiktok.com/@tiktok/live\"]\n}\n```\n\n## Output per room-status row\n\n- `recordType`, `isLive`, `status`\n- `roomId`, `liveUrl`, `sourceUrl`\n- `liveTitle`, `liveStatus`, `liveRoomMode`\n- `startTime`, `startedAt`, `liveDurationSeconds`\n- `totalViewers`, `currentViewers`\n- `likeCount`, `diggCount`, `shareCount`, `commentCount`, `followCount`, `giftUvCount`, `watchUserCount`, `roomFollowCount`, `totalUser`\n- `coverUrl`, `squareCoverUrl`, `hashtagId`, `gameTagId`, `isPaidEvent`, `isSubscriberOnly`, `streamId`\n- `streamUrls`, `streamUrlExpiresAt`\n- `hostUsername`, `hostUserId`, `hostSecUid`, `hostDisplayName`, `hostVerified`, `hostBio`, `hostBioLink`, `hostAvatarUrl`, `hostFollowerCount`, `hostFollowingCount`, `hostHeartCount`, `hostVideoCount`, `hostPrivateAccount`, `hostIsOrganization`, `hostLanguage`\n- Offline-only: `lastLiveTitle`, `lastLiveStartTime`, `lastLiveStartedAt`, `lastLiveStatus`\n- `checkAlive` when TikTok answered the real-time check\n- `scrapedAt`\n\nMissing values are omitted, never filled with `null`, empty strings or placeholders.\n\n## Output per live-event row\n\n- `recordType`, `isLive`, `status`, `roomId`, `hostUsername`, `liveUrl`, `sourceUrl`\n- `eventType`, `receivedAt`, `eventTimestamp`, `msgId`\n- `user`: `id`, `secUid`, `username`, `displayName`, `avatarUrl`, `verified`\n- `payload`:\n  - chat: `text`, `emotes`, `contentLanguage`\n  - gift: `giftName`, `giftId`, `giftCount`, `giftDiamondCount`, `giftTotalDiamonds`, `repeatEnd`\n  - like: `likeCount`, `totalLikes`\n  - stats: `viewerCount`\n  - join: `actionId`\n  - follow/share: `action`, `shareType`, `shareTarget`, `shareCount`, `followCount` (the last two are cumulative room/host counters reported with the event)\n  - other: `rawMethod`, `payloadSize`\n- `scrapedAt`\n\n## Use cases\n\n- **Go-live alerts:** poll a creator roster and diff `isLive` between runs.\n- **Audience snapshots:** compare viewer counts, likes, shares, follows and gift activity across streams.\n- **Creator research:** keep a current record of who is live, under what title, and with how many viewers.\n- **Community management:** capture your own stream's chat and gifts for moderation or a highlight reel.\n- **Live-commerce research:** follow a set of sellers and record their stream metadata over time.\n\n## FAQ\n\n**Do I need a TikTok account or cookie?**\nNo. Room status and live events are read from the same public surfaces any logged-out viewer sees. Authentication is only required to *post* messages, which this actor never does.\n\n**Why did a creator come back as offline even though their page shows a room title?**\nTikTok keeps the previous room's metadata after a stream ends. The actor checks the room's live status and the real-time `check_alive` endpoint; if neither confirms a broadcast, the creator is reported as offline with `lastLive*` fields for the ended room.\n\n**What happens when a creator isn't live?**\nWith \"Include offline creators\" on, you get one status row with their public profile. With it off, the creator is skipped — the old behaviour. In live-events mode an offline creator produces no event rows and a clear log line.\n\n**Do the stream URLs keep working?**\nThey are signed by TikTok and expire. The actor emits `streamUrlExpiresAt` when it can parse the signature's expiry. Re-run for fresh links.\n\n**Can I capture chat history?**\nNo. TikTok exposes no endpoint for past chat messages. Live-events mode captures what arrives while it is attached.\n\n**Are events region-dependent?**\nYes. TikTok's live rooms and viewer counts are relative to the connection's region. If a room is region-restricted, the actor reports it as `unavailable` rather than guessing.\n\n**Can I monitor many creators in one run?**\nYes. In room-status mode each creator is checked in turn and gets one row. In live-events mode each live creator is captured for `connectionDuration` seconds, so total runtime grows with the list.\n\n**Does this actor discover live streams by keyword or record video?**\nNo. It is a creator-status and event-capture actor. Keyword/category discovery, rankings, top-gifter leaderboards and recording are separate jobs and are not part of this actor.\n\n**Is this affiliated with TikTok?**\nNo. It is an independent third-party tool that reads public LIVE data. Use it only for public data and in line with TikTok's terms and applicable law.\n\n## Limitations\n\n- Chat history does not exist upstream; live events are only what arrives while attached.\n- Playback, cover and avatar URLs are signed and expire. Some CDNs reject HTTP `HEAD` probes; playback itself works with a normal media request.\n- Engagement counters (likes, shares, comments, follows, gift viewers) come from TikTok's room-enter response. A region-restricted room can withhold that response; the counters are then omitted rather than fabricated.\n- Some rooms are region-restricted; the actor labels them `unavailable` instead of inventing data.\n- Private accounts, private analytics, sending messages, recording and keyword discovery are out of scope.\n- TikTok can change its internal page state or Webcast protocol without notice. The actor fails soft (status rows/log lines) rather than fabricating fields.\n\n## Data source\n\nPublic TikTok LIVE pages (`/@creator/live`), public profile pages, the real-time room `check_alive` endpoint, and the public Webcast event stream. No account, cookie, API key or proxy input is used.\n",
      "input": {
        "title": "TikTok LIVE Room Status & Event Capture Input",
        "description": "Check TikTok creators for a LIVE broadcast and export room metadata, playback URLs, host and audience stats — or attach to a live room and capture chat, gifts, likes, follows, joins and viewer-count updates. No login, cookie or API key is needed.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "mode": {
            "title": "Mode",
            "type": "string",
            "description": "What to collect. 'Room status' returns one row per creator (live or offline). 'Live events' attaches to a live room and returns one row per chat/gift/like/follow/share/join/viewer event.",
            "editor": "select",
            "enum": [
              "roomStatus",
              "liveEvents"
            ],
            "enumTitles": [
              "Room status (one row per creator)",
              "Live events (real-time chat and audience events)"
            ],
            "default": "roomStatus",
            "prefill": "roomStatus"
          },
          "usernames": {
            "title": "Usernames",
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "TikTok creators to monitor: bare usernames, @handles, profile URLs or LIVE URLs. Duplicates are removed. The prefill checks the National Geographic account.",
            "editor": "stringList",
            "prefill": [
              "natgeo"
            ],
            "sectionCaption": "Creators to check",
            "sectionDescription": "Add one entry per creator. Both bare handles and full TikTok URLs are accepted."
          },
          "liveUrls": {
            "title": "LIVE URLs",
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Direct TikTok URLs such as https://www.tiktok.com/@creator/live (or a profile URL). An alternative to usernames; both lists are merged.",
            "editor": "stringList"
          },
          "includeOffline": {
            "title": "Include offline creators",
            "type": "boolean",
            "description": "When on, every valid creator produces a row even when they are not LIVE (status 'offline', with public profile data). This makes scheduled watchlists and the daily test reliable (mode=roomStatus; ignored in live-events mode).",
            "default": false,
            "prefill": true
          },
          "includeStreamUrls": {
            "title": "Include stream URLs",
            "type": "boolean",
            "description": "Add the HLS/FLV playback URL map (and its expiry) for LIVE creators (mode=roomStatus). These URLs are signed by TikTok and stop working when the signature or the stream ends.",
            "default": true,
            "prefill": true
          },
          "connectionDuration": {
            "title": "Connection duration (seconds)",
            "type": "integer",
            "description": "How long to stay attached to each LIVE room and collect events (mode=liveEvents). A short window is enough for a status check; events need a longer window.",
            "default": 60,
            "minimum": 10,
            "maximum": 3600,
            "prefill": 10,
            "sectionCaption": "Live event capture (mode=liveEvents)",
            "sectionDescription": "These settings apply only when Mode is 'Live events'."
          },
          "eventCap": {
            "title": "Event cap",
            "type": "integer",
            "description": "Stop collecting from a stream after this many events. Applies per stream (mode=liveEvents).",
            "default": 500,
            "minimum": 1,
            "maximum": 10000,
            "prefill": 100
          },
          "eventTypes": {
            "title": "Event types",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "all",
                "chat",
                "gift",
                "like",
                "follow",
                "share",
                "join",
                "stats",
                "other"
              ],
              "enumTitles": [
                "All events",
                "Chat messages",
                "Gifts",
                "Likes",
                "Follows",
                "Shares",
                "Joins",
                "Viewer counts",
                "Other message types"
              ]
            },
            "description": "Which event categories to keep (mode=liveEvents). 'All' keeps every category. 'Other' keeps TikTok message types that do not map to a named category.",
            "editor": "select",
            "default": [
              "all"
            ],
            "prefill": [
              "all"
            ]
          }
        },
        "required": [
          "mode"
        ]
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "TikTok LIVE Room Status & Event Capture Output",
        "description": "One row per creator (live status, room metadata, playback URLs, host and audience stats) or one row per real-time LIVE event (chat, gift, like, follow, share, join, viewer count).",
        "properties": {
          "events": {
            "type": "string",
            "title": "TikTok LIVE dataset",
            "description": "Dataset containing room-status rows and/or captured LIVE event rows.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "categories": [
        "SOCIAL_MEDIA"
      ],
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "TikTok LIVE Data",
          "views": {
            "overview": {
              "title": "Overview",
              "description": "One row per creator (room status) or per real-time LIVE event.",
              "transformation": {
                "fields": [
                  "recordType",
                  "isLive",
                  "status",
                  "hostUsername",
                  "liveTitle",
                  "currentViewers",
                  "eventType",
                  "receivedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "recordType": {
                    "label": "Record",
                    "format": "text"
                  },
                  "isLive": {
                    "label": "Live?",
                    "format": "boolean"
                  },
                  "status": {
                    "label": "Status",
                    "format": "text"
                  },
                  "hostUsername": {
                    "label": "Creator",
                    "format": "text"
                  },
                  "liveTitle": {
                    "label": "Title",
                    "format": "text"
                  },
                  "currentViewers": {
                    "label": "Viewers",
                    "format": "number"
                  },
                  "eventType": {
                    "label": "Event",
                    "format": "text"
                  },
                  "receivedAt": {
                    "label": "Received",
                    "format": "text"
                  }
                }
              }
            },
            "roomStatus": {
              "title": "Room status",
              "description": "Creator status, room metadata, playback URLs, host and audience stats.",
              "transformation": {
                "fields": [
                  "hostUsername",
                  "isLive",
                  "status",
                  "liveTitle",
                  "currentViewers",
                  "totalViewers",
                  "startedAt",
                  "hostFollowerCount",
                  "liveUrl"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "hostUsername": {
                    "label": "Creator",
                    "format": "text"
                  },
                  "isLive": {
                    "label": "Live?",
                    "format": "boolean"
                  },
                  "status": {
                    "label": "Status",
                    "format": "text"
                  },
                  "liveTitle": {
                    "label": "Title",
                    "format": "text"
                  },
                  "currentViewers": {
                    "label": "Current viewers",
                    "format": "number"
                  },
                  "totalViewers": {
                    "label": "Total enters",
                    "format": "number"
                  },
                  "startedAt": {
                    "label": "Started",
                    "format": "date"
                  },
                  "hostFollowerCount": {
                    "label": "Followers",
                    "format": "number"
                  },
                  "liveUrl": {
                    "label": "Live URL",
                    "format": "link"
                  }
                }
              }
            },
            "liveEvents": {
              "title": "Live events",
              "description": "Real-time chat, gifts, likes, follows, shares, joins and viewer-count updates.",
              "transformation": {
                "fields": [
                  "receivedAt",
                  "eventType",
                  "user",
                  "payload"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "receivedAt": {
                    "label": "Time",
                    "format": "date"
                  },
                  "eventType": {
                    "label": "Type",
                    "format": "text"
                  },
                  "user": {
                    "label": "User",
                    "format": "text"
                  },
                  "payload": {
                    "label": "Payload",
                    "format": "text"
                  }
                }
              }
            }
          },
          "fields": {
            "recordType": {
              "type": "string",
              "title": "Record Type",
              "description": "liveStatus (one row per creator) or liveEvent (one row per real-time event)"
            },
            "isLive": {
              "type": "boolean",
              "title": "Is Live",
              "description": "True when the creator is broadcasting and false when confirmed offline; omitted when the state is unknown (notFound/unavailable)"
            },
            "status": {
              "type": "string",
              "title": "Status",
              "description": "live, offline, notFound or unavailable"
            },
            "roomId": {
              "type": "string",
              "title": "Room ID",
              "description": "TikTok LIVE room ID (string to preserve 64-bit precision)"
            },
            "hostUsername": {
              "type": "string",
              "title": "Host Username",
              "description": "TikTok handle of the creator"
            },
            "hostUserId": {
              "type": "string",
              "title": "Host User ID",
              "description": "TikTok user ID of the creator"
            },
            "hostSecUid": {
              "type": "string",
              "title": "Host secUid",
              "description": "TikTok secUid of the creator"
            },
            "hostDisplayName": {
              "type": "string",
              "title": "Host Display Name",
              "description": "Display name of the creator"
            },
            "hostVerified": {
              "type": "boolean",
              "title": "Host Verified",
              "description": "Whether the creator has a verified badge"
            },
            "hostBio": {
              "type": "string",
              "title": "Host Bio",
              "description": "Creator bio/signature"
            },
            "hostBioLink": {
              "type": "string",
              "title": "Host Bio Link",
              "description": "Link in the creator's bio, when present"
            },
            "hostAvatarUrl": {
              "type": "string",
              "title": "Host Avatar URL",
              "description": "Signed URL of the creator's avatar image"
            },
            "hostFollowerCount": {
              "type": "integer",
              "title": "Host Follower Count",
              "description": "Number of followers at collection time"
            },
            "hostFollowingCount": {
              "type": "integer",
              "title": "Host Following Count",
              "description": "Number of accounts the creator follows"
            },
            "hostHeartCount": {
              "type": "integer",
              "title": "Host Heart Count",
              "description": "Total likes received by the creator (profile stat)"
            },
            "hostVideoCount": {
              "type": "integer",
              "title": "Host Video Count",
              "description": "Number of public videos on the creator's profile"
            },
            "hostPrivateAccount": {
              "type": "boolean",
              "title": "Host Private Account",
              "description": "Whether the creator's account is private"
            },
            "hostIsOrganization": {
              "type": "boolean",
              "title": "Host Is Organization",
              "description": "Whether the creator is a business/organization account"
            },
            "hostLanguage": {
              "type": "string",
              "title": "Host Language",
              "description": "Profile language reported by TikTok"
            },
            "liveTitle": {
              "type": "string",
              "title": "Live Title",
              "description": "Title of the current LIVE stream"
            },
            "lastLiveTitle": {
              "type": "string",
              "title": "Last Live Title",
              "description": "Title of the most recent ended room (offline rows only)"
            },
            "liveStatus": {
              "type": "integer",
              "title": "Live Status Code",
              "description": "TikTok internal room status code (2 = live, 4 = ended)"
            },
            "lastLiveStatus": {
              "type": "integer",
              "title": "Last Live Status Code",
              "description": "TikTok status code of the most recent room (offline rows only)"
            },
            "liveRoomMode": {
              "type": "integer",
              "title": "Live Room Mode",
              "description": "TikTok internal room mode code"
            },
            "startTime": {
              "type": "integer",
              "title": "Start Time (Unix)",
              "description": "Stream start time as a Unix timestamp"
            },
            "startedAt": {
              "type": "string",
              "title": "Started At",
              "description": "Stream start time in ISO 8601 UTC format"
            },
            "lastLiveStartTime": {
              "type": "integer",
              "title": "Last Live Start Time (Unix)",
              "description": "Start time of the most recent ended stream (offline rows only)"
            },
            "lastLiveStartedAt": {
              "type": "string",
              "title": "Last Live Started At",
              "description": "ISO 8601 start time of the most recent ended stream (offline rows only)"
            },
            "liveDurationSeconds": {
              "type": "integer",
              "title": "Live Duration (Seconds)",
              "description": "Seconds elapsed since the current stream started"
            },
            "totalViewers": {
              "type": "integer",
              "title": "Total Viewers",
              "description": "Cumulative viewer entries since the stream started"
            },
            "currentViewers": {
              "type": "integer",
              "title": "Current Viewers",
              "description": "Concurrent viewers at collection time"
            },
            "likeCount": {
              "type": "integer",
              "title": "Like Count",
              "description": "Likes received by the current stream"
            },
            "diggCount": {
              "type": "integer",
              "title": "Digg Count",
              "description": "TikTok's digg counter for the current stream"
            },
            "shareCount": {
              "type": "integer",
              "title": "Share Count",
              "description": "Shares of the current stream"
            },
            "commentCount": {
              "type": "integer",
              "title": "Comment Count",
              "description": "Chat comments posted in the current stream (room stats)"
            },
            "followCount": {
              "type": "integer",
              "title": "Follow Count",
              "description": "Follows attributed to the current stream"
            },
            "giftUvCount": {
              "type": "integer",
              "title": "Gift UV Count",
              "description": "Unique viewers who sent a gift in the current stream"
            },
            "watchUserCount": {
              "type": "integer",
              "title": "Watch User Count",
              "description": "TikTok's watched-user counter for the room, when exposed"
            },
            "roomFollowCount": {
              "type": "integer",
              "title": "Room Follow Count",
              "description": "Follows recorded inside the room"
            },
            "totalUser": {
              "type": "integer",
              "title": "Total User Count",
              "description": "TikTok's total-user counter for the room"
            },
            "coverUrl": {
              "type": "string",
              "title": "Cover URL",
              "description": "Signed room cover image URL"
            },
            "squareCoverUrl": {
              "type": "string",
              "title": "Square Cover URL",
              "description": "Signed square room cover image URL"
            },
            "hashtagId": {
              "type": "integer",
              "title": "Hashtag ID",
              "description": "TikTok hashtag ID associated with the room"
            },
            "gameTagId": {
              "type": "integer",
              "title": "Game Tag ID",
              "description": "TikTok game tag ID associated with the room"
            },
            "isPaidEvent": {
              "type": "boolean",
              "title": "Paid Event",
              "description": "Whether the LIVE is a paid/ticketed event"
            },
            "isSubscriberOnly": {
              "type": "boolean",
              "title": "Subscriber Only",
              "description": "Whether the LIVE is restricted to subscribers"
            },
            "streamId": {
              "type": "string",
              "title": "Stream ID",
              "description": "TikTok stream identifier"
            },
            "liveUrl": {
              "type": "string",
              "title": "Live URL",
              "description": "Public TikTok URL of the creator's LIVE page"
            },
            "sourceUrl": {
              "type": "string",
              "title": "Source URL",
              "description": "Public TikTok URL the record describes"
            },
            "streamUrls": {
              "type": "object",
              "title": "Stream URLs",
              "description": "HLS/FLV playback URLs keyed by quality (for example hls_hd_60, flv_origin). Signed and expiring."
            },
            "streamUrlExpiresAt": {
              "type": "string",
              "title": "Stream URL Expires At",
              "description": "Earliest ISO 8601 expiry parsed from the signed playback URLs"
            },
            "checkAlive": {
              "type": "boolean",
              "title": "Check Alive",
              "description": "Result of TikTok's real-time room check, when it answered"
            },
            "scrapedAt": {
              "type": "string",
              "title": "Scraped At",
              "description": "ISO 8601 UTC timestamp when the record was collected"
            },
            "error": {
              "type": "string",
              "title": "Error",
              "description": "Short reason when a creator could not be read (unavailable rows only)"
            },
            "eventType": {
              "type": "string",
              "title": "Event Type",
              "description": "chat, gift, like, follow, share, join, stats or other"
            },
            "receivedAt": {
              "type": "string",
              "title": "Received At",
              "description": "ISO 8601 UTC timestamp when the event was received"
            },
            "eventTimestamp": {
              "type": "string",
              "title": "Event Timestamp",
              "description": "ISO 8601 UTC timestamp from TikTok's event create time, when available"
            },
            "msgId": {
              "type": "string",
              "title": "Message ID",
              "description": "TikTok message ID used to deduplicate replayed events"
            },
            "user": {
              "type": "object",
              "title": "User",
              "description": "User who triggered the event",
              "properties": {
                "id": {
                  "type": "string",
                  "title": "User ID"
                },
                "secUid": {
                  "type": "string",
                  "title": "secUid"
                },
                "username": {
                  "type": "string",
                  "title": "Username"
                },
                "displayName": {
                  "type": "string",
                  "title": "Display Name"
                },
                "avatarUrl": {
                  "type": "string",
                  "title": "Avatar URL"
                },
                "verified": {
                  "type": "boolean",
                  "title": "Verified"
                }
              }
            },
            "payload": {
              "type": "object",
              "title": "Payload",
              "description": "Event-specific data: text/emotes (chat), gift fields, like counts, viewer counts, follow/share fields, or rawMethod for unmapped events",
              "properties": {
                "text": {
                  "type": "string",
                  "title": "Chat Text"
                },
                "emotes": {
                  "type": "array",
                  "title": "Emotes"
                },
                "contentLanguage": {
                  "type": "string",
                  "title": "Content Language"
                },
                "giftName": {
                  "type": "string",
                  "title": "Gift Name"
                },
                "giftId": {
                  "type": "string",
                  "title": "Gift ID"
                },
                "giftCount": {
                  "type": "integer",
                  "title": "Gift Count"
                },
                "giftDiamondCount": {
                  "type": "integer",
                  "title": "Gift Diamond Value"
                },
                "giftTotalDiamonds": {
                  "type": "integer",
                  "title": "Gift Total Diamonds"
                },
                "repeatEnd": {
                  "type": "boolean",
                  "title": "Gift Streak Ended"
                },
                "likeCount": {
                  "type": "integer",
                  "title": "Like Count"
                },
                "totalLikes": {
                  "type": "integer",
                  "title": "Total Likes"
                },
                "viewerCount": {
                  "type": "integer",
                  "title": "Viewer Count"
                },
                "totalUsers": {
                  "type": "integer",
                  "title": "Total Users"
                },
                "actionId": {
                  "type": "integer",
                  "title": "Join Action ID"
                },
                "action": {
                  "type": "integer",
                  "title": "Social Action",
                  "description": "TikTok's social action code for the follow/share event"
                },
                "shareType": {
                  "type": "integer",
                  "title": "Share Type",
                  "description": "TikTok's share channel code, when reported"
                },
                "shareTarget": {
                  "type": "string",
                  "title": "Share Target",
                  "description": "Share destination, when TikTok reports a usable value"
                },
                "shareCount": {
                  "type": "integer",
                  "title": "Room Share Count",
                  "description": "Cumulative room share count reported with the event"
                },
                "followCount": {
                  "type": "integer",
                  "title": "Host Follow Count",
                  "description": "Cumulative host follow count reported with the event"
                },
                "rawMethod": {
                  "type": "string",
                  "title": "Raw Method"
                },
                "payloadSize": {
                  "type": "integer",
                  "title": "Payload Size"
                }
              }
            }
          }
        }
      },
      "environmentVariables": {}
    },
    "buildNumber": "1.1.1",
    "imageDigest": "e339c7f78c6f723318eaeb02362725257cf0fb60d56134d615b1dcacb07e619c",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.1"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.0043122222222222225
    }
  }
}