{
  "data": {
    "id": "DzJaUztInWd9xlRqc",
    "actId": "XgHgPRuRuydAmORvP",
    "userId": "IYgBDiXtHOijAaUel",
    "startedAt": "2026-11-06T18:18:31.619Z",
    "finishedAt": "2026-11-06T18:18:42.601Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 10889,
      "runTimeSecs": 10.889,
      "computeUnits": 0.012098888888888888,
      "imageSizeBytes": 320029184
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "QYo53EZkJk0prePWY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Snapchat Spotlight Video Downloader\",\n  \"description\": \"Download video metadata and direct CDN URLs for Snapchat Spotlight posts.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"spotlightUrls\": {\n      \"title\": \"Spotlight URLs\",\n      \"type\": \"array\",\n      \"description\": \"One or more Snapchat Spotlight URLs to download. Supports snapchat.com/spotlight/... (with or without www), snapchat.com/@user/spotlight/..., snapchat.com/t/..., story.snapchat.com/o/... and /s/..., and t.snapchat.com short links.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"minItems\": 1,\n      \"prefill\": [\n        \"https://www.snapchat.com/@baby_d4700/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYdHVudG1rbWl5AZtVrgXFAZtVrgWTAAAAAQ\"\n      ]\n    },\n    \"includeTranscript\": {\n      \"type\": \"boolean\",\n      \"default\": true,\n      \"title\": \"Include Video Transcript\",\n      \"description\": \"Parse WebVTT transcript if available (adds transcript[] array)\",\n      \"prefill\": false\n    },\n    \"includeAiMetadata\": {\n      \"type\": \"boolean\",\n      \"default\": true,\n      \"title\": \"Include AI Metadata\",\n      \"description\": \"Include LLM-generated title, description, keywords, context cards\",\n      \"prefill\": true\n    },\n    \"includeComments\": {\n      \"type\": \"boolean\",\n      \"default\": false,\n      \"title\": \"Include Comment Threads\",\n      \"description\": \"Decode and include comment threads from the page\",\n      \"prefill\": false\n    },\n    \"includeRelatedStories\": {\n      \"type\": \"boolean\",\n      \"default\": false,\n      \"title\": \"Include Related Stories\",\n      \"description\": \"Include up to 24 related Spotlight stories from the feed\",\n      \"prefill\": false\n    },\n    \"proxyConfiguration\": {\n      \"title\": \"Proxy Configuration\",\n      \"type\": \"object\",\n      \"description\": \"Optional proxy settings. Snapchat public Spotlight pages work without a proxy in most regions.\",\n      \"editor\": \"proxy\",\n      \"sectionCaption\": \"Proxy\",\n      \"nullable\": true\n    }\n  },\n  \"required\": [\n    \"spotlightUrls\"\n  ]\n}",
    "readme": "# Snapchat Spotlight Video Link & Caption Downloader\r\n\r\nA Snapchat Spotlight link on its own doesn't give you a file you can save or embed. This actor turns one or more of those links into a direct video URL alongside thumbnail, caption, creator info, and engagement counts — with AI-generated descriptions, a WebVTT transcript, comment threads, and related videos available on request. No login or cookies required.\r\n\r\n## What this actor does\r\n\r\n- Resolves a Spotlight link (including short `t.snapchat.com` links) into a direct, downloadable video URL\r\n- Extracts data from JSON-LD first, Next.js Flight data second, and legacy `__NEXT_DATA__` last\r\n- Requires an exact match for the requested snap ID, so a dead or mismatched link never returns another video\r\n- Captures caption, creator info, and full engagement stats — shares, likes, comments, recommendations\r\n- Preserves real zero counts instead of dropping them\r\n- Adds AI-generated title, description, keywords and detected languages, on request\r\n- Parses the video's WebVTT transcript into timestamped segments, on request\r\n- Can also pull comment threads and up to 24 related Spotlight stories from the same feed\r\n- Leaves a field out of the record when Snapchat didn't provide a value for it, rather than sending it empty\r\n\r\n## Input\r\n\r\n| Field | Type | Required | Default | Description |\r\n|-------|------|----------|---------|-------------|\r\n| `spotlightUrls` | string[] | Yes | — | One or more Snapchat Spotlight URLs to process |\r\n| `includeTranscript` | boolean | No | `true` | Parse WebVTT transcript into timestamped segments |\r\n| `includeAiMetadata` | boolean | No | `true` | Include LLM title, description, keywords, context cards, detected languages |\r\n| `includeComments` | boolean | No | `false` | Decode comment threads from the page |\r\n| `includeRelatedStories` | boolean | No | `false` | Include up to 24 related Spotlight stories |\r\n| `proxyConfiguration` | object | No | — | Optional proxy settings |\r\n\r\n### Supported URL Formats\r\n\r\n```\r\nhttps://www.snapchat.com/spotlight/{id}\r\nhttps://snapchat.com/spotlight/{id}\r\nhttps://www.snapchat.com/@{username}/spotlight/{id}\r\nhttps://www.snapchat.com/t/{id}\r\nhttps://story.snapchat.com/o/{id}\r\nhttps://story.snapchat.com/s/{id}\r\nhttps://t.snapchat.com/{code}\r\n```\r\n\r\nAll forms are normalized to a canonical Spotlight URL. Short links (`t.snapchat.com`) are resolved automatically before scraping, and duplicate snap IDs are skipped within a run.\r\n\r\n## Output Fields\r\n\r\n### Core Fields\r\n\r\n`snapId`, `inputUrl`, `videoUrl`, `availability`, and `scrapedAt` are always present on success. The remaining fields are emitted when the current JSON-LD/Flight/legacy payload exposes them.\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `snapId` | string | Unique Spotlight snap identifier |\r\n| `inputUrl` | string | The URL you provided as input |\r\n| `videoUrl` | string | Direct CDN video URL |\r\n| `availability` | string | `available`, `restricted`, `unavailable`, or `unknown` |\r\n| `thumbnailUrl` | string | Thumbnail image URL |\r\n| `caption` | string | Caption or description text on the snap |\r\n| `creatorUsername` | string | Creator's Snapchat username |\r\n| `profileUrl` | string | Full profile URL (`snapchat.com/@username`) |\r\n| `creatorDisplayName` | string | Creator's display name |\r\n| `durationSeconds` | number | Video duration in seconds |\r\n| `uploadedAt` | string | ISO 8601 upload timestamp |\r\n| `scrapedAt` | string | ISO 8601 timestamp of when this record was collected |\r\n| `shareCount` | integer | Number of times the video was shared |\r\n| `commentCount` | integer | Number of comments |\r\n| `likeCount` | integer | Number of likes (boosts) |\r\n| `recommendCount` | integer | Number of recommendations |\r\n| `mediaPreviewUrl` | string | Preview/thumbnail variant URL (legacy page data only) |\r\n| `width` | integer | Video width in pixels (video snaps only) |\r\n| `height` | integer | Video height in pixels (video snaps only) |\r\n| `restricted` | boolean | Whether Snapchat marks the content as age- or region-restricted |\r\n| `isAttributed` | boolean | Whether Snapchat attributes the snap to a creator account rather than an unattributed feed item |\r\n\r\n> `viewCount` is omitted for very recent videos — Snapchat returns -1 as a sentinel value for posts still accumulating views.\r\n\r\n### AI Metadata (when `includeAiMetadata: true`)\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `llmTitle` | string | AI title when the page exposes it (legacy pages) |\r\n| `llmDescription` | string | AI description when the page exposes it |\r\n| `llmKeywords` | string[] | Keyword tags from the page metadata |\r\n| `textMetadataKeywords` | string[] | Text-based keyword tags (legacy page data only) |\r\n| `hashtags` | string[] | Hashtags associated with the snap |\r\n| `contextCards` | object[] | Context cards shown on the snap (sound info, creator card, etc.) |\r\n| `detectedLanguages` | object[] | Detected languages with confidence scores (legacy page data only) |\r\n\r\n### Transcript (when `includeTranscript: true`)\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `transcript` | object[] | Array of `{startTime, endTime, text}` WebVTT segments |\r\n| `transcriptUrl` | string | URL of the raw WebVTT transcript file |\r\n\r\n### Comments (when `includeComments: true`, up to 500 via the public cursor API)\r\n\r\nEach item in `comments[]`:\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `commentId` | string | Unique comment identifier |\r\n| `snapId` | string | ID of the snap this comment belongs to |\r\n| `replyText` | string | Comment text |\r\n| `reactionCounts` | object[] | Array of `{reactTypeId, count}` reaction tallies |\r\n| `commenterDisplayName` | string | Commenter's display name |\r\n| `approvalState` | any | Moderation approval state |\r\n| `postedAt` | string | ISO 8601 timestamp when the comment was posted |\r\n\r\n### Related Stories (when `includeRelatedStories: true`)\r\n\r\nEach item in `relatedStories[]`:\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `thumbnailUrl` | string | Thumbnail URL of the related story |\r\n| `storyPageUrl` | string | Full Spotlight URL of the related story |\r\n| `durationSeconds` | number | Duration of the related story in seconds |\r\n| `creatorUsername` | string | Creator's username |\r\n| `caption` | string | Related story caption when present |\r\n\r\n### Error Records\r\n\r\nIf a URL fails, an error record is saved instead of a video record:\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `inputUrl` | string | The URL that failed |\r\n| `snapId` | string | Snap ID if it could be extracted |\r\n| `error` | string | Human-readable error message |\r\n| `availability` | string | `unavailable` when the snap was not found, `unknown` for fetch/parse failures |\r\n| `scrapedAt` | string | ISO 8601 timestamp |\r\n\r\nA dead, deleted, or mismatched link returns an `unavailable` record with the requested `snapId` and no `videoUrl`; the actor never substitutes a different video.\r\n\r\n## Example Input\r\n\r\n```json\r\n{\r\n  \"spotlightUrls\": [\r\n    \"https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYZmRwYmVqcm5wAZ8Kxg_vAZ8Kxgn9AAAAAQ\",\r\n    \"https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYZG5iaHJuY2phAZ8KF10GAZ8KETc1AAAAAQ\"\r\n  ],\r\n  \"includeTranscript\": true,\r\n  \"includeAiMetadata\": true,\r\n  \"includeComments\": false,\r\n  \"includeRelatedStories\": false\r\n}\r\n```\r\n\r\n## Example Output\r\n\r\n```json\r\n{\r\n  \"snapId\": \"W7_EDlXWTBiXAEEniNoMPwAAYZG5iaHJuY2phAZ8KF10GAZ8KETc1AAAAAQ\",\r\n  \"inputUrl\": \"https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYZG5iaHJuY2phAZ8KF10GAZ8KETc1AAAAAQ\",\r\n  \"availability\": \"available\",\r\n  \"videoUrl\": \"https://bolt-gcdn.sc-cdn.net/v/udlVbjK0wdjHbPx1FRph0.27.IRZXSOY?...\",\r\n  \"thumbnailUrl\": \"https://bolt-gcdn.sc-cdn.net/v/udlVbjK0wdjHbPx1FRph0.256.IRZXSOY?...\",\r\n  \"caption\": \"Another Spotlight Snap brought to you by Snapchat\",\r\n  \"creatorUsername\": \"waqarzaka\",\r\n  \"profileUrl\": \"https://www.snapchat.com/@waqarzaka\",\r\n  \"creatorDisplayName\": \"Waqar Zaka\",\r\n  \"durationSeconds\": 130.23,\r\n  \"width\": 540,\r\n  \"height\": 960,\r\n  \"shareCount\": 0,\r\n  \"likeCount\": 3,\r\n  \"commentCount\": 0,\r\n  \"recommendCount\": 0,\r\n  \"uploadedAt\": \"2026-06-27T17:12:08.245000+00:00\",\r\n  \"scrapedAt\": \"2026-06-28T06:43:34.588497+00:00\",\r\n  \"isAttributed\": true,\r\n  \"textMetadataKeywords\": [\"bitcoin\", \"hacker\", \"crypto\", \"cryptocurrency\", \"blockchain\"],\r\n  \"contextCards\": [\r\n    {\r\n      \"contextType\": 3,\r\n      \"title\": \"Waqar Zaka\",\r\n      \"subtitle\": \"waqarzaka\",\r\n      \"url\": \"https://www.snapchat.com/@waqarzaka\",\r\n      \"thumbnailType\": 0,\r\n      \"hasBadge\": true,\r\n      \"id\": \"36d0088b-39d5-4765-a237-bb147a292272\"\r\n    }\r\n  ],\r\n  \"detectedLanguages\": [\r\n    { \"languageCode\": \"hi\", \"score\": 0.910262405872345 }\r\n  ]\r\n}\r\n```\r\n\r\n## FAQ\r\n\r\n**Does this require a Snapchat account or cookies?**\r\nNo. All data is extracted from public Snapchat Spotlight pages. No login, no cookies, and no proxy are required in most regions.\r\n\r\n**Do video URLs expire?**\r\nThere is no fixed expiry that this actor relies on or promises. The returned URL is the CDN URL Snapchat served at scrape time; Snapchat can rotate, restrict, or remove it at any time. Save the file promptly if you need a durable copy.\r\n\r\n**Why is `viewCount` missing from some records?**\r\nSnapchat returns -1 as a sentinel for videos that are too new to have an accurate view count. The actor omits this field rather than storing a misleading -1. A real zero is kept as `0`.\r\n\r\n**Are `width` and `height` always present?**\r\nOnly for video snaps. Some Spotlight posts are images or have incomplete metadata, in which case these fields are absent.\r\n\r\n**Can I scrape a large batch of URLs at once?**\r\nYes. Provide all URLs in the `spotlightUrls` array. The actor processes them sequentially with a short delay between requests to stay respectful of rate limits. Duplicate snap IDs are skipped after normalization.\r\n\r\n**What is the `isAttributed` flag?**\r\nWhen `true`, Snapchat attributes the snap to a creator account. When absent, Snapchat did not expose the flag.\r\n\r\n**What happens when a link is dead or points to a removed snap?**\r\nThe actor verifies the requested snap ID against the page data. If it cannot find that exact ID, it writes an `availability: \"unavailable\"` record with the error message and no `videoUrl`. It never returns a different video.\r\n\r\n**What does `availability` mean?**\r\n`available` means a video URL was returned. `restricted` means the page only exposed restricted content. `unavailable` means the exact snap was not found. `unknown` means a fetch or parse failure prevented a decision. `restricted: true` means Snapchat marks the content as age- or region-restricted.\r\n\r\n**Can I get comments and transcripts from all videos?**\r\nSet `includeComments` and/or `includeTranscript`. Comments and WebVTT transcripts are only returned when Snapchat exposes them for that snap. Related stories are limited to the first 24 usable entries.\r\n\r\n**Is this affiliated with Snapchat?**\r\nNo. This is an independent data extraction tool and has no connection to Snap Inc.\r\n\r\n## Limits\r\n\r\n- Public Spotlight pages only; no login, cookies, private profiles, or Stories.\r\n- The requested snap ID must appear in the page data. There is no \"first video on the page\" fallback.\r\n- JSON-LD, Flight, and legacy `__NEXT_DATA__` layouts are supported, but Snapchat can change them at any time.\r\n- Comments, transcripts, AI metadata, and related stories depend on what Snapchat includes for each snap.\r\n- Short links are resolved over the network; a dead short link becomes an `unavailable` record.\r\n- CDN URLs are not guaranteed to remain valid after collection.\r\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "snapchat-spotlight-video-link-and-caption",
      "title": "Snapchat Spotlight Video Link & Caption Downloader",
      "description": "Give this actor one or more Snapchat Spotlight links and get back a direct video link, thumbnail, caption, creator info and engagement counts per video, with optional AI-generated metadata, transcript and comments.",
      "version": "1.0",
      "buildTag": "latest",
      "meta": {
        "templateId": "python"
      },
      "input": {
        "title": "Snapchat Spotlight Video Downloader",
        "description": "Download video metadata and direct CDN URLs for Snapchat Spotlight posts.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "spotlightUrls": {
            "title": "Spotlight URLs",
            "type": "array",
            "description": "One or more Snapchat Spotlight URLs to download. Supports snapchat.com/spotlight/... (with or without www), snapchat.com/@user/spotlight/..., snapchat.com/t/..., story.snapchat.com/o/... and /s/..., and t.snapchat.com short links.",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "prefill": [
              "https://www.snapchat.com/@baby_d4700/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYdHVudG1rbWl5AZtVrgXFAZtVrgWTAAAAAQ"
            ]
          },
          "includeTranscript": {
            "type": "boolean",
            "default": true,
            "title": "Include Video Transcript",
            "description": "Parse WebVTT transcript if available (adds transcript[] array)",
            "prefill": false
          },
          "includeAiMetadata": {
            "type": "boolean",
            "default": true,
            "title": "Include AI Metadata",
            "description": "Include LLM-generated title, description, keywords, context cards",
            "prefill": true
          },
          "includeComments": {
            "type": "boolean",
            "default": false,
            "title": "Include Comment Threads",
            "description": "Decode and include comment threads from the page",
            "prefill": false
          },
          "includeRelatedStories": {
            "type": "boolean",
            "default": false,
            "title": "Include Related Stories",
            "description": "Include up to 24 related Spotlight stories from the feed",
            "prefill": false
          },
          "proxyConfiguration": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Optional proxy settings. Snapchat public Spotlight pages work without a proxy in most regions.",
            "editor": "proxy",
            "sectionCaption": "Proxy",
            "nullable": true
          }
        },
        "required": [
          "spotlightUrls"
        ]
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Snapchat Spotlight Video Link & Caption Downloader Output",
        "type": "object",
        "description": "One record per Snapchat Spotlight link, with its direct video URL, caption, creator info, engagement counts and optional AI metadata, transcript and comments.",
        "properties": {
          "results": {
            "type": "string",
            "description": "Dataset containing scraped Spotlight video records",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        },
        "fields": {
          "snapId": {
            "type": "string",
            "description": "Spotlight snap ID"
          },
          "inputUrl": {
            "type": "string",
            "description": "Original input URL supplied by the user"
          },
          "videoUrl": {
            "type": "string",
            "description": "Direct CDN video URL"
          },
          "availability": {
            "type": "string",
            "enum": [
              "available",
              "restricted",
              "unavailable",
              "unknown"
            ],
            "description": "Whether a usable video URL was returned. 'restricted' means the page only exposed restricted content; 'unavailable' means the requested snap was not found; 'unknown' means a fetch or parse failure prevented a decision."
          },
          "restricted": {
            "type": "boolean",
            "description": "Whether Snapchat marks this snap as age- or region-restricted"
          },
          "thumbnailUrl": {
            "type": "string",
            "description": "Thumbnail image URL"
          },
          "caption": {
            "type": "string",
            "description": "Video caption / description text"
          },
          "creatorUsername": {
            "type": "string",
            "description": "Creator Snapchat username"
          },
          "creatorDisplayName": {
            "type": "string",
            "description": "Creator display name"
          },
          "creatorFollowerCount": {
            "type": "integer",
            "description": "Creator follower count"
          },
          "profileUrl": {
            "type": "string",
            "description": "Creator Snapchat profile URL"
          },
          "durationSeconds": {
            "type": "number",
            "description": "Video duration in seconds"
          },
          "width": {
            "type": "integer",
            "description": "Video width in pixels"
          },
          "height": {
            "type": "integer",
            "description": "Video height in pixels"
          },
          "name": {
            "type": "string",
            "description": "Video name from metadata (when available)"
          },
          "viewCount": {
            "type": "integer",
            "description": "Total view count (from engagementStats or videoMetadata)"
          },
          "shareCount": {
            "type": "integer",
            "description": "Total share count"
          },
          "commentCount": {
            "type": "integer",
            "description": "Total comment count (from engagementStats)"
          },
          "likeCount": {
            "type": "integer",
            "description": "Like/boost count (from engagementStats)"
          },
          "recommendCount": {
            "type": "integer",
            "description": "Recommend count (from engagementStats)"
          },
          "uploadedAt": {
            "type": "string",
            "description": "Upload timestamp in ISO 8601 UTC"
          },
          "lat": {
            "type": "number",
            "description": "Snap latitude (when geotagged)"
          },
          "lng": {
            "type": "number",
            "description": "Snap longitude (when geotagged)"
          },
          "snapTitle": {
            "type": "string",
            "description": "Snap title (when present)"
          },
          "audioTranscriptionObjectUrl": {
            "type": "string",
            "description": "URL to audio transcription object (when available)"
          },
          "overlayUrl": {
            "type": "string",
            "description": "Overlay image URL (when present)"
          },
          "mediaPreviewUrl": {
            "type": "string",
            "description": "Media preview image URL"
          },
          "attachmentUrl": {
            "type": "string",
            "description": "Attachment URL linked from the snap (sparse)"
          },
          "snapSubtitles": {
            "type": "array",
            "description": "Subtitle/caption data embedded in the snap (when present)"
          },
          "intervalStartTimeMs": {
            "type": "integer",
            "description": "Snap interval start time in milliseconds (when present)"
          },
          "isSponsored": {
            "type": "boolean",
            "description": "Whether this snap is sponsored content"
          },
          "hasAttachment": {
            "type": "boolean",
            "description": "Whether this snap has an attachment"
          },
          "llmDescription": {
            "type": "string",
            "description": "AI-generated description (when include_ai_metadata=true)"
          },
          "llmTitle": {
            "type": "string",
            "description": "AI-generated title (when include_ai_metadata=true)"
          },
          "llmKeywords": {
            "type": "array",
            "description": "AI-generated keywords (when include_ai_metadata=true)"
          },
          "textMetadataKeywords": {
            "type": "array",
            "description": "Text metadata keywords (when include_ai_metadata=true)"
          },
          "hashtags": {
            "type": "array",
            "description": "Hashtags associated with the snap (when include_ai_metadata=true)"
          },
          "contextCards": {
            "type": "array",
            "description": "Context card objects linked to the snap (when include_ai_metadata=true)"
          },
          "detectedLanguages": {
            "type": "array",
            "description": "Detected language scores [{languageCode, score}] from cuSignals (when include_ai_metadata=true)"
          },
          "transcript": {
            "type": "array",
            "description": "Parsed WebVTT transcript segments [{startTime, endTime, text}] (when includeTranscript=true)"
          },
          "transcriptUrl": {
            "type": "string",
            "description": "URL to original WebVTT transcript file (when transcript is available)"
          },
          "isAttributed": {
            "type": "boolean",
            "description": "Whether the snap is attributed to a creator"
          },
          "comments": {
            "type": "array",
            "description": "Comment threads for the snap (when includeComments=true and Snapchat exposes them)",
            "items": {
              "type": "object",
              "properties": {
                "commentId": {
                  "type": "string"
                },
                "snapId": {
                  "type": "string"
                },
                "replyText": {
                  "type": "string"
                },
                "reactionCounts": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "reactTypeId": {
                        "type": "string"
                      },
                      "count": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "commenterDisplayName": {
                  "type": "string"
                },
                "commenterBitmojiAvatarId": {
                  "type": "string"
                },
                "commenterBitmojiSelfieId": {
                  "type": "string"
                },
                "reportCount": {
                  "type": "integer"
                },
                "approvalState": {},
                "postedAt": {
                  "type": "string"
                }
              }
            }
          },
          "relatedStories": {
            "type": "array",
            "description": "Related spotlight story summaries with thumbnailUrl, storyPageUrl, durationSeconds, creatorUsername"
          },
          "scrapedAt": {
            "type": "string",
            "description": "ISO 8601 UTC timestamp when this record was scraped"
          },
          "error": {
            "type": "string",
            "description": "Error message if scraping failed for this URL"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "readme": "# Snapchat Spotlight Video Link & Caption Downloader\r\n\r\nA Snapchat Spotlight link on its own doesn't give you a file you can save or embed. This actor turns one or more of those links into a direct video URL alongside thumbnail, caption, creator info, and engagement counts — with AI-generated descriptions, a WebVTT transcript, comment threads, and related videos available on request. No login or cookies required.\r\n\r\n## What this actor does\r\n\r\n- Resolves a Spotlight link (including short `t.snapchat.com` links) into a direct, downloadable video URL\r\n- Extracts data from JSON-LD first, Next.js Flight data second, and legacy `__NEXT_DATA__` last\r\n- Requires an exact match for the requested snap ID, so a dead or mismatched link never returns another video\r\n- Captures caption, creator info, and full engagement stats — shares, likes, comments, recommendations\r\n- Preserves real zero counts instead of dropping them\r\n- Adds AI-generated title, description, keywords and detected languages, on request\r\n- Parses the video's WebVTT transcript into timestamped segments, on request\r\n- Can also pull comment threads and up to 24 related Spotlight stories from the same feed\r\n- Leaves a field out of the record when Snapchat didn't provide a value for it, rather than sending it empty\r\n\r\n## Input\r\n\r\n| Field | Type | Required | Default | Description |\r\n|-------|------|----------|---------|-------------|\r\n| `spotlightUrls` | string[] | Yes | — | One or more Snapchat Spotlight URLs to process |\r\n| `includeTranscript` | boolean | No | `true` | Parse WebVTT transcript into timestamped segments |\r\n| `includeAiMetadata` | boolean | No | `true` | Include LLM title, description, keywords, context cards, detected languages |\r\n| `includeComments` | boolean | No | `false` | Decode comment threads from the page |\r\n| `includeRelatedStories` | boolean | No | `false` | Include up to 24 related Spotlight stories |\r\n| `proxyConfiguration` | object | No | — | Optional proxy settings |\r\n\r\n### Supported URL Formats\r\n\r\n```\r\nhttps://www.snapchat.com/spotlight/{id}\r\nhttps://snapchat.com/spotlight/{id}\r\nhttps://www.snapchat.com/@{username}/spotlight/{id}\r\nhttps://www.snapchat.com/t/{id}\r\nhttps://story.snapchat.com/o/{id}\r\nhttps://story.snapchat.com/s/{id}\r\nhttps://t.snapchat.com/{code}\r\n```\r\n\r\nAll forms are normalized to a canonical Spotlight URL. Short links (`t.snapchat.com`) are resolved automatically before scraping, and duplicate snap IDs are skipped within a run.\r\n\r\n## Output Fields\r\n\r\n### Core Fields\r\n\r\n`snapId`, `inputUrl`, `videoUrl`, `availability`, and `scrapedAt` are always present on success. The remaining fields are emitted when the current JSON-LD/Flight/legacy payload exposes them.\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `snapId` | string | Unique Spotlight snap identifier |\r\n| `inputUrl` | string | The URL you provided as input |\r\n| `videoUrl` | string | Direct CDN video URL |\r\n| `availability` | string | `available`, `restricted`, `unavailable`, or `unknown` |\r\n| `thumbnailUrl` | string | Thumbnail image URL |\r\n| `caption` | string | Caption or description text on the snap |\r\n| `creatorUsername` | string | Creator's Snapchat username |\r\n| `profileUrl` | string | Full profile URL (`snapchat.com/@username`) |\r\n| `creatorDisplayName` | string | Creator's display name |\r\n| `durationSeconds` | number | Video duration in seconds |\r\n| `uploadedAt` | string | ISO 8601 upload timestamp |\r\n| `scrapedAt` | string | ISO 8601 timestamp of when this record was collected |\r\n| `shareCount` | integer | Number of times the video was shared |\r\n| `commentCount` | integer | Number of comments |\r\n| `likeCount` | integer | Number of likes (boosts) |\r\n| `recommendCount` | integer | Number of recommendations |\r\n| `mediaPreviewUrl` | string | Preview/thumbnail variant URL (legacy page data only) |\r\n| `width` | integer | Video width in pixels (video snaps only) |\r\n| `height` | integer | Video height in pixels (video snaps only) |\r\n| `restricted` | boolean | Whether Snapchat marks the content as age- or region-restricted |\r\n| `isAttributed` | boolean | Whether Snapchat attributes the snap to a creator account rather than an unattributed feed item |\r\n\r\n> `viewCount` is omitted for very recent videos — Snapchat returns -1 as a sentinel value for posts still accumulating views.\r\n\r\n### AI Metadata (when `includeAiMetadata: true`)\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `llmTitle` | string | AI title when the page exposes it (legacy pages) |\r\n| `llmDescription` | string | AI description when the page exposes it |\r\n| `llmKeywords` | string[] | Keyword tags from the page metadata |\r\n| `textMetadataKeywords` | string[] | Text-based keyword tags (legacy page data only) |\r\n| `hashtags` | string[] | Hashtags associated with the snap |\r\n| `contextCards` | object[] | Context cards shown on the snap (sound info, creator card, etc.) |\r\n| `detectedLanguages` | object[] | Detected languages with confidence scores (legacy page data only) |\r\n\r\n### Transcript (when `includeTranscript: true`)\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `transcript` | object[] | Array of `{startTime, endTime, text}` WebVTT segments |\r\n| `transcriptUrl` | string | URL of the raw WebVTT transcript file |\r\n\r\n### Comments (when `includeComments: true`, up to 500 via the public cursor API)\r\n\r\nEach item in `comments[]`:\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `commentId` | string | Unique comment identifier |\r\n| `snapId` | string | ID of the snap this comment belongs to |\r\n| `replyText` | string | Comment text |\r\n| `reactionCounts` | object[] | Array of `{reactTypeId, count}` reaction tallies |\r\n| `commenterDisplayName` | string | Commenter's display name |\r\n| `approvalState` | any | Moderation approval state |\r\n| `postedAt` | string | ISO 8601 timestamp when the comment was posted |\r\n\r\n### Related Stories (when `includeRelatedStories: true`)\r\n\r\nEach item in `relatedStories[]`:\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `thumbnailUrl` | string | Thumbnail URL of the related story |\r\n| `storyPageUrl` | string | Full Spotlight URL of the related story |\r\n| `durationSeconds` | number | Duration of the related story in seconds |\r\n| `creatorUsername` | string | Creator's username |\r\n| `caption` | string | Related story caption when present |\r\n\r\n### Error Records\r\n\r\nIf a URL fails, an error record is saved instead of a video record:\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `inputUrl` | string | The URL that failed |\r\n| `snapId` | string | Snap ID if it could be extracted |\r\n| `error` | string | Human-readable error message |\r\n| `availability` | string | `unavailable` when the snap was not found, `unknown` for fetch/parse failures |\r\n| `scrapedAt` | string | ISO 8601 timestamp |\r\n\r\nA dead, deleted, or mismatched link returns an `unavailable` record with the requested `snapId` and no `videoUrl`; the actor never substitutes a different video.\r\n\r\n## Example Input\r\n\r\n```json\r\n{\r\n  \"spotlightUrls\": [\r\n    \"https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYZmRwYmVqcm5wAZ8Kxg_vAZ8Kxgn9AAAAAQ\",\r\n    \"https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYZG5iaHJuY2phAZ8KF10GAZ8KETc1AAAAAQ\"\r\n  ],\r\n  \"includeTranscript\": true,\r\n  \"includeAiMetadata\": true,\r\n  \"includeComments\": false,\r\n  \"includeRelatedStories\": false\r\n}\r\n```\r\n\r\n## Example Output\r\n\r\n```json\r\n{\r\n  \"snapId\": \"W7_EDlXWTBiXAEEniNoMPwAAYZG5iaHJuY2phAZ8KF10GAZ8KETc1AAAAAQ\",\r\n  \"inputUrl\": \"https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYZG5iaHJuY2phAZ8KF10GAZ8KETc1AAAAAQ\",\r\n  \"availability\": \"available\",\r\n  \"videoUrl\": \"https://bolt-gcdn.sc-cdn.net/v/udlVbjK0wdjHbPx1FRph0.27.IRZXSOY?...\",\r\n  \"thumbnailUrl\": \"https://bolt-gcdn.sc-cdn.net/v/udlVbjK0wdjHbPx1FRph0.256.IRZXSOY?...\",\r\n  \"caption\": \"Another Spotlight Snap brought to you by Snapchat\",\r\n  \"creatorUsername\": \"waqarzaka\",\r\n  \"profileUrl\": \"https://www.snapchat.com/@waqarzaka\",\r\n  \"creatorDisplayName\": \"Waqar Zaka\",\r\n  \"durationSeconds\": 130.23,\r\n  \"width\": 540,\r\n  \"height\": 960,\r\n  \"shareCount\": 0,\r\n  \"likeCount\": 3,\r\n  \"commentCount\": 0,\r\n  \"recommendCount\": 0,\r\n  \"uploadedAt\": \"2026-06-27T17:12:08.245000+00:00\",\r\n  \"scrapedAt\": \"2026-06-28T06:43:34.588497+00:00\",\r\n  \"isAttributed\": true,\r\n  \"textMetadataKeywords\": [\"bitcoin\", \"hacker\", \"crypto\", \"cryptocurrency\", \"blockchain\"],\r\n  \"contextCards\": [\r\n    {\r\n      \"contextType\": 3,\r\n      \"title\": \"Waqar Zaka\",\r\n      \"subtitle\": \"waqarzaka\",\r\n      \"url\": \"https://www.snapchat.com/@waqarzaka\",\r\n      \"thumbnailType\": 0,\r\n      \"hasBadge\": true,\r\n      \"id\": \"36d0088b-39d5-4765-a237-bb147a292272\"\r\n    }\r\n  ],\r\n  \"detectedLanguages\": [\r\n    { \"languageCode\": \"hi\", \"score\": 0.910262405872345 }\r\n  ]\r\n}\r\n```\r\n\r\n## FAQ\r\n\r\n**Does this require a Snapchat account or cookies?**\r\nNo. All data is extracted from public Snapchat Spotlight pages. No login, no cookies, and no proxy are required in most regions.\r\n\r\n**Do video URLs expire?**\r\nThere is no fixed expiry that this actor relies on or promises. The returned URL is the CDN URL Snapchat served at scrape time; Snapchat can rotate, restrict, or remove it at any time. Save the file promptly if you need a durable copy.\r\n\r\n**Why is `viewCount` missing from some records?**\r\nSnapchat returns -1 as a sentinel for videos that are too new to have an accurate view count. The actor omits this field rather than storing a misleading -1. A real zero is kept as `0`.\r\n\r\n**Are `width` and `height` always present?**\r\nOnly for video snaps. Some Spotlight posts are images or have incomplete metadata, in which case these fields are absent.\r\n\r\n**Can I scrape a large batch of URLs at once?**\r\nYes. Provide all URLs in the `spotlightUrls` array. The actor processes them sequentially with a short delay between requests to stay respectful of rate limits. Duplicate snap IDs are skipped after normalization.\r\n\r\n**What is the `isAttributed` flag?**\r\nWhen `true`, Snapchat attributes the snap to a creator account. When absent, Snapchat did not expose the flag.\r\n\r\n**What happens when a link is dead or points to a removed snap?**\r\nThe actor verifies the requested snap ID against the page data. If it cannot find that exact ID, it writes an `availability: \"unavailable\"` record with the error message and no `videoUrl`. It never returns a different video.\r\n\r\n**What does `availability` mean?**\r\n`available` means a video URL was returned. `restricted` means the page only exposed restricted content. `unavailable` means the exact snap was not found. `unknown` means a fetch or parse failure prevented a decision. `restricted: true` means Snapchat marks the content as age- or region-restricted.\r\n\r\n**Can I get comments and transcripts from all videos?**\r\nSet `includeComments` and/or `includeTranscript`. Comments and WebVTT transcripts are only returned when Snapchat exposes them for that snap. Related stories are limited to the first 24 usable entries.\r\n\r\n**Is this affiliated with Snapchat?**\r\nNo. This is an independent data extraction tool and has no connection to Snap Inc.\r\n\r\n## Limits\r\n\r\n- Public Spotlight pages only; no login, cookies, private profiles, or Stories.\r\n- The requested snap ID must appear in the page data. There is no \"first video on the page\" fallback.\r\n- JSON-LD, Flight, and legacy `__NEXT_DATA__` layouts are supported, but Snapchat can change them at any time.\r\n- Comments, transcripts, AI metadata, and related stories depend on what Snapchat includes for each snap.\r\n- Short links are resolved over the network; a dead short link becomes an `unavailable` record.\r\n- CDN URLs are not guaranteed to remain valid after collection.\r\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "Snapchat Spotlight Videos",
          "views": {
            "overview": {
              "title": "Video Overview",
              "transformation": {
                "fields": [
                  "snapId",
                  "creatorUsername",
                  "caption",
                  "viewCount",
                  "shareCount",
                  "commentCount",
                  "likeCount",
                  "durationSeconds",
                  "availability",
                  "videoUrl",
                  "thumbnailUrl"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "snapId": {
                    "label": "Snap ID",
                    "format": "text"
                  },
                  "creatorUsername": {
                    "label": "Creator",
                    "format": "text"
                  },
                  "caption": {
                    "label": "Caption",
                    "format": "text"
                  },
                  "viewCount": {
                    "label": "Views",
                    "format": "number"
                  },
                  "shareCount": {
                    "label": "Shares",
                    "format": "number"
                  },
                  "commentCount": {
                    "label": "Comments",
                    "format": "number"
                  },
                  "likeCount": {
                    "label": "Likes",
                    "format": "number"
                  },
                  "durationSeconds": {
                    "label": "Duration (s)",
                    "format": "number"
                  },
                  "availability": {
                    "label": "Availability",
                    "format": "text"
                  },
                  "videoUrl": {
                    "label": "Video URL",
                    "format": "link"
                  },
                  "thumbnailUrl": {
                    "label": "Thumbnail",
                    "format": "link"
                  }
                }
              }
            },
            "detailed": {
              "title": "Detailed View",
              "transformation": {
                "fields": [
                  "snapId",
                  "inputUrl",
                  "creatorUsername",
                  "creatorDisplayName",
                  "creatorFollowerCount",
                  "profileUrl",
                  "caption",
                  "name",
                  "width",
                  "height",
                  "viewCount",
                  "shareCount",
                  "commentCount",
                  "likeCount",
                  "recommendCount",
                  "durationSeconds",
                  "uploadedAt",
                  "videoUrl",
                  "thumbnailUrl",
                  "llmTitle",
                  "llmDescription",
                  "llmKeywords",
                  "hashtags",
                  "restricted",
                  "availability",
                  "isAttributed",
                  "scrapedAt",
                  "error"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "snapId": {
                    "label": "Snap ID",
                    "format": "text"
                  },
                  "inputUrl": {
                    "label": "Input URL",
                    "format": "link"
                  },
                  "creatorUsername": {
                    "label": "Username",
                    "format": "text"
                  },
                  "creatorDisplayName": {
                    "label": "Display Name",
                    "format": "text"
                  },
                  "creatorFollowerCount": {
                    "label": "Followers",
                    "format": "number"
                  },
                  "profileUrl": {
                    "label": "Profile",
                    "format": "link"
                  },
                  "caption": {
                    "label": "Caption",
                    "format": "text"
                  },
                  "name": {
                    "label": "Video Name",
                    "format": "text"
                  },
                  "width": {
                    "label": "Width",
                    "format": "number"
                  },
                  "height": {
                    "label": "Height",
                    "format": "number"
                  },
                  "viewCount": {
                    "label": "Views",
                    "format": "number"
                  },
                  "shareCount": {
                    "label": "Shares",
                    "format": "number"
                  },
                  "commentCount": {
                    "label": "Comments",
                    "format": "number"
                  },
                  "likeCount": {
                    "label": "Likes",
                    "format": "number"
                  },
                  "recommendCount": {
                    "label": "Recommends",
                    "format": "number"
                  },
                  "durationSeconds": {
                    "label": "Duration (s)",
                    "format": "number"
                  },
                  "uploadedAt": {
                    "label": "Uploaded At",
                    "format": "text"
                  },
                  "videoUrl": {
                    "label": "Video URL",
                    "format": "link"
                  },
                  "thumbnailUrl": {
                    "label": "Thumbnail",
                    "format": "link"
                  },
                  "llmTitle": {
                    "label": "AI Title",
                    "format": "text"
                  },
                  "llmDescription": {
                    "label": "AI Description",
                    "format": "text"
                  },
                  "hashtags": {
                    "label": "Hashtags",
                    "format": "text"
                  },
                  "llmKeywords": {
                    "label": "Keywords",
                    "format": "text"
                  },
                  "restricted": {
                    "label": "Restricted",
                    "format": "text"
                  },
                  "availability": {
                    "label": "Availability",
                    "format": "text"
                  },
                  "isAttributed": {
                    "label": "Is Attributed",
                    "format": "text"
                  },
                  "scrapedAt": {
                    "label": "Scraped At",
                    "format": "text"
                  },
                  "error": {
                    "label": "Error",
                    "format": "text"
                  }
                }
              }
            }
          }
        }
      }
    },
    "buildNumber": "1.0.2",
    "imageDigest": "928f4a4374490e5206e19f5bf8f11a43349e7b1766ecdc3eb66fb3dda01337be",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.012098888888888888
    }
  }
}