{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Title & Thumbnail Change Tracker - Metadata Edit Feed",
    "description": "Watches YouTube videos, channels or playlists and emits only what changed since the last run: title or description edited, thumbnail replaced, tags or category changed, or the video gone private, unlisted or deleted, with before/after values and view count at the edit.",
    "version": "1.0",
    "x-build-id": "Ef8qFeSCXYnZEsFQ7"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/mibedk~youtube-metadata-change-tracker/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-mibedk-youtube-metadata-change-tracker",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/mibedk~youtube-metadata-change-tracker/runs": {
      "post": {
        "operationId": "runs-sync-mibedk-youtube-metadata-change-tracker",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/mibedk~youtube-metadata-change-tracker/run-sync": {
      "post": {
        "operationId": "run-sync-mibedk-youtube-metadata-change-tracker",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "apiKey"
        ],
        "properties": {
          "apiKey": {
            "title": "YouTube Data API v3 key",
            "type": "string",
            "description": "A free Google Cloud API key with the 'YouTube Data API v3' enabled. No OAuth or login needed. Get one in ~2 minutes: console.cloud.google.com/apis/credentials -> Create Credentials -> API key, then enable 'YouTube Data API v3' for that project in the API Library. Checking 500 videos costs about 12 units of the free 10,000-unit daily quota, so quota is not a practical limit here."
          },
          "channelUrls": {
            "title": "Channels to watch",
            "type": "array",
            "description": "Channel URLs, @handles, or raw UC... channel IDs. The actor tracks each channel's most recent uploads (see 'Max videos per source'). Example: https://www.youtube.com/@MrBeast",
            "default": [
              "https://www.youtube.com/@MrBeast"
            ],
            "items": {
              "type": "string"
            }
          },
          "videoUrls": {
            "title": "Individual videos to watch",
            "type": "array",
            "description": "Specific YouTube videos to watch, as full URLs (watch, shorts, embed or youtu.be) or bare 11-character video IDs. Use this when you care about a handful of videos rather than a whole channel.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "playlistUrls": {
            "title": "Playlists to watch",
            "type": "array",
            "description": "Playlist URLs or raw PL.../UU... playlist IDs. The actor tracks the first N videos in each playlist (see 'Max videos per source').",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxVideosPerSource": {
            "title": "Max videos per source",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "How many videos to take from each channel or playlist, newest first. Individual videos listed above are always included and do not count against this.",
            "default": 10
          },
          "maxVideosPerRun": {
            "title": "Max videos per run",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "Hard cap on how many videos are checked (and charged as 'video-checked') in a single run, across all sources. Protects you from an accidental 5,000-video watchlist.",
            "default": 50
          },
          "trackedFields": {
            "title": "Fields to treat as a change",
            "type": "array",
            "description": "Which metadata fields produce a change event. Unticking 'thumbnail' makes runs noticeably faster and cheaper, because it is the only field that needs a request to the image CDN rather than the API.",
            "items": {
              "type": "string",
              "enum": [
                "title",
                "description",
                "thumbnail",
                "tags",
                "category",
                "status"
              ],
              "enumTitles": [
                "Title edited",
                "Description edited",
                "Thumbnail replaced",
                "Tags added or removed",
                "Category changed",
                "Privacy status changed / video gone"
              ]
            },
            "default": [
              "title",
              "description",
              "thumbnail",
              "tags",
              "category",
              "status"
            ]
          },
          "thumbnailCheckMode": {
            "title": "Thumbnail check mode",
            "enum": [
              "headers",
              "bytes"
            ],
            "type": "string",
            "description": "'headers' sends a HEAD request to i.ytimg.com and compares the ETag and byte length - fast, near-zero bandwidth, and accurate in practice. 'bytes' downloads the JPEG and compares a SHA-256 of the actual pixels - slower and ~20 KB per video, but immune to a CDN that changes an ETag without changing the image. Ignored if 'thumbnail' is not in the tracked fields.",
            "default": "headers"
          },
          "maxChangeEvents": {
            "title": "Max change events per run",
            "minimum": 1,
            "type": "integer",
            "description": "Hard cap on the number of change events returned and charged for in one run. A normal run on a stable watchlist returns single digits; this only matters on the run after you widen the watchlist.",
            "default": 500
          },
          "markGoneAfterMisses": {
            "title": "Consecutive misses before reporting a video as gone",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "The YouTube API silently omits videos that are deleted or made private, and it also omits them during transient hiccups. The actor waits for this many consecutive runs with the video missing before emitting a 'gone' event, so a blip does not create a false alarm. Set to 1 to report immediately.",
            "default": 2
          },
          "includeBaselineRecords": {
            "title": "Emit a baseline record the first time a video is seen",
            "type": "boolean",
            "description": "The first run has nothing to compare against, so it cannot report changes. With this on, that run returns one 'baseline' record per video showing the metadata as it stands now, so you can see the watchlist was picked up correctly. Baseline records are not charged as change events. Turn it off if you only ever want edits.",
            "default": true
          },
          "forceBaseline": {
            "title": "Reset stored state and re-baseline",
            "type": "boolean",
            "description": "Discards the remembered state for every video in this run and treats them all as seen for the first time. Use after changing 'Thumbnail check mode', or to clear out state you no longer trust. Leave off for normal scheduled runs, otherwise the actor can never detect a change.",
            "default": false
          },
          "stateKeyValueStoreName": {
            "title": "State storage name",
            "type": "string",
            "description": "Name of the named key-value store holding the last-seen metadata for each video. Runs sharing this name share a memory of the watchlist. Change it to run two independent watchlists side by side under one account.",
            "default": "youtube-metadata-tracker-state"
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (seconds)",
            "minimum": 5,
            "maximum": 120,
            "type": "integer",
            "description": "Per-request timeout for YouTube API and thumbnail CDN calls.",
            "default": 30
          },
          "maxRequestRetries": {
            "title": "Max request retries",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "How many times to retry a failing YouTube API or thumbnail request before giving up on it.",
            "default": 3
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. The actor talks to Google's official API and image CDN, which do not IP-block, so the default of no proxy is both cheaper and faster. Only turn this on if your own network is rate-limiting you.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}