> ## Documentation Index
> Fetch the complete documentation index at: https://monitoryt.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API quickstart

> Generate an API key and fetch your first feed page.

The public API is read-only. It returns the feed and video history belonging to the
authenticated Monitor YT account.

## Before you begin

You need:

* A Monitor YT account with a Pro plan
* At least one tracked channel
* A personal API key from [Settings](https://monitoryt.com/app/settings)

Free accounts can create keys, but authenticated requests return
`403 upgrade_required` until the account upgrades.

<Steps>
  <Step title="Store your API key">
    Keep the key outside your source code:

    ```bash theme={null}
    export MONITOR_YT_API_KEY="myt_your_api_key"
    ```
  </Step>

  <Step title="Fetch feed events">
    <Tabs>
      <Tab title="curl">
        ```bash theme={null}
        curl -H "Authorization: Bearer $MONITOR_YT_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{"limit":20}' \
          "https://monitoryt.com/api/public/feed"
        ```
      </Tab>

      <Tab title="JavaScript">
        ```javascript theme={null}
        const response = await fetch("https://monitoryt.com/api/public/feed", {
          method: "POST",
          headers: {
            Authorization: `Bearer ${process.env.MONITOR_YT_API_KEY}`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ limit: 20 }),
        });

        if (!response.ok) throw new Error(await response.text());
        const page = await response.json();
        console.log(page.events);
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        import json
        import os
        from urllib.request import Request, urlopen

        request = Request(
            "https://monitoryt.com/api/public/feed",
            data=json.dumps({"limit": 20}).encode(),
            headers={
                "Authorization": f"Bearer {os.environ['MONITOR_YT_API_KEY']}",
                "Content-Type": "application/json",
            },
            method="POST",
        )

        with urlopen(request) as response:
            page = json.load(response)

        print(page["events"])
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Read the response">
    A page contains an `events` array and a nullable `nextCursor`:

    ```json theme={null}
    {
      "events": [
        {
          "id": "665f21c09b1d8a4f30aa1234",
          "type": "video_published",
          "createdAt": 1783897200000,
          "channel": {
            "id": "665f21c09b1d8a4f30aa5678",
            "youtubeChannelId": "UCBJycsmduvYEL83R_U4JriQ",
            "title": "Example Channel",
            "thumbnailUrl": "https://yt3.ggpht.com/example"
          },
          "video": {
            "youtubeVideoId": "aqz-KE-bpKQ",
            "currentTitle": "Our biggest video yet",
            "currentThumbnailUrl": "https://i.ytimg.com/vi/aqz-KE-bpKQ/hqdefault.jpg",
            "publishedAt": 1783893600000,
            "isMembersOnly": false,
            "viewCount": 12345,
            "likeCount": 678,
            "commentCount": 90
          }
        }
      ],
      "nextCursor": "665f21c09b1d8a4f30aa1234"
    }
    ```

    All timestamps are Unix epoch milliseconds. Counter fields can be `null` when
    YouTube does not expose a value or Monitor YT has not collected one yet.
  </Step>

  <Step title="Request the next page">
    Pass `nextCursor` unchanged in the next request body. Stop when it is `null`.

    ```json theme={null}
    {
      "cursor": "665f21c09b1d8a4f30aa1234",
      "limit": 20
    }
    ```
  </Step>
</Steps>

## Add filters

```json theme={null}
{
  "limit": 20,
  "types": ["video_published", "title_changed"],
  "channelIds": ["665f21c09b1d8a4f30aa5678"]
}
```

`channelIds` uses the Monitor YT `channel.id` returned in events, not the YouTube
`youtubeChannelId`. Omit a filter array to include every value on that dimension.

## Continue building

* Explore the complete [feed request](/feed-api).
* Fetch [video history and stat samples](/videos-api).
* Handle [errors and rate limits](/errors-and-rate-limits).
