{
  "data": {
    "id": "dDxnim0EkVlo74Ldw",
    "actId": "q1TdCUHc87k8c3NFU",
    "userId": "NL4ThgItAwaoBlffQ",
    "startedAt": "2026-10-22T02:00:20.799Z",
    "finishedAt": "2026-10-22T02:00:32.732Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 11684,
      "runTimeSecs": 11.684,
      "computeUnits": 0.012982222222222221,
      "imageSizeBytes": 318436864
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "zifX0mkAFMHe8CatY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"YouTube Search Scraper Input\",\n  \"description\": \"Search YouTube by keyword for videos, Shorts, channels, playlists, or movies. Filter by upload date, duration, sort order, features, market, and language. Optional video details add exact publish dates, views, likes, categories, and tags.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"searchQueries\": {\n      \"title\": \"Search Queries\",\n      \"type\": \"array\",\n      \"description\": \"One or more YouTube search terms. Each query is scraped separately and its results are combined in the dataset.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1\n      },\n      \"minItems\": 1,\n      \"prefill\": [\n        \"apify\"\n      ]\n    },\n    \"maxResults\": {\n      \"title\": \"Max Results Per Query\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum number of results per query. YouTube may serve fewer rows for a given query, entity type, session, or IP; the run reports the requested and actual counts and whether the result pool was exhausted.\",\n      \"default\": 20,\n      \"minimum\": 1,\n      \"maximum\": 1000,\n      \"prefill\": 3\n    },\n    \"scrapeAllResults\": {\n      \"title\": \"Scrape All Available Results\",\n      \"type\": \"boolean\",\n      \"description\": \"Keep loading pages until YouTube stops offering results. This ignores Max Results Per Query and can take longer on broad searches.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"sortBy\": {\n      \"title\": \"Sort By\",\n      \"type\": \"string\",\n      \"description\": \"Order of the search results. YouTube currently supports relevance and popularity (view count). Legacy values upload_date and rating are accepted for saved tasks and mapped to relevance with a warning.\",\n      \"editor\": \"select\",\n      \"default\": \"relevance\",\n      \"prefill\": \"relevance\",\n      \"enumTitles\": [\n        \"Relevance\",\n        \"View count (popularity)\"\n      ],\n      \"enumSuggestedValues\": [\n        \"relevance\",\n        \"view_count\"\n      ]\n    },\n    \"uploadDate\": {\n      \"title\": \"Upload Date\",\n      \"type\": \"string\",\n      \"description\": \"Only return results uploaded in the selected period. Applies to videos and Shorts.\",\n      \"editor\": \"select\",\n      \"default\": \"\",\n      \"prefill\": \"\",\n      \"enum\": [\n        \"\",\n        \"last_hour\",\n        \"today\",\n        \"this_week\",\n        \"this_month\",\n        \"this_year\"\n      ],\n      \"enumTitles\": [\n        \"Any time\",\n        \"Last hour\",\n        \"Today\",\n        \"This week\",\n        \"This month\",\n        \"This year\"\n      ]\n    },\n    \"type\": {\n      \"title\": \"Result Type\",\n      \"type\": \"string\",\n      \"description\": \"Restrict results to one entity type. Legacy plural value shorts is accepted and mapped to Shorts.\",\n      \"editor\": \"select\",\n      \"default\": \"\",\n      \"prefill\": \"video\",\n      \"enumTitles\": [\n        \"All\",\n        \"Videos\",\n        \"Shorts\",\n        \"Channels\",\n        \"Playlists\",\n        \"Movies\"\n      ],\n      \"enumSuggestedValues\": [\n        \"\",\n        \"video\",\n        \"short\",\n        \"channel\",\n        \"playlist\",\n        \"movie\"\n      ]\n    },\n    \"duration\": {\n      \"title\": \"Duration\",\n      \"type\": \"string\",\n      \"description\": \"Filter videos by length. Applies to video and Shorts searches.\",\n      \"editor\": \"select\",\n      \"default\": \"\",\n      \"prefill\": \"\",\n      \"enum\": [\n        \"\",\n        \"short\",\n        \"medium\",\n        \"long\"\n      ],\n      \"enumTitles\": [\n        \"Any duration\",\n        \"Under 3 minutes\",\n        \"3 to 20 minutes\",\n        \"Over 20 minutes\"\n      ]\n    },\n    \"features\": {\n      \"title\": \"Video Features\",\n      \"type\": \"array\",\n      \"description\": \"Filter videos by features. Multiple selections are combined. Legacy aliases cc, location, and purchased are accepted for saved tasks; cc maps to subtitles and the other two are ignored with a warning.\",\n      \"editor\": \"select\",\n      \"items\": {\n        \"type\": \"string\",\n        \"enumTitles\": [\n          \"HD\",\n          \"Subtitles/CC\",\n          \"Creative Commons\",\n          \"Live\",\n          \"4K\",\n          \"HDR\",\n          \"360 degrees\",\n          \"VR180\",\n          \"3D\"\n        ],\n        \"enumSuggestedValues\": [\n          \"hd\",\n          \"subtitles\",\n          \"creative_commons\",\n          \"live\",\n          \"4k\",\n          \"hdr\",\n          \"360\",\n          \"vr180\",\n          \"3d\"\n        ]\n      },\n      \"default\": [],\n      \"prefill\": []\n    },\n    \"market\": {\n      \"title\": \"Market\",\n      \"type\": \"string\",\n      \"description\": \"Country used for YouTube's search context (gl). Results and labels follow this market.\",\n      \"editor\": \"select\",\n      \"default\": \"US\",\n      \"prefill\": \"US\",\n      \"enum\": [\n        \"US\",\n        \"GB\",\n        \"CA\",\n        \"AU\",\n        \"DE\",\n        \"FR\",\n        \"JP\",\n        \"KR\",\n        \"BR\",\n        \"IN\",\n        \"MX\",\n        \"IT\",\n        \"ES\",\n        \"NL\",\n        \"PL\",\n        \"RU\",\n        \"SE\",\n        \"NO\",\n        \"DK\",\n        \"FI\",\n        \"ZA\",\n        \"SG\",\n        \"HK\",\n        \"TW\",\n        \"ID\",\n        \"MY\",\n        \"TH\",\n        \"PH\",\n        \"AR\",\n        \"CO\",\n        \"CL\"\n      ],\n      \"enumTitles\": [\n        \"United States\",\n        \"United Kingdom\",\n        \"Canada\",\n        \"Australia\",\n        \"Germany\",\n        \"France\",\n        \"Japan\",\n        \"South Korea\",\n        \"Brazil\",\n        \"India\",\n        \"Mexico\",\n        \"Italy\",\n        \"Spain\",\n        \"Netherlands\",\n        \"Poland\",\n        \"Russia\",\n        \"Sweden\",\n        \"Norway\",\n        \"Denmark\",\n        \"Finland\",\n        \"South Africa\",\n        \"Singapore\",\n        \"Hong Kong\",\n        \"Taiwan\",\n        \"Indonesia\",\n        \"Malaysia\",\n        \"Thailand\",\n        \"Philippines\",\n        \"Argentina\",\n        \"Colombia\",\n        \"Chile\"\n      ]\n    },\n    \"language\": {\n      \"title\": \"Interface Language\",\n      \"type\": \"string\",\n      \"description\": \"Language for YouTube labels and search text (hl). Auto follows the selected market.\",\n      \"editor\": \"select\",\n      \"default\": \"auto\",\n      \"prefill\": \"auto\",\n      \"enum\": [\n        \"auto\",\n        \"ar\",\n        \"bn\",\n        \"cs\",\n        \"da\",\n        \"de\",\n        \"el\",\n        \"en\",\n        \"es\",\n        \"fa\",\n        \"fi\",\n        \"fr\",\n        \"he\",\n        \"hi\",\n        \"hu\",\n        \"id\",\n        \"it\",\n        \"ja\",\n        \"ko\",\n        \"ms\",\n        \"nl\",\n        \"no\",\n        \"pl\",\n        \"pt\",\n        \"ro\",\n        \"ru\",\n        \"sv\",\n        \"th\",\n        \"tr\",\n        \"uk\",\n        \"ur\",\n        \"vi\",\n        \"zh-Hans\",\n        \"zh-Hant\"\n      ],\n      \"enumTitles\": [\n        \"Auto (from market)\",\n        \"Arabic\",\n        \"Bengali\",\n        \"Czech\",\n        \"Danish\",\n        \"German\",\n        \"Greek\",\n        \"English\",\n        \"Spanish\",\n        \"Persian\",\n        \"Finnish\",\n        \"French\",\n        \"Hebrew\",\n        \"Hindi\",\n        \"Hungarian\",\n        \"Indonesian\",\n        \"Italian\",\n        \"Japanese\",\n        \"Korean\",\n        \"Malay\",\n        \"Dutch\",\n        \"Norwegian\",\n        \"Polish\",\n        \"Portuguese\",\n        \"Romanian\",\n        \"Russian\",\n        \"Swedish\",\n        \"Thai\",\n        \"Turkish\",\n        \"Ukrainian\",\n        \"Urdu\",\n        \"Vietnamese\",\n        \"Chinese (Simplified)\",\n        \"Chinese (Traditional)\"\n      ]\n    },\n    \"includeVideoDetails\": {\n      \"title\": \"Include Video Details\",\n      \"type\": \"boolean\",\n      \"description\": \"Fetch each video's public detail payload to add exact publish date, views, likes, category, tags, and full description. Adds one request per video and makes runs slower.\",\n      \"default\": false,\n      \"prefill\": false\n    }\n  },\n  \"required\": [\n    \"searchQueries\"\n  ]\n}",
    "readme": "# YouTube Search Results & Entity Type Scraper\n\nSearch YouTube without cookies or API keys and get structured rows for videos, Shorts, channels, playlists, and movies. Use YouTube's own filters, follow pagination, and optionally enrich every video with exact views and likes, dates when YouTube exposes them, and categories or tags when available.\n\n## What this actor does\n\n- **Five result types:** videos, Shorts, channels, playlists, and movies.\n- **All-result mode:** mix the entity types in YouTube's own order.\n- **Server-side filters:** upload date, duration, sort order, video features, market, and interface language.\n- **Pagination:** follow continuation tokens until your limit or YouTube's own ceiling.\n- **Optional details:** one detail request per video (plus fallback calls when needed) adds exact views and likes, dates when exposed, tags, and the full description.\n- **Bulk queries:** run several searches in one job.\n- **Cookieless:** public search data only. No login, no browser, no proxy setup.\n- **Omit-empty output:** a row only contains values that are actually available.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `searchQueries` | array | — | One or more YouTube search terms. Duplicate terms are removed. |\n| `maxResults` | integer | `20` | Results per query (1-1000). YouTube caps each entity type below 1000. |\n| `scrapeAllResults` | boolean | `false` | Follow pages until YouTube stops returning results, ignoring `maxResults`. |\n| `sortBy` | string | `relevance` | `relevance` or `view_count`. YouTube no longer supports date or rating sorting. |\n| `uploadDate` | string | any | `last_hour`, `today`, `this_week`, `this_month`, or `this_year`. |\n| `type` | string | all | `video`, `short`, `channel`, `playlist`, or `movie`. |\n| `duration` | string | any | `short` (under 3 min), `medium` (3-20 min), or `long` (over 20 min). |\n| `features` | array | `[]` | `hd`, `subtitles`, `creative_commons`, `live`, `4k`, `hdr`, `360`, `vr180`, `3d`. Multiple values are combined. |\n| `market` | string | `US` | Country used for YouTube's search context. 31 markets are available. |\n| `language` | string | `auto` | Interface language. `auto` follows the market. |\n| `includeVideoDetails` | boolean | `false` | Fetch each video's detail payload for exact views, likes, and duration, plus dates, category, tags, and the full description when YouTube exposes them. |\n\n### Example: video search\n\n```json\n{\n  \"searchQueries\": [\"web scraping tutorial\", \"python automation\"],\n  \"maxResults\": 50,\n  \"type\": \"video\",\n  \"sortBy\": \"view_count\",\n  \"uploadDate\": \"this_year\"\n}\n```\n\n### Example: Shorts\n\n```json\n{\n  \"searchQueries\": [\"lofi beats\"],\n  \"type\": \"short\",\n  \"maxResults\": 100\n}\n```\n\n### Example: channels\n\n```json\n{\n  \"searchQueries\": [\"python tutorials\"],\n  \"type\": \"channel\",\n  \"market\": \"GB\"\n}\n```\n\n### Example: exact video details\n\n```json\n{\n  \"searchQueries\": [\"apify\"],\n  \"type\": \"video\",\n  \"maxResults\": 20,\n  \"includeVideoDetails\": true\n}\n```\n\n## Output\n\nEvery result row has `type`, `position` (1-based within the query), `searchQuery`, and `scrapedAt`. When YouTube exposes an estimate for the query, `estimatedResults` is added to each row.\n\n### Video and movie rows\n\n| Field | Example |\n|---|---|\n| videoId | `\"dQw4w9WgXcQ\"` |\n| title | `\"Never Gonna Give You Up\"` |\n| url | `\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"` |\n| description | result-card snippet |\n| channelName | `\"Rick Astley\"` |\n| channelId | `\"UCuAXFkgsw1L7...\"` |\n| channelUrl | `\"https://www.youtube.com/@RickAstley\"` |\n| channelHandle | `\"@RickAstley\"` when the byline links to a handle |\n| channelVerified | `true` when the uploader has a verified badge |\n| viewCount | exact integer when the card or details provide one |\n| viewCountText | `\"1.6B views\"` or `\"42,963 views\"` (verbatim) |\n| publishedTimeText | `\"2 years ago\"` |\n| publishedAt | ISO 8601 UTC timestamp when a full time is exposed (`includeVideoDetails` only) |\n| likeCount | exact integer (`includeVideoDetails` only) |\n| category | `\"Science & Technology\"` when exposed (`includeVideoDetails` only) |\n| tags | array of video keywords when exposed (`includeVideoDetails` only) |\n| fullDescription | full description text (`includeVideoDetails` only) |\n| duration | `\"3:33\"` |\n| durationSeconds | `213` |\n| thumbnails | array of `{url, width, height}` |\n| richThumbnailUrl | animated preview URL when available |\n| badges | result-card badges such as `[\"CC\", \"4K\"]` |\n| isLive | `true` for a live broadcast |\n| isUpcoming | `true` for a scheduled premiere or live event |\n| scheduledStartTime | ISO 8601 start time for upcoming videos (`includeVideoDetails` only) |\n| concurrentViewers | current viewer count on a live card |\n\n### Channel rows\n\n| Field | Example |\n|---|---|\n| channelId | `\"UCxxxxxx\"` |\n| channelName | `\"Python Programmer\"` |\n| channelUrl | `\"https://www.youtube.com/@gilesmcmullen\"` |\n| handle | `\"@gilesmcmullen\"` |\n| channelHandle | same handle, for consistency with video rows |\n| description | search-card snippet |\n| subscriberCount | approximate integer from YouTube's rounded label |\n| subscriberCountText | `\"782K subscribers\"` |\n| videoCount / videoCountText | only when YouTube shows a video count on the card |\n| thumbnails | array of avatar images |\n| isVerified | true or false |\n\n### Playlist and course rows\n\n| Field | Example |\n|---|---|\n| playlistId | `\"PLxxxxxxx\"` |\n| title | `\"Python Full Course\"` |\n| url | `\"https://www.youtube.com/playlist?list=PLxxxxxxx\"` |\n| channelName | `\"CodeWithHarry\"` |\n| channelId | `\"UCxxxxxx\"` |\n| channelUrl | `\"https://www.youtube.com/@CodeWithHarry\"` |\n| channelHandle | `\"@CodeWithHarry\"` |\n| videoCount / videoCountText | `100` / `\"100 lessons\"` when available |\n| firstVideoId | first video shown on the card |\n| thumbnails | array of playlist thumbnails |\n\n### Shorts rows\n\n| Field | Example |\n|---|---|\n| videoId | `\"abc123\"` |\n| title | `\"A short example\"` |\n| url | `\"https://www.youtube.com/shorts/abc123\"` |\n| viewCount | exact integer only when YouTube shows an unabridged count |\n| viewCountText | `\"1.2M views\"` (verbatim) |\n| thumbnails | vertical thumbnails |\n| badge | card badge when present |\n| isShort | `true` |\n\nWith `includeVideoDetails`, Shorts also gain `channelName`, `channelId`, `channelUrl`, `channelHandle`, `publishedAt`, `likeCount`, `durationSeconds`, `category`, and `tags`.\n\n### Status rows\n\nA typed query with no results produces one status row: `recordType: \"status\"`, `status: \"no_results\"`, `query`, `market`, `resultType`, `appliedFilters`, and `resultCount: 0`. A failed query produces `status: \"query_failed\"` with an `error` string.\n\n## How row limits work\n\nYouTube serves a variable number of results for the same query. There is no fixed ceiling: the same `news` query returned 343-373 videos, 14-24 Shorts, 601-685 mixed rows, 134-367 channels, 357-461 playlists, and 204 movies on different runs and IPs. Set `scrapeAllResults` to follow pages until YouTube stops offering results, or use `maxResults` for a smaller slice. When the requested count is not reached, the status message reports the requested and actual counts and whether the query pool was exhausted, stopped after repeated empty pages, or lost its continuation. It does not claim a fixed ceiling.\n\n## Limitations\n\n- **Date and rating sorts are not available.** YouTube removed them; the UI suggests only relevance and view count. Saved tasks that still send `sortBy: \"upload_date\"` or `\"rating\"` are accepted and mapped to relevance with a warning.\n- **Subscriber counts are rounded.** YouTube only publishes display labels for search results, so `subscriberCount` is an approximation and `subscriberCountText` is the verbatim label. Localized labels are parsed, including Japanese `チャンネル登録者数 184万人` and Korean `구독자 8.65만명`.\n- **Some exact fields need a full player response.** On datacenter IPs YouTube can return a reduced response. Exact views, likes, and duration normally resolve, but `publishedAt` can be date-only or absent and `category`/`tags` can be omitted. The actor never fills these with zero or a placeholder.\n- **Live view counts are a live counter.** For an active stream, the detail `viewCount` follows the current live counter and is not comparable to lifetime views. Use `concurrentViewers` on the card for the live audience.\n- **Shorts can stop early.** Repeated empty continuation pages can end a Shorts run before the requested count. The run succeeds and the status message reports the requested and actual counts.\n- **No comment counts.** Comments are handled by the dedicated YouTube comments actor.\n- **Shorts cards are sparse.** Without `includeVideoDetails`, YouTube does not expose channel, date, duration, or exact views on a Shorts card.\n- **Movies are YouTube's \"Movies\" filter.** It returns movie-catalog videos; some are full films, some are clips or episodes.\n- **Results vary between runs.** YouTube personalizes and re-ranks search results over time.\n- **Detail fields can be withheld.** On some datacenter IPs YouTube returns a limited player response. The actor tries a second player client and the watch-next payload; fields that remain unavailable (`viewCount`, `category`, `tags`, `publishedAt`) are omitted, never filled with zero or a placeholder.\n- **Location and Purchased filters are not offered.** They return no cookieless results. Saved tasks that send `features: [\"location\"]`, `[\"purchased\"]`, or `[\"cc\"]` are accepted: `cc` maps to subtitles, the other two are ignored with a warning.\n\n## FAQ\n\n**Do I need cookies or a YouTube API key?**\n\nNo. The actor reads public search results with no credentials.\n\n**Which result types can I request?**\n\nVideos, Shorts, channels, playlists, and movies. Leave `type` empty for mixed results. Saved tasks that send the plural `shorts` are mapped to the Shorts type.\n\n**Why did I get fewer rows than `maxResults`?**\n\nYouTube serves a variable number of rows and there is no fixed ceiling. The status message reports the requested and actual counts and whether the query pool was exhausted or stopped after repeated empty pages. Some Shorts searches can stop early; the same shortfall message applies.\n\n**What does `includeVideoDetails` add?**\n\nExact views, likes, and duration, plus publish date, category, tags, full description, and upcoming/live state when YouTube exposes them. It costs one or more requests per video and makes the run slower.\n\n**Why is `viewCount` missing on some rows?**\n\nYouTube shows rounded labels such as `1.6B views` on many cards. The actor keeps `viewCountText` but does not turn a rounded label into a fake exact number. Enable `includeVideoDetails` for exact views.\n\n**Why is a channel's subscriber count approximate?**\n\nSearch cards only show rounded labels such as `782K subscribers`.\n\n**Are Shorts supported without details?**\n\nYes. Title, URL, views text, and thumbnails are available. Channel, date, duration, and exact views require `includeVideoDetails`.\n\n**Can I run several searches at once?**\n\nYes. Add them to `searchQueries`; each query gets its own `position` sequence and `searchQuery` value.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "youtube-search-results-and-entity-type-scraper",
      "title": "YouTube Search Results & Entity Type Scraper",
      "description": "Search YouTube for videos, Shorts, channels, playlists, or movies. Get views, duration, channel data, plus optional exact views and likes, dates, categories, and tags when available. Filter by date, duration, features, market, and language.",
      "version": "1.1",
      "meta": {
        "templateId": "python-start"
      },
      "input": {
        "title": "YouTube Search Scraper Input",
        "description": "Search YouTube by keyword for videos, Shorts, channels, playlists, or movies. Filter by upload date, duration, sort order, features, market, and language. Optional video details add exact publish dates, views, likes, categories, and tags.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "searchQueries": {
            "title": "Search Queries",
            "type": "array",
            "description": "One or more YouTube search terms. Each query is scraped separately and its results are combined in the dataset.",
            "editor": "stringList",
            "items": {
              "type": "string",
              "minLength": 1
            },
            "minItems": 1,
            "prefill": [
              "apify"
            ]
          },
          "maxResults": {
            "title": "Max Results Per Query",
            "type": "integer",
            "description": "Maximum number of results per query. YouTube may serve fewer rows for a given query, entity type, session, or IP; the run reports the requested and actual counts and whether the result pool was exhausted.",
            "default": 20,
            "minimum": 1,
            "maximum": 1000,
            "prefill": 3
          },
          "scrapeAllResults": {
            "title": "Scrape All Available Results",
            "type": "boolean",
            "description": "Keep loading pages until YouTube stops offering results. This ignores Max Results Per Query and can take longer on broad searches.",
            "default": false,
            "prefill": false
          },
          "sortBy": {
            "title": "Sort By",
            "type": "string",
            "description": "Order of the search results. YouTube currently supports relevance and popularity (view count). Legacy values upload_date and rating are accepted for saved tasks and mapped to relevance with a warning.",
            "editor": "select",
            "default": "relevance",
            "prefill": "relevance",
            "enumTitles": [
              "Relevance",
              "View count (popularity)"
            ],
            "enumSuggestedValues": [
              "relevance",
              "view_count"
            ]
          },
          "uploadDate": {
            "title": "Upload Date",
            "type": "string",
            "description": "Only return results uploaded in the selected period. Applies to videos and Shorts.",
            "editor": "select",
            "default": "",
            "prefill": "",
            "enum": [
              "",
              "last_hour",
              "today",
              "this_week",
              "this_month",
              "this_year"
            ],
            "enumTitles": [
              "Any time",
              "Last hour",
              "Today",
              "This week",
              "This month",
              "This year"
            ]
          },
          "type": {
            "title": "Result Type",
            "type": "string",
            "description": "Restrict results to one entity type. Legacy plural value shorts is accepted and mapped to Shorts.",
            "editor": "select",
            "default": "",
            "prefill": "video",
            "enumTitles": [
              "All",
              "Videos",
              "Shorts",
              "Channels",
              "Playlists",
              "Movies"
            ],
            "enumSuggestedValues": [
              "",
              "video",
              "short",
              "channel",
              "playlist",
              "movie"
            ]
          },
          "duration": {
            "title": "Duration",
            "type": "string",
            "description": "Filter videos by length. Applies to video and Shorts searches.",
            "editor": "select",
            "default": "",
            "prefill": "",
            "enum": [
              "",
              "short",
              "medium",
              "long"
            ],
            "enumTitles": [
              "Any duration",
              "Under 3 minutes",
              "3 to 20 minutes",
              "Over 20 minutes"
            ]
          },
          "features": {
            "title": "Video Features",
            "type": "array",
            "description": "Filter videos by features. Multiple selections are combined. Legacy aliases cc, location, and purchased are accepted for saved tasks; cc maps to subtitles and the other two are ignored with a warning.",
            "editor": "select",
            "items": {
              "type": "string",
              "enumTitles": [
                "HD",
                "Subtitles/CC",
                "Creative Commons",
                "Live",
                "4K",
                "HDR",
                "360 degrees",
                "VR180",
                "3D"
              ],
              "enumSuggestedValues": [
                "hd",
                "subtitles",
                "creative_commons",
                "live",
                "4k",
                "hdr",
                "360",
                "vr180",
                "3d"
              ]
            },
            "default": [],
            "prefill": []
          },
          "market": {
            "title": "Market",
            "type": "string",
            "description": "Country used for YouTube's search context (gl). Results and labels follow this market.",
            "editor": "select",
            "default": "US",
            "prefill": "US",
            "enum": [
              "US",
              "GB",
              "CA",
              "AU",
              "DE",
              "FR",
              "JP",
              "KR",
              "BR",
              "IN",
              "MX",
              "IT",
              "ES",
              "NL",
              "PL",
              "RU",
              "SE",
              "NO",
              "DK",
              "FI",
              "ZA",
              "SG",
              "HK",
              "TW",
              "ID",
              "MY",
              "TH",
              "PH",
              "AR",
              "CO",
              "CL"
            ],
            "enumTitles": [
              "United States",
              "United Kingdom",
              "Canada",
              "Australia",
              "Germany",
              "France",
              "Japan",
              "South Korea",
              "Brazil",
              "India",
              "Mexico",
              "Italy",
              "Spain",
              "Netherlands",
              "Poland",
              "Russia",
              "Sweden",
              "Norway",
              "Denmark",
              "Finland",
              "South Africa",
              "Singapore",
              "Hong Kong",
              "Taiwan",
              "Indonesia",
              "Malaysia",
              "Thailand",
              "Philippines",
              "Argentina",
              "Colombia",
              "Chile"
            ]
          },
          "language": {
            "title": "Interface Language",
            "type": "string",
            "description": "Language for YouTube labels and search text (hl). Auto follows the selected market.",
            "editor": "select",
            "default": "auto",
            "prefill": "auto",
            "enum": [
              "auto",
              "ar",
              "bn",
              "cs",
              "da",
              "de",
              "el",
              "en",
              "es",
              "fa",
              "fi",
              "fr",
              "he",
              "hi",
              "hu",
              "id",
              "it",
              "ja",
              "ko",
              "ms",
              "nl",
              "no",
              "pl",
              "pt",
              "ro",
              "ru",
              "sv",
              "th",
              "tr",
              "uk",
              "ur",
              "vi",
              "zh-Hans",
              "zh-Hant"
            ],
            "enumTitles": [
              "Auto (from market)",
              "Arabic",
              "Bengali",
              "Czech",
              "Danish",
              "German",
              "Greek",
              "English",
              "Spanish",
              "Persian",
              "Finnish",
              "French",
              "Hebrew",
              "Hindi",
              "Hungarian",
              "Indonesian",
              "Italian",
              "Japanese",
              "Korean",
              "Malay",
              "Dutch",
              "Norwegian",
              "Polish",
              "Portuguese",
              "Romanian",
              "Russian",
              "Swedish",
              "Thai",
              "Turkish",
              "Ukrainian",
              "Urdu",
              "Vietnamese",
              "Chinese (Simplified)",
              "Chinese (Traditional)"
            ]
          },
          "includeVideoDetails": {
            "title": "Include Video Details",
            "type": "boolean",
            "description": "Fetch each video's public detail payload to add exact publish date, views, likes, category, tags, and full description. Adds one request per video and makes runs slower.",
            "default": false,
            "prefill": false
          }
        },
        "required": [
          "searchQueries"
        ]
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "YouTube Search Results & Entity Type Scraper Output",
        "description": "Search result rows for videos, Shorts, channels, playlists, and movies, with optional exact dates, views, likes, categories, tags, and live or upcoming state.",
        "properties": {
          "results": {
            "type": "string",
            "title": "YouTube Search Scraper dataset",
            "description": "Dataset containing all scraped YouTube search result rows.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "YouTube Search Results",
          "views": {
            "overview": {
              "title": "Results Overview",
              "transformation": {
                "fields": [
                  "position",
                  "type",
                  "videoId",
                  "title",
                  "channelName",
                  "viewCount",
                  "publishedAt",
                  "publishedTimeText",
                  "duration",
                  "url",
                  "searchQuery"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "position": {
                    "label": "Position",
                    "format": "number"
                  },
                  "type": {
                    "label": "Type",
                    "format": "text"
                  },
                  "videoId": {
                    "label": "Video ID",
                    "format": "text"
                  },
                  "title": {
                    "label": "Title",
                    "format": "text"
                  },
                  "channelName": {
                    "label": "Channel",
                    "format": "text"
                  },
                  "viewCount": {
                    "label": "Views",
                    "format": "number"
                  },
                  "publishedAt": {
                    "label": "Published At",
                    "format": "text"
                  },
                  "publishedTimeText": {
                    "label": "Published",
                    "format": "text"
                  },
                  "duration": {
                    "label": "Duration",
                    "format": "text"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  },
                  "searchQuery": {
                    "label": "Search Query",
                    "format": "text"
                  }
                }
              }
            },
            "detailed": {
              "title": "Detailed View",
              "transformation": {
                "fields": [
                  "position",
                  "type",
                  "videoId",
                  "title",
                  "description",
                  "fullDescription",
                  "channelName",
                  "channelId",
                  "channelUrl",
                  "channelHandle",
                  "channelVerified",
                  "viewCount",
                  "viewCountText",
                  "likeCount",
                  "category",
                  "tags",
                  "duration",
                  "durationText",
                  "durationSeconds",
                  "publishedAt",
                  "publishedTimeText",
                  "isLive",
                  "isUpcoming",
                  "scheduledStartTime",
                  "concurrentViewers",
                  "badges",
                  "richThumbnailUrl",
                  "isVerified",
                  "subscriberCount",
                  "subscriberCountText",
                  "videoCount",
                  "videoCountText",
                  "playlistId",
                  "firstVideoId",
                  "ownerName",
                  "handle",
                  "badge",
                  "isShort",
                  "url",
                  "estimatedResults",
                  "searchQuery",
                  "scrapedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "position": {
                    "label": "Position",
                    "format": "number"
                  },
                  "type": {
                    "label": "Type",
                    "format": "text"
                  },
                  "videoId": {
                    "label": "Video ID",
                    "format": "text"
                  },
                  "title": {
                    "label": "Title",
                    "format": "text"
                  },
                  "description": {
                    "label": "Description",
                    "format": "text"
                  },
                  "fullDescription": {
                    "label": "Full Description",
                    "format": "text"
                  },
                  "channelName": {
                    "label": "Channel",
                    "format": "text"
                  },
                  "channelId": {
                    "label": "Channel ID",
                    "format": "text"
                  },
                  "channelUrl": {
                    "label": "Channel URL",
                    "format": "link"
                  },
                  "channelHandle": {
                    "label": "Channel Handle",
                    "format": "text"
                  },
                  "channelVerified": {
                    "label": "Channel Verified",
                    "format": "boolean"
                  },
                  "viewCount": {
                    "label": "Views",
                    "format": "number"
                  },
                  "viewCountText": {
                    "label": "Views Text",
                    "format": "text"
                  },
                  "likeCount": {
                    "label": "Likes",
                    "format": "number"
                  },
                  "category": {
                    "label": "Category",
                    "format": "text"
                  },
                  "tags": {
                    "label": "Tags",
                    "format": "text"
                  },
                  "duration": {
                    "label": "Duration",
                    "format": "text"
                  },
                  "durationText": {
                    "label": "Duration Text",
                    "format": "text"
                  },
                  "durationSeconds": {
                    "label": "Duration (s)",
                    "format": "number"
                  },
                  "publishedAt": {
                    "label": "Published At",
                    "format": "text"
                  },
                  "publishedTimeText": {
                    "label": "Published",
                    "format": "text"
                  },
                  "isLive": {
                    "label": "Live",
                    "format": "boolean"
                  },
                  "isUpcoming": {
                    "label": "Upcoming",
                    "format": "boolean"
                  },
                  "scheduledStartTime": {
                    "label": "Scheduled Start",
                    "format": "text"
                  },
                  "concurrentViewers": {
                    "label": "Concurrent Viewers",
                    "format": "number"
                  },
                  "badges": {
                    "label": "Badges",
                    "format": "text"
                  },
                  "richThumbnailUrl": {
                    "label": "Rich Thumbnail",
                    "format": "link"
                  },
                  "isVerified": {
                    "label": "Verified",
                    "format": "boolean"
                  },
                  "subscriberCount": {
                    "label": "Subscribers",
                    "format": "number"
                  },
                  "subscriberCountText": {
                    "label": "Subscribers Text",
                    "format": "text"
                  },
                  "videoCount": {
                    "label": "Video Count",
                    "format": "number"
                  },
                  "videoCountText": {
                    "label": "Video Count Text",
                    "format": "text"
                  },
                  "playlistId": {
                    "label": "Playlist ID",
                    "format": "text"
                  },
                  "firstVideoId": {
                    "label": "First Video ID",
                    "format": "text"
                  },
                  "ownerName": {
                    "label": "Owner",
                    "format": "text"
                  },
                  "handle": {
                    "label": "Handle",
                    "format": "text"
                  },
                  "badge": {
                    "label": "Badge",
                    "format": "text"
                  },
                  "isShort": {
                    "label": "Short",
                    "format": "boolean"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  },
                  "estimatedResults": {
                    "label": "Estimated Results",
                    "format": "number"
                  },
                  "searchQuery": {
                    "label": "Search Query",
                    "format": "text"
                  },
                  "scrapedAt": {
                    "label": "Scraped At",
                    "format": "text"
                  }
                }
              }
            }
          }
        }
      },
      "readme": "# YouTube Search Results & Entity Type Scraper\n\nSearch YouTube without cookies or API keys and get structured rows for videos, Shorts, channels, playlists, and movies. Use YouTube's own filters, follow pagination, and optionally enrich every video with exact views and likes, dates when YouTube exposes them, and categories or tags when available.\n\n## What this actor does\n\n- **Five result types:** videos, Shorts, channels, playlists, and movies.\n- **All-result mode:** mix the entity types in YouTube's own order.\n- **Server-side filters:** upload date, duration, sort order, video features, market, and interface language.\n- **Pagination:** follow continuation tokens until your limit or YouTube's own ceiling.\n- **Optional details:** one detail request per video (plus fallback calls when needed) adds exact views and likes, dates when exposed, tags, and the full description.\n- **Bulk queries:** run several searches in one job.\n- **Cookieless:** public search data only. No login, no browser, no proxy setup.\n- **Omit-empty output:** a row only contains values that are actually available.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `searchQueries` | array | — | One or more YouTube search terms. Duplicate terms are removed. |\n| `maxResults` | integer | `20` | Results per query (1-1000). YouTube caps each entity type below 1000. |\n| `scrapeAllResults` | boolean | `false` | Follow pages until YouTube stops returning results, ignoring `maxResults`. |\n| `sortBy` | string | `relevance` | `relevance` or `view_count`. YouTube no longer supports date or rating sorting. |\n| `uploadDate` | string | any | `last_hour`, `today`, `this_week`, `this_month`, or `this_year`. |\n| `type` | string | all | `video`, `short`, `channel`, `playlist`, or `movie`. |\n| `duration` | string | any | `short` (under 3 min), `medium` (3-20 min), or `long` (over 20 min). |\n| `features` | array | `[]` | `hd`, `subtitles`, `creative_commons`, `live`, `4k`, `hdr`, `360`, `vr180`, `3d`. Multiple values are combined. |\n| `market` | string | `US` | Country used for YouTube's search context. 31 markets are available. |\n| `language` | string | `auto` | Interface language. `auto` follows the market. |\n| `includeVideoDetails` | boolean | `false` | Fetch each video's detail payload for exact views, likes, and duration, plus dates, category, tags, and the full description when YouTube exposes them. |\n\n### Example: video search\n\n```json\n{\n  \"searchQueries\": [\"web scraping tutorial\", \"python automation\"],\n  \"maxResults\": 50,\n  \"type\": \"video\",\n  \"sortBy\": \"view_count\",\n  \"uploadDate\": \"this_year\"\n}\n```\n\n### Example: Shorts\n\n```json\n{\n  \"searchQueries\": [\"lofi beats\"],\n  \"type\": \"short\",\n  \"maxResults\": 100\n}\n```\n\n### Example: channels\n\n```json\n{\n  \"searchQueries\": [\"python tutorials\"],\n  \"type\": \"channel\",\n  \"market\": \"GB\"\n}\n```\n\n### Example: exact video details\n\n```json\n{\n  \"searchQueries\": [\"apify\"],\n  \"type\": \"video\",\n  \"maxResults\": 20,\n  \"includeVideoDetails\": true\n}\n```\n\n## Output\n\nEvery result row has `type`, `position` (1-based within the query), `searchQuery`, and `scrapedAt`. When YouTube exposes an estimate for the query, `estimatedResults` is added to each row.\n\n### Video and movie rows\n\n| Field | Example |\n|---|---|\n| videoId | `\"dQw4w9WgXcQ\"` |\n| title | `\"Never Gonna Give You Up\"` |\n| url | `\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"` |\n| description | result-card snippet |\n| channelName | `\"Rick Astley\"` |\n| channelId | `\"UCuAXFkgsw1L7...\"` |\n| channelUrl | `\"https://www.youtube.com/@RickAstley\"` |\n| channelHandle | `\"@RickAstley\"` when the byline links to a handle |\n| channelVerified | `true` when the uploader has a verified badge |\n| viewCount | exact integer when the card or details provide one |\n| viewCountText | `\"1.6B views\"` or `\"42,963 views\"` (verbatim) |\n| publishedTimeText | `\"2 years ago\"` |\n| publishedAt | ISO 8601 UTC timestamp when a full time is exposed (`includeVideoDetails` only) |\n| likeCount | exact integer (`includeVideoDetails` only) |\n| category | `\"Science & Technology\"` when exposed (`includeVideoDetails` only) |\n| tags | array of video keywords when exposed (`includeVideoDetails` only) |\n| fullDescription | full description text (`includeVideoDetails` only) |\n| duration | `\"3:33\"` |\n| durationSeconds | `213` |\n| thumbnails | array of `{url, width, height}` |\n| richThumbnailUrl | animated preview URL when available |\n| badges | result-card badges such as `[\"CC\", \"4K\"]` |\n| isLive | `true` for a live broadcast |\n| isUpcoming | `true` for a scheduled premiere or live event |\n| scheduledStartTime | ISO 8601 start time for upcoming videos (`includeVideoDetails` only) |\n| concurrentViewers | current viewer count on a live card |\n\n### Channel rows\n\n| Field | Example |\n|---|---|\n| channelId | `\"UCxxxxxx\"` |\n| channelName | `\"Python Programmer\"` |\n| channelUrl | `\"https://www.youtube.com/@gilesmcmullen\"` |\n| handle | `\"@gilesmcmullen\"` |\n| channelHandle | same handle, for consistency with video rows |\n| description | search-card snippet |\n| subscriberCount | approximate integer from YouTube's rounded label |\n| subscriberCountText | `\"782K subscribers\"` |\n| videoCount / videoCountText | only when YouTube shows a video count on the card |\n| thumbnails | array of avatar images |\n| isVerified | true or false |\n\n### Playlist and course rows\n\n| Field | Example |\n|---|---|\n| playlistId | `\"PLxxxxxxx\"` |\n| title | `\"Python Full Course\"` |\n| url | `\"https://www.youtube.com/playlist?list=PLxxxxxxx\"` |\n| channelName | `\"CodeWithHarry\"` |\n| channelId | `\"UCxxxxxx\"` |\n| channelUrl | `\"https://www.youtube.com/@CodeWithHarry\"` |\n| channelHandle | `\"@CodeWithHarry\"` |\n| videoCount / videoCountText | `100` / `\"100 lessons\"` when available |\n| firstVideoId | first video shown on the card |\n| thumbnails | array of playlist thumbnails |\n\n### Shorts rows\n\n| Field | Example |\n|---|---|\n| videoId | `\"abc123\"` |\n| title | `\"A short example\"` |\n| url | `\"https://www.youtube.com/shorts/abc123\"` |\n| viewCount | exact integer only when YouTube shows an unabridged count |\n| viewCountText | `\"1.2M views\"` (verbatim) |\n| thumbnails | vertical thumbnails |\n| badge | card badge when present |\n| isShort | `true` |\n\nWith `includeVideoDetails`, Shorts also gain `channelName`, `channelId`, `channelUrl`, `channelHandle`, `publishedAt`, `likeCount`, `durationSeconds`, `category`, and `tags`.\n\n### Status rows\n\nA typed query with no results produces one status row: `recordType: \"status\"`, `status: \"no_results\"`, `query`, `market`, `resultType`, `appliedFilters`, and `resultCount: 0`. A failed query produces `status: \"query_failed\"` with an `error` string.\n\n## How row limits work\n\nYouTube serves a variable number of results for the same query. There is no fixed ceiling: the same `news` query returned 343-373 videos, 14-24 Shorts, 601-685 mixed rows, 134-367 channels, 357-461 playlists, and 204 movies on different runs and IPs. Set `scrapeAllResults` to follow pages until YouTube stops offering results, or use `maxResults` for a smaller slice. When the requested count is not reached, the status message reports the requested and actual counts and whether the query pool was exhausted, stopped after repeated empty pages, or lost its continuation. It does not claim a fixed ceiling.\n\n## Limitations\n\n- **Date and rating sorts are not available.** YouTube removed them; the UI suggests only relevance and view count. Saved tasks that still send `sortBy: \"upload_date\"` or `\"rating\"` are accepted and mapped to relevance with a warning.\n- **Subscriber counts are rounded.** YouTube only publishes display labels for search results, so `subscriberCount` is an approximation and `subscriberCountText` is the verbatim label. Localized labels are parsed, including Japanese `チャンネル登録者数 184万人` and Korean `구독자 8.65만명`.\n- **Some exact fields need a full player response.** On datacenter IPs YouTube can return a reduced response. Exact views, likes, and duration normally resolve, but `publishedAt` can be date-only or absent and `category`/`tags` can be omitted. The actor never fills these with zero or a placeholder.\n- **Live view counts are a live counter.** For an active stream, the detail `viewCount` follows the current live counter and is not comparable to lifetime views. Use `concurrentViewers` on the card for the live audience.\n- **Shorts can stop early.** Repeated empty continuation pages can end a Shorts run before the requested count. The run succeeds and the status message reports the requested and actual counts.\n- **No comment counts.** Comments are handled by the dedicated YouTube comments actor.\n- **Shorts cards are sparse.** Without `includeVideoDetails`, YouTube does not expose channel, date, duration, or exact views on a Shorts card.\n- **Movies are YouTube's \"Movies\" filter.** It returns movie-catalog videos; some are full films, some are clips or episodes.\n- **Results vary between runs.** YouTube personalizes and re-ranks search results over time.\n- **Detail fields can be withheld.** On some datacenter IPs YouTube returns a limited player response. The actor tries a second player client and the watch-next payload; fields that remain unavailable (`viewCount`, `category`, `tags`, `publishedAt`) are omitted, never filled with zero or a placeholder.\n- **Location and Purchased filters are not offered.** They return no cookieless results. Saved tasks that send `features: [\"location\"]`, `[\"purchased\"]`, or `[\"cc\"]` are accepted: `cc` maps to subtitles, the other two are ignored with a warning.\n\n## FAQ\n\n**Do I need cookies or a YouTube API key?**\n\nNo. The actor reads public search results with no credentials.\n\n**Which result types can I request?**\n\nVideos, Shorts, channels, playlists, and movies. Leave `type` empty for mixed results. Saved tasks that send the plural `shorts` are mapped to the Shorts type.\n\n**Why did I get fewer rows than `maxResults`?**\n\nYouTube serves a variable number of rows and there is no fixed ceiling. The status message reports the requested and actual counts and whether the query pool was exhausted or stopped after repeated empty pages. Some Shorts searches can stop early; the same shortfall message applies.\n\n**What does `includeVideoDetails` add?**\n\nExact views, likes, and duration, plus publish date, category, tags, full description, and upcoming/live state when YouTube exposes them. It costs one or more requests per video and makes the run slower.\n\n**Why is `viewCount` missing on some rows?**\n\nYouTube shows rounded labels such as `1.6B views` on many cards. The actor keeps `viewCountText` but does not turn a rounded label into a fake exact number. Enable `includeVideoDetails` for exact views.\n\n**Why is a channel's subscriber count approximate?**\n\nSearch cards only show rounded labels such as `782K subscribers`.\n\n**Are Shorts supported without details?**\n\nYes. Title, URL, views text, and thumbnails are available. Channel, date, duration, and exact views require `includeVideoDetails`.\n\n**Can I run several searches at once?**\n\nYes. Add them to `searchQueries`; each query gets its own `position` sequence and `searchQuery` value.\n"
    },
    "buildNumber": "1.1.2",
    "imageDigest": "a665272628d02976af6081d096ad248611d062a22d75a431c04458a583832f00",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.1"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.012982222222222221
    }
  }
}