class ytapi_kit._analytics.AnalyticsClient(session: AuthorizedSession)[source]

Bases: object

Tiny Analytics client with retries, type‑coercion, and rate‑limit detection.

channel_ad_performance(**kw) DataFrame[source]

Inspect ad-revenue performance for the authenticated channel.

The helper queries the Analytics API with dimensions=("adType")display, bumper, skippable in-stream, etc.— and defaults to the adRate metric (revenue per 1 000 monetized playbacks). Override metrics in **kw if you need additional figures such as grossRevenue or cpm.

Parameters:

**kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per adType with the requested metric columns.

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_ad_performance(
...     metrics=("adRate", "grossRevenue"),
...     start_date="2024-01-01",
...     end_date="2024-12-31",
... )
>>> df.head()
channel_demographics(*, demographic: str | Sequence[str] = 'ageGroup', **kw) DataFrame[source]

Break down channel’s audience by age and/or gender.

Parameters:
  • demographic (str | Sequence[str], optional) – A single literal or an iterable chosen from: - "ageGroup" – 13-17, 18-24, …, 65-plus (default) - "gender"male, female, user-specified Pass both to obtain a multi-dimension report, e.g. demographic=("ageGroup", "gender").

  • **kw – Extra keyword arguments forwarded verbatim to reports_query() (for example start_date, end_date, or a custom metrics tuple).

Returns:

One row per demographic combo.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If demographic contains anything outside {"ageGroup", "gender"}.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_demographics(
...     demographic=("ageGroup", "gender"),
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
channel_devices(*, device_info: str | Sequence[str] = 'deviceType', **kw) DataFrame[source]

Break down channel stats by viewers’ device characteristics.

Parameters:
  • device_info (str | Sequence[str], optional) –

    Either a single literal or an iterable drawn from: - "deviceType" – desktop, mobile, tablet, TV, etc. (default) - "operatingSystem" – iOS, Android, Windows, macOS, etc.

    You may pass both to get a multi-dimension report, e.g. device_info=("deviceType", "operatingSystem").

  • **kw – Additional keyword arguments forwarded unchanged to reports_query() (such as start_date, metrics).

Returns:

One row per device characteristic.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If device_info contains anything outside {"deviceType", "operatingSystem"}.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_devices(
...     device_info=("deviceType", "operatingSystem"),
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
channel_geography(*, geo_dim: str = 'country', max_results: int = 200, **kw) DataFrame[source]

Returns channel stats by geographical region (e.g. “country”, “city”, etc.)

Parameters:
  • geo_dim (str, optional) – Geographic granularity— 'country' (default), 'province', 'dma', or 'city'.

  • max_results (int, optional) – Maximum rows per API page. Defaults to 200.

  • **kw – Extra keyword arguments forwarded intact to reports_query() (e.g. start_date, end_date).

Returns:

A dataframe with one row per geo_dim.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If geo_dim is not one of the allowed values.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_geography(
...     geo_dim="dma",
...     start_date="2024-01-01",
...     end_date="2024-01-31",
... )
>>> df.head()
channel_membership_cancellation(**kw) DataFrame[source]

Analyse why paying members cancel their channel memberships.

The report groups rows by membershipCancellationSurveyReason and returns the metric membershipsCancellationSurveyResponses (count of answers per reason). Use this to spot the top churn drivers—price, content cadence, “just browsing,” etc.

Parameters:

**kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per membershipCancellationSurveyReason with the membershipsCancellationSurveyResponses metric.

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_membership_cancellation(
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
channel_playback_details(*, detail: str = 'liveOrOnDemand', **kw) DataFrame[source]

Break down channel stats by a playback-detail dimension (live vs. VOD, etc.).

Parameters:
  • detail (str, optional) – Dimension to split by—must be one of 'creatorContentType', 'liveOrOnDemand', 'subscribedStatus', 'youtubeProduct'. Defaults to 'liveOrOnDemand'.

  • **kw – Extra keyword arguments forwarded verbatim to reports_query() (e.g. start_date, metrics).

Returns:

One row per detail value, with the metrics requested (default views & estimatedMinutesWatched).

Return type:

pandas.DataFrame

Raises:
  • ValueError – If detail is not one of the allowed literals.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_playback_details(
...     detail="subscribedStatus",
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
channel_playback_location(*, detail: bool = False, max_results: int = 200, **kw) DataFrame[source]

Return where viewers watched channel videos (YouTube, embedded players, etc.).

Parameters:
  • detail (bool, optional) –

    • False (default) – group results by high-level insightPlaybackLocationType (e.g. EMBEDDED, YOUTUBE).

    • True – drill into insightPlaybackLocationDetail; the API automatically filters to insightPlaybackLocationType==EMBEDDED and caps max_results at 25.

  • max_results (int, optional) – Requested page size. Ignored when detail is True because the API hard-caps it.

  • **kw – Extra keyword arguments forwarded verbatim to reports_query() (e.g. start_date, end_date).

Returns:

One row per playback-location.

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_playback_location(
...     detail=True,
...     start_date="2024-01-01",
...     end_date="2024-03-31",
... )
>>> df.head()
channel_sharing_services(**kw) DataFrame[source]

Show which social / messaging platforms drove shares to the channel.

Parameters:

**kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per sharingService.

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_sharing_services(
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
channel_stats(**kw) DataFrame[source]

Get stats for a channel.

This is a generic channel stats helper: whatever metrics/dimensions you pass through **kw pass to reports_query(), which means you can ask for any Analytics combo without creating a new wrapper.

Parameters:

**kw – Keyword arguments forwarded verbatim to reports_query() — for example metrics, dimensions, start_date, end_date, filters, etc.

Returns:

One row per requested dimension(s).

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_stats(
...     metrics=("views", "likes", "comments"),
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
channel_time_period(*, time_period: str = 'month', start_date: str | date, end_date: str | date, max_results: int | None = None, **kw) DataFrame[source]

Summarise channel performance by calendar day or month.

Parameters:
  • time_period (str, optional) – Reporting grain—either "day" or "month". Defaults to "month".

  • start_date (str | datetime.date) – ISO YYYY-MM-DD or date object marking the start of the reporting window (inclusive).

  • end_date (str | datetime.date) – ISO YYYY-MM-DD or date object marking the end of the reporting window (inclusive).

  • max_results (int | None, optional) – Number of rows to return.

  • **kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per {day | month}.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If time_period is not "day" or "month".

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_time_period(
...     time_period="day",
...     start_date="2024-01-01",
...     end_date="2024-01-31",
... )
>>> df.head()
channel_top_videos(**kw) DataFrame[source]

Return the top-performing videos in the channel.

Parameters:

**kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per video.

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_top_videos(
...     metrics=("views", "likes", "comments"),
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
channel_traffic_sources(*, detail: str | None = None, **kw) DataFrame[source]

Break down traffic sources for the channel.

Parameters:
  • detail (str | None, optional) –

    • None (default) – group rows by high-level insightTrafficSourceType (e.g. YT_SEARCH, RELATED_VIDEO).

    • Any literal in {"ADVERTISING", "CAMPAIGN_CARD", "END_SCREEN", "EXT_URL", "HASHTAGS", "NOTIFICATION", "RELATED_VIDEO", "SOUND_PAGE", "SUBSCRIBER", "YT_CHANNEL", "YT_OTHER_PAGE", "YT_SEARCH", "VIDEO_REMIXES"} – drill into insightTrafficSourceDetail for that specific type.

  • **kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

  • If detail is None – one row per insightTrafficSourceType.

  • If detail is provided – one row per insightTrafficSourceDetail.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If detail is not None and not in the allowed literal set shown above.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.channel_traffic_sources(
...     detail="YT_SEARCH",
...     start_date="2024-01-01",
...     end_date="2024-03-31",
... )
>>> df.head()
playlist_top_videos(playlist_ids: str | Sequence[str], **kw) DataFrame[source]

Return the top-performing videos within one or more playlists.

Parameters:
  • playlist_ids (str | Sequence[str]) – One or more YouTube playlist IDs.

  • **kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per video × playlist , with whatever metrics requested (defaults to views and estimatedMinutesWatched).

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.playlist_top_videos(
...     ["PL9tY0BWXOZFtQ-GG8X2E8oia-MfeLeGKv"],
...     metrics=("views", "likes", "comments"),
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
reports_query(*, ids: str = 'channel==MINE', metrics: str | Sequence[str] | None = None, dimensions: str | Sequence[str] | None = None, sort: str | None = None, max_results: int | None = 10, filters: str | None = None, start_date: str | date = '2000-01-01', end_date: str | date | None = None, currency: str | None = None, start_index: int | None = None, include_historical_channel_data: bool | None = None) DataFrame[source]

Send a single YouTube Analytics reports.query request and return the result as a pandas DataFrame`.

Most other functions in this package are wrappers for this function with some arguments already populated. If none of the other prebuilt functions work for your use case, this is the function to turn to.

Parameters:
  • ids (str, optional) – The ids request parameter. Defaults to "channel==MINE" (i.e. the authorised user’s own channel).

  • metrics (Iterable[str] | str, optional) – Comma-separated string or iterable of metric names. If None, defaults to ("views", "estimatedMinutesWatched"). Must contain at least one metric.

  • dimensions (Iterable[str] | str, optional) – Comma-separated string or iterable of dimension names.

  • sort (str, optional) – Sort order. If None we auto-sort descending on the first metric (e.g. "-views").

  • max_results (int | None, optional) – None defaults to 10.

  • filters (str, optional) – Raw filter string, e.g. "country==US;video==abc123".

  • start_date (str | date, optional) – Start of reporting window (inclusive). If you pass a datetime.date, we convert it to ISO-8601.

  • end_date (str | date | None, optional) – End of reporting window (inclusive). None ⇒ today.

  • currency (str, optional) – 3-letter ISO code when requesting revenue metrics.

  • start_index (int, optional) – 1-based pagination index.

  • include_historical_channel_data (bool, optional) – When True, include data from before the channel was linked to the current owner.

Returns:

A tidy dataframe whose columns mirror the API’s columnHeaders list, with dtypes coerced to sensible pandas types (Int64, float, datetime64[ns]).

Return type:

pandas.DataFrame

Raises:
  • QuotaExceeded – If the API replies with HTTP 403 and a quota-related error code (quotaExceeded, userRateLimitExceeded …).

  • YTAPIError – For any other failure (4xx, 5xx).

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.reports_query(
...     metrics=["views", "likes"],
...     dimensions=["day"],
...     start_date="2024-01-01",
...     end_date="2024-01-31",
...     max_results=None,
... )
>>> df.head()
video_audience_retention(video_ids: str | Sequence[str], *, audience_type: str | None = None, **kw) DataFrame[source]

Chart how well viewers stick around for each video (audience‐retention).

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • audience_type (str | None, optional) –

    Filter the report by viewer origin:

    • "ORGANIC" – regular, unpaid views

    • "AD_INSTREAM" – pre-roll / mid-roll ad views

    • "AD_INDISPLAY" – video discovery ads

    • None (default) – all audiences combined

    Any other literal triggers a tidy bullet-listed ValueError.

  • **kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per video × elapsedVideoTimeRatio bucket, with the audienceWatchRatio metric.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If audience_type is not None and not in {"ORGANIC", "AD_INSTREAM", "AD_INDISPLAY"}.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_audience_retention(
...     ["dQw4w9WgXcQ"],
...     audience_type="ORGANIC",
...     start_date="2024-01-01",
...     end_date="2024-03-31",
... )
>>> df.head()
video_demographics(video_ids: str | Sequence[str], *, demographic: str | Sequence[str] = 'ageGroup', **kw) DataFrame[source]

Break down each video’s audience by age and/or gender.

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • demographic (str | Sequence[str], optional) – A single literal or an iterable chosen from: - "ageGroup" – 13-17, 18-24, …, 65-plus (default) - "gender"male, female, user-specified Pass both to obtain a multi-dimension report, e.g. demographic=("ageGroup", "gender").

  • **kw – Extra keyword arguments forwarded verbatim to reports_query() (for example start_date, end_date, or a custom metrics tuple).

Returns:

One row per video × demographic combo with the requested metrics (defaults to views and estimatedMinutesWatched if not overridden).

Return type:

pandas.DataFrame

Raises:
  • ValueError – If demographic contains anything outside {"ageGroup", "gender"}.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_demographics(
...     ["dQw4w9WgXcQ", "HEXWRTEbj1I"],
...     demographic=("ageGroup", "gender"),
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
video_devices(video_ids: str | Sequence[str], *, device_info: str | Sequence[str] = 'deviceType', **kw) DataFrame[source]

Break down each video by viewers’ device characteristics.

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • device_info (str | Sequence[str], optional) –

    Either a single literal or an iterable drawn from: - "deviceType" – desktop, mobile, tablet, TV, etc. (default) - "operatingSystem" – iOS, Android, Windows, macOS, etc.

    You may pass both to get a multi-dimension report, e.g. device_info=("deviceType", "operatingSystem").

  • **kw – Additional keyword arguments forwarded unchanged to reports_query() (such as start_date, metrics).

Returns:

One row per video × device combo containing the requested metrics (defaults to views and estimatedMinutesWatched if not overridden).

Return type:

pandas.DataFrame

Raises:
  • ValueError – If device_info contains anything outside {"deviceType", "operatingSystem"}.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_devices(
...     ["dQw4w9WgXcQ", "HEXWRTEbj1I"],
...     device_info=("deviceType", "operatingSystem"),
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
video_geography(video_ids: str | Sequence[str], *, geo_dim: str = 'country', max_results: int = 200, **kw) DataFrame[source]

Returns video stats by geographical region (e.g. “country”, “city”, etc.)

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • geo_dim (str, optional) – Geographic granularity— 'country' (default), 'province', 'dma', or 'city'.

  • max_results (int, optional) – Maximum rows per API page. Defaults to 200.

  • **kw – Extra keyword arguments forwarded intact to reports_query() (e.g. start_date, end_date).

Returns:

A dataframe with one row per video × geo_dim.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If geo_dim is not one of the allowed values.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_geography(
...     ["dQw4w9WgXcQ", "HEXWRTEbj1I"],
...     geo_dim="dma",
...     start_date="2024-01-01",
...     end_date="2024-01-31",
... )
>>> df.head()
video_live_position(video_ids: str | Sequence[str], *, metrics: str | Sequence[str] = 'peakConcurrentViewers', **kw) DataFrame[source]

Fetch live-stream performance by in-broadcast position.

The API’s liveStreamPosition dimension buckets data by how far a viewer was into the stream when they joined (0–10 %, 10–25 %, etc.).

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • metrics (str | Sequence[str], optional) – Metric name or collection drawn from: - "averageConcurrentViewers" - "peakConcurrentViewers" (default) Pass a list/tuple when you need both.

  • **kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per video × liveStreamPosition bucket with the requested metric columns.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If metrics is empty or contains anything outside {"averageConcurrentViewers", "peakConcurrentViewers"}.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_live_position(
...     ["dQw4w9WgXcQ"],
...     metrics=("averageConcurrentViewers", "peakConcurrentViewers"),
...     start_date="2024-05-01",
...     end_date="2024-05-31",
... )
>>> df.head()
video_playback_details(video_ids: str | Sequence[str], *, detail: str = 'liveOrOnDemand', **kw) DataFrame[source]

Break down each video by a playback-detail dimension (live vs. VOD, etc.).

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • detail (str, optional) – Dimension to split by—must be one of 'creatorContentType', 'liveOrOnDemand', 'subscribedStatus', 'youtubeProduct'. Defaults to 'liveOrOnDemand'.

  • **kw – Extra keyword arguments forwarded verbatim to reports_query() (e.g. start_date, metrics).

Returns:

One row per video × detail.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If detail is not one of the allowed literals.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_playback_details(
...     ["dQw4w9WgXcQ"],
...     detail="subscribedStatus",
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
video_playback_location(video_ids: str | Sequence[str], *, detail: bool = False, max_results: int = 200, **kw) DataFrame[source]

Return where viewers watched each video (YouTube, embedded players, etc.).

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • detail (bool, optional) –

    • False (default) – group results by high-level insightPlaybackLocationType (e.g. EMBEDDED, YOUTUBE).

    • True – drill into insightPlaybackLocationDetail; the API automatically filters to insightPlaybackLocationType==EMBEDDED and caps max_results at 25.

  • max_results (int, optional) – Requested page size. Ignored when detail is True because the API hard-caps it.

  • **kw – Extra keyword arguments forwarded verbatim to reports_query() (e.g. start_date, end_date).

Returns:

One row per video × playback-location

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_playback_location(
...     ["dQw4w9WgXcQ"],
...     detail=True,
...     start_date="2024-01-01",
...     end_date="2024-03-31",
... )
>>> df.head()
video_sharing_services(video_ids: str | Sequence[str], **kw) DataFrame[source]

Show which social / messaging platforms drove shares for each video.

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • **kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per video × sharingService.

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_sharing_services(
...     ["dQw4w9WgXcQ", "HEXWRTEbj1I"],
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
video_stats(video_ids: str | Sequence[str], **kw) DataFrame[source]

Get stats for one or more videos.

This is a generic video stats helper: whatever metrics/dimensions you pass through **kw pass to reports_query(), which means you can ask for any Analytics combo without creating a new wrapper.

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • **kw – Keyword arguments forwarded verbatim to reports_query() — for example metrics, dimensions, start_date, end_date, filters, etc.

Returns:

One row per video × requested dimension(s) with the metrics you asked for (defaults to views and estimatedMinutesWatched).

Return type:

pandas.DataFrame

Raises:

QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_stats(
...     ["dQw4w9WgXcQ", "HEXWRTEbj1I"],
...     metrics=("views", "likes", "comments"),
...     start_date="2024-01-01",
...     end_date="2024-06-30",
... )
>>> df.head()
video_time_period(video_ids: str | Sequence[str], *, time_period: str = 'month', start_date: str | date, end_date: str | date, max_results: int | None = None, **kw) DataFrame[source]

Summarise video performance by calendar day or month.

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • time_period (str, optional) – Reporting grain—either "day" or "month". Defaults to "month".

  • start_date (str | datetime.date) – ISO YYYY-MM-DD or date object marking the start of the reporting window (inclusive).

  • end_date (str | datetime.date) – ISO YYYY-MM-DD or date object marking the end of the reporting window (inclusive).

  • max_results (int | None, optional) – Number of rows to return.

  • **kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

One row per video × {day | month} with the metrics requested (defaults to views and estimatedMinutesWatched).

Return type:

pandas.DataFrame

Raises:
  • ValueError – If time_period is not "day" or "month".

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_time_period(
...     ["dQw4w9WgXcQ", "HEXWRTEbj1I"],
...     time_period="day",
...     start_date="2024-01-01",
...     end_date="2024-01-31",
... )
>>> df.head()
video_traffic_sources(video_ids: str | Sequence[str], *, detail: str | None = None, **kw) DataFrame[source]

Break down traffic sources for one or more videos.

Parameters:
  • video_ids (str | Sequence[str]) – One or more YouTube video IDs.

  • detail (str | None, optional) –

    • None (default) – group rows by high-level insightTrafficSourceType (e.g. YT_SEARCH, RELATED_VIDEO).

    • Any literal in {"ADVERTISING", "CAMPAIGN_CARD", "END_SCREEN", "EXT_URL", "HASHTAGS", "NOTIFICATION", "RELATED_VIDEO", "SOUND_PAGE", "SUBSCRIBER", "YT_CHANNEL", "YT_OTHER_PAGE", "YT_SEARCH", "VIDEO_REMIXES"} – drill into insightTrafficSourceDetail for that specific type.

  • **kw – Keyword arguments forwarded unchanged to reports_query() – e.g. start_date, end_date, or a custom filters string.

Returns:

  • If detail is None – one row per video × insightTrafficSourceType.

  • If detail is provided – one row per video × insightTrafficSourceDetail.

Metrics default to views and estimatedMinutesWatched unless overridden via **kw.

Return type:

pandas.DataFrame

Raises:
  • ValueError – If detail is not None and not in the allowed literal set shown above.

  • QuotaExceeded / AnalyticsError – Propagated from reports_query().

Example

>>> yt = AnalyticsClient(creds)
>>> df = yt.video_traffic_sources(
...     ["dQw4w9WgXcQ"],
...     detail="YT_SEARCH",
...     start_date="2024-01-01",
...     end_date="2024-03-31",
... )
>>> df.head()