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

# Panda Video as a data source

> Bring your Panda Video videos, folders, playlists, lives and viewing analytics to Nekt.

Panda Video is a Brazilian video hosting platform used for sales videos (VSLs), online courses and live streams, with a secure player, DRM and viewing analytics. This connector reads your video library (videos, folders, playlists and lives) and your viewing analytics: views and plays per day, per video and hour, per country, browser, operating system and embedding page, and the average engagement of each video.

> [!NOTE]
>
> The connector only reads data. It never uploads, changes or deletes videos, folders, playlists or lives.

## Configuring Panda Video as a Source

In the [Sources](https://app.nekt.ai/sources) tab, click on the "Add source" button located on the top right of your screen. Then, select the Panda Video option from the list of connectors.

Click **Next** and you'll be prompted to add your access.

### 1. Add account access

You'll need a Panda Video API key. In the Panda Video dashboard, go to **Settings > Advanced > API Key** and copy the key.

The following configurations are available:

* **API Key**: Your Panda Video API key. Paste it as it is, without a `Bearer` prefix. The key gives access to the whole Panda Video account, so keep it private.
* **Start Date**: The first day of viewing analytics read on the first sync. The analytics are read one day at a time, so an older date makes the first sync longer. Videos, folders, playlists and lives are always read in full, whatever this date.

Once you're done, click **Next**.

### 2. Select streams

Choose which data streams you want to sync. For faster extractions, select only the streams that are relevant to your analysis. You can select entire groups of streams or pick specific ones.

> Tip: The stream can be found more easily by typing its name.

Select the streams and click **Next**.

### 3. Configure data streams

Customize how you want your data to appear in your catalog. Select the desired layer where the data will be placed, a folder to organize it inside the layer, a name for each table (which will effectively contain the fetched data) and the type of sync.

* **Layer**: choose between the existing layers on your catalog. This is where you will find your new extracted tables as the extraction runs successfully.
* **Folder**: a folder can be created inside the selected layer to group all tables being created from this new data source.
* **Table name**: we suggest a name, but feel free to customize it. You have the option to add a **prefix** to all tables at once and make this process faster!
* **Sync Type**: you can choose between INCREMENTAL and FULL\_TABLE.
  * Incremental: every time the extraction happens, we'll get only the new data, which is good if, for example, you want to keep every record ever fetched.
  * Full table: every time the extraction happens, we'll get the current state of the data, which is good if, for example, you don't want to have deleted data in your catalog.

Once you are done configuring, click **Next**.

### 4. Configure data source

Describe your data source for easy identification within your organization, not exceeding 140 characters.

To define your [Trigger](https://docs.nekt.com/runs/scheduling-and-triggers.md), consider how often you want data to be extracted from this source. This decision usually depends on how frequently you need the new table data updated (every day, once a week, or only at specific times). Panda Video processes each day's analytics after the day ends, so a daily sync is usually enough.

Optionally, you can define some additional settings:

* Configure Delta Log Retention and determine for how long we should store old states of this table as it gets updated. Read more about this resource [here](https://docs.nekt.com/get-started/core-concepts/resource-control).
* Determine when to execute an **Additional [Full Sync](https://docs.nekt.com/get-started/core-concepts/types-of-sync#additional-full-sync)**. This will complement the incremental data extractions, ensuring that your data is completely synchronized with your source every once in a while. For the analytics tables, a full sync reads every day again from the Start Date, which takes longer.

Once you are ready, click **Next** to finalize the setup.

### 5. Check your new source

You can view your new source on the [Sources](https://app.nekt.ai/sources) page. If needed, manually trigger the source extraction by clicking on the arrow button. Once executed, your data will appear in your Catalog.

> [!WARNING]
>
> For you to be able to see it on your [Catalog](https://app.nekt.ai/catalog), you need at least one successful source run.

## How the data is read

* **Analytics are read by UTC day, up to yesterday.** Panda Video finishes processing a day after it ends, so today's partial numbers are not loaded. Each sync also reads the last 7 days again, to pick up late processing.
* **Daily totals are in UTC.** Every `date` is a UTC day, so daily numbers may not match the Panda Video dashboard when it shows another time zone (for example, Brasília time). Totals over a week or a month match closely.
* **Breakdowns are checked against the daily totals.** If Panda Video returns no country, browser or operating system data for any of the days read although some had views, that table is not updated in the run (with a message saying so) instead of loading a gap; the next run tries again. A few days without breakdown data among normal days (for example, a handful of views with no browser or country recorded) only produce a warning, and the table loads. The referrer table only warns, because views opened directly on the player link may have no referrer.
* **Unique viewers are counted per hour by Panda Video.** A day's `unique_view` and `unique_play` are the sum of its hours, so a person who comes back later the same day is counted again. This is how Panda Video defines these metrics.
* **Joining analytics to videos:** the analytics tables identify videos by `video_external_id`. Join them with `videos.video_external_id`, not with `videos.id`.
* **Rate limit:** Panda Video allows 200 requests per minute per network address. The connector stays well below it and waits when Panda Video asks it to, so a large first sync can take a while.
* **Permissions:** if Panda Video refuses a group of tables (for example, analytics not included in your plan), those tables are skipped with a warning that names them, and the other tables keep syncing.

# Streams and Fields

## Available streams

The table below lists every stream, its **slug** (the exact identifier to pass when creating the source via API) and a short description.

| Stream | Slug | Description |
| - | - | - |
| Videos | `videos` | Every video of the account, with status, folder, duration, size and player URLs. |
| Folders | `folders` | Active folders and their parent folder. |
| Playlists | `playlists` | Playlists of the account. |
| Playlist Videos | `playlist_videos` | The videos of each playlist, in playlist order. |
| Lives | `lives` | Live streams with status, schedule and recording. |
| Daily Metrics | `daily_metrics` | Account views, plays and unique viewers per day. |
| Video Hourly Metrics | `video_hourly_metrics` | Views, plays and unique viewers of each video per hour. |
| Video Daily Engagement | `video_daily_engagement` | Average share of each video watched per day. |
| Daily Country Metrics | `daily_country_metrics` | Views and plays per country and day. |
| Daily Browser Metrics | `daily_browser_metrics` | Views and plays per browser and day. |
| Daily OS Metrics | `daily_os_metrics` | Views and plays per operating system and day. |
| Daily Referrer Metrics | `daily_referrer_metrics` | Views and plays per page where the player was embedded, per day. |

Every table also has an `extra_fields` column with fields Panda Video sent that are not mapped to a column yet (JSON).

## Fields by stream

> [accordion] Videos
>
> Stream `videos`. Every video of the account. Full table; key `id`.
>
> * `id` - Internal ID of the video (used by the API's video routes)
> * `video_external_id` - Public external ID of the video, used in player URLs, webhooks and the analytics tables
> * `title` - Video title
> * `description` - Video description
> * `status` - Conversion status: DRAFT, CONVERTING, CONVERTED, FAILED, BLOCKED or DELETING (in the trash)
> * `user_id` - ID of the user who owns the video
> * `folder_id` - ID of the folder holding the video; empty when the video is in the root folder
> * `library_id` - ID of the library the video belongs to
> * `converted_at` - When the conversion finished; empty while still converting
> * `created_at` - When the video was created
> * `updated_at` - When the video was last updated
> * `storage_size` - Size of the stored video in bytes
> * `length` - Duration of the video in seconds
> * `width` - Native video width in pixels
> * `height` - Native video height in pixels
> * `video_player` - Embeddable player URL
> * `video_hls` - HLS playback URL
> * `thumbnail` - Thumbnail image URL
> * `preview` - Hover-preview asset URL (animated image)
> * `profile_id` - ID of the player profile linked to the video; empty when none
> * `player_state` - How the player of the video is configured: custom, default, profile or empty
> * `playable` - Whether the video is ready to play
> * `playback` - Enabled playback qualities, e.g. 360p, 720p, 1080p (JSON)
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Folders
>
> Stream `folders`. Active folders, with their parent folder. Full table; key `id`.
>
> * `id` - Unique identifier of the folder
> * `name` - Folder name
> * `user_id` - ID of the user who owns the folder
> * `parent_folder_id` - ID of the parent folder; empty for a folder in the root
> * `status` - Whether the folder is active (inactive folders are soft-deleted and not listed)
> * `videos_count` - Number of videos directly inside the folder
> * `player_state` - Whether the videos of the folder share a player profile: single, multiple or empty
> * `player_profile_id` - ID of the shared player profile when player\_state is single
> * `created_at` - When the folder was created
> * `updated_at` - When the folder was last updated
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Playlists
>
> Stream `playlists`. Playlists of the account (passwords are never stored). Full table; key `id`.
>
> * `id` - Unique identifier of the playlist
> * `user_id` - ID of the user who owns the playlist
> * `name` - Playlist name
> * `duration` - Total duration of the playlist's videos in seconds
> * `videos_quantity` - Number of videos in the playlist
> * `access_type` - Who can open the playlist: anyone\_with\_link or anyone\_with\_password
> * `image_url` - Custom logo URL of the playlist
> * `first_thumbnail` - Thumbnail of the first video of the playlist
> * `updated_at` - When the playlist was last updated
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Playlist Videos
>
> Stream `playlist_videos`. The videos of each playlist, in order. Full table; key `playlist_id`, `video_id`, `position`.
>
> * `playlist_id` - ID of the playlist
> * `video_id` - Internal ID of the video (joins videos.id)
> * `position` - Position of the video in the playlist, starting at 0 (the API's order field)
> * `video_title` - Title of the video
> * `video_duration` - Duration of the video in seconds
> * `video_thumbnail_url` - Thumbnail URL of the video
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Lives
>
> Stream `lives`. Live streams of the account. The stream key and the ingest URL are never stored. Full table; key `id`.
>
> * `id` - Unique identifier of the live
> * `title` - Title of the live
> * `status` - Current status: provisioning, offline, online, finishing, finished, finished\_imported, expired or canceled
> * `stream_key_id` - ID of the stream key used by the live (the key itself is not stored)
> * `user_id` - ID of the user who owns the live
> * `region` - Ingest region of the live
> * `quality_package` - Quality package of the live
> * `latency_type` - Latency mode of the live
> * `save_vod` - Whether the live is saved as a video when it ends
> * `active_dvr` - Whether DVR (rewind during the live) is enabled
> * `bitrate` - Qualities delivered to viewers, e.g. 360p, 720p (JSON)
> * `folder_id` - ID of the folder where the recording is saved
> * `live_hls` - HLS playback URL of the live
> * `live_player` - Embeddable player URL of the live
> * `scheduled_at` - When the live is scheduled to start
> * `started_at` - When the live started
> * `ended_at` - When the live ended
> * `vod_id` - ID of the recording (video on demand) created from the live
> * `video_id` - ID of the video created from the live
> * `created_at` - When the live was created
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Daily Metrics
>
> Stream `daily_metrics`. Account views and plays per day. Incremental by `date`; key `date`.
>
> * `date` - UTC day of the metrics, used as the incremental replication key
> * `view` - Number of views (player loads) in the period
> * `play` - Number of plays (the viewer pressed play) in the period
> * `unique_view` - Unique viewers in the period (Panda Video counts a viewer once per hour, so a day is the sum of its hours)
> * `unique_play` - Unique viewers who pressed play in the period (counted once per hour, summed over the day)
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Video Hourly Metrics
>
> Stream `video_hourly_metrics`. Views and plays of each video per hour. Incremental by `date`; key `date`, `hour`, `video_external_id`.
>
> * `date` - UTC day of the metrics, used as the incremental replication key
> * `hour` - Hour of the day (0-23, UTC) the metrics refer to
> * `video_external_id` - External ID of the video (joins videos.video\_external\_id)
> * `view` - Number of views (player loads) in the period
> * `play` - Number of plays (the viewer pressed play) in the period
> * `unique_view` - Unique viewers in the period (Panda Video counts a viewer once per hour, so a day is the sum of its hours)
> * `unique_play` - Unique viewers who pressed play in the period (counted once per hour, summed over the day)
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Video Daily Engagement
>
> Stream `video_daily_engagement`. Average share of each video watched per day. Incremental by `date`; key `date`, `video_key`.
>
> * `date` - UTC day of the metrics, used as the incremental replication key
> * `video_key` - Identifier of the video in this table: its external ID when Panda Video sends it, otherwise its ID
> * `video_external_id` - External ID of the video (joins videos.video\_external\_id)
> * `video_id` - ID of the video, when Panda Video sends it
> * `title` - Title of the video
> * `engagement` - Average share of the video watched by its viewers that day, in percent (0-100)
> * `retention_rate` - Retention rate of the video that day, in percent, when Panda Video sends it
> * `duration` - Duration of the video in seconds
> * `drop_off_points` - Retention at points of the video (seconds and percent), when Panda Video sends them (JSON)
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Daily Country Metrics
>
> Stream `daily_country_metrics`. Views and plays per country and day. Incremental by `date`; key `date`, `country`.
>
> * `date` - UTC day of the metrics, used as the incremental replication key
> * `country` - Country of the viewers (ISO 3166-1 alpha-2 code, as sent by Panda Video)
> * `view` - Number of views (player loads) in the period
> * `play` - Number of plays (the viewer pressed play) in the period
> * `unique_view` - Unique viewers in the period (Panda Video counts a viewer once per hour, so a day is the sum of its hours)
> * `unique_play` - Unique viewers who pressed play in the period (counted once per hour, summed over the day)
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Daily Browser Metrics
>
> Stream `daily_browser_metrics`. Views and plays per browser and day. Incremental by `date`; key `date`, `browser`.
>
> * `date` - UTC day of the metrics, used as the incremental replication key
> * `browser` - Browser of the viewers (e.g. Chrome, Safari)
> * `view` - Number of views (player loads) in the period
> * `play` - Number of plays (the viewer pressed play) in the period
> * `unique_view` - Unique viewers in the period (Panda Video counts a viewer once per hour, so a day is the sum of its hours)
> * `unique_play` - Unique viewers who pressed play in the period (counted once per hour, summed over the day)
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Daily OS Metrics
>
> Stream `daily_os_metrics`. Views and plays per operating system and day. Incremental by `date`; key `date`, `os`.
>
> * `date` - UTC day of the metrics, used as the incremental replication key
> * `os` - Operating system of the viewers (e.g. Android, iOS, Windows)
> * `view` - Number of views (player loads) in the period
> * `play` - Number of plays (the viewer pressed play) in the period
> * `unique_view` - Unique viewers in the period (Panda Video counts a viewer once per hour, so a day is the sum of its hours)
> * `unique_play` - Unique viewers who pressed play in the period (counted once per hour, summed over the day)
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)

> [accordion] Daily Referrer Metrics
>
> Stream `daily_referrer_metrics`. Views and plays per page where the player was embedded, per day. Incremental by `date`; key `date`, `referrer`.
>
> * `date` - UTC day of the metrics, used as the incremental replication key
> * `referrer` - Page (URL) where the player was embedded when the video was watched
> * `view` - Number of views (player loads) in the period
> * `play` - Number of plays (the viewer pressed play) in the period
> * `unique_view` - Unique viewers in the period (Panda Video counts a viewer once per hour, so a day is the sum of its hours)
> * `unique_play` - Unique viewers who pressed play in the period (counted once per hour, summed over the day)
> * `extra_fields` - Fields Panda Video returned that this connector does not map to a column yet, keyed by their original names (JSON)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.