Skip to content

Clip Analytics API#

The Clip Analytics endpoint provides the same engagement metrics that power the Storyteller CMS clip analytics dashboard. Use it to populate BI tools, concierge dashboards, or automated reporting without duplicating analytics logic.

Endpoints#

By External ID#

GET https://integrations.usestoryteller.com/api/clips/{externalId}/analytics
Parameter Type Required Description
externalId string Path External ID of the clip you want to analyse

By ID#

GET https://integrations.usestoryteller.com/api/clips/by-id/{id}/analytics
Parameter Type Required Description
id string (GUID) Path Internal Storyteller clip ID

Analytics are aggregated across all available history. Date filtering is not currently exposed via the Integrations API.

Example Response#

{
  "clipViewsTotal": 12854,
  "clipLoopsTotal": 7645,
  "viewersTotal": 4120,
  "sharesTotal": 583,
  "clickThroughsTotal": 241,
  "likesTotal": 1330,
  "charts": {
    "multiLinesCharts": null,
    "singleLineCharts": [
      {
        "title": "Clip Views",
        "iconName": "",
        "total": 12854,
        "totalDisplay": "12,854",
        "percentage": 0,
        "percentageDisplay": "0.00",
        "data": [
          {
            "key": 1,
            "values": {
              "Clip Views": 2143,
              "name": "Feb 04 2025, 10:00 AM"
            }
          }
        ]
      },
      {
        "title": "Clip Loops",
        "iconName": "",
        "total": 7645,
        "totalDisplay": "7,645",
        "percentage": 0,
        "percentageDisplay": "0.00",
        "data": [
          {
            "key": 1,
            "values": {
              "Clip Loops": 1320,
              "name": "Feb 04 2025, 10:00 AM"
            }
          }
        ]
      }
    ]
  }
}

Metrics Returned#

Field Description
clipViewsTotal Total clip opens (equivalent to CMS “Views”)
clipLoopsTotal Completed loops/playbacks
viewersTotal Unique viewers derived from open events
sharesTotal Share button taps
clickThroughsTotal Action button taps (swipe ups)
likesTotal Total likes

Chart Set Structure#

The charts property mirrors the CMS analytics widgets and uses the shared chart DTOs:

  • singleLineCharts contains one entry per metric (Clip Views, Clip Loops, Viewers, Shares, Click Throughs, Likes).
  • Each chart has hourly buckets in Eastern Time to stay aligned with Storyteller dashboards.
  • multiLinesCharts is currently null for clip analytics.

Usage Examples#

import fetch from 'node-fetch';

export async function getClipAnalytics(apiKey, externalId) {
  const response = await fetch(`https://integrations.usestoryteller.com/api/clips/${externalId}/analytics`, {
    headers: { 'x-storyteller-api-key': apiKey }
  });

  if (!response.ok) {
    const problem = await response.json();
    throw new Error(`${problem.title}: ${problem.detail}`);
  }

  return response.json();
}
import requests

def get_clip_analytics(api_key: str, external_id: str) -> dict:
    response = requests.get(
        f"https://integrations.usestoryteller.com/api/clips/{external_id}/analytics",
        headers={'x-storyteller-api-key': api_key},
        timeout=30
    )
    response.raise_for_status()
    return response.json()
public async Task<ClipAnalyticsResponse?> GetClipAnalyticsAsync(string apiKey, string externalId)
{
    using var client = new HttpClient { BaseAddress = new Uri("https://integrations.usestoryteller.com/") };
    client.DefaultRequestHeaders.Add("x-storyteller-api-key", apiKey);

    var response = await client.GetAsync($"api/clips/{externalId}/analytics");
    if (!response.IsSuccessStatusCode)
    {
        var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
        throw new InvalidOperationException(problem?.Detail ?? "Unable to load clip analytics");
    }

    return await response.Content.ReadFromJsonAsync<ClipAnalyticsResponse>();
}
curl -X GET "https://integrations.usestoryteller.com/api/clips/clip-001/analytics" \
  -H "x-storyteller-api-key: YOUR_API_KEY"

Best Practices#

  1. Map analytics to CMS links – pair totals with cmsAnalyticsUrl from the Clips API for quick drill-down.
  2. Convert to local timezones if your UI requires region-specific timestamps; the API returns Eastern Time buckets by design.
  3. Respect polling cadence – metrics update hourly, so fetching more frequently than every few minutes offers little benefit.
  4. Plan for new metrics – store raw chart data if you intend to support additional Storyteller metrics without redeploying.
  5. Handle Problem Details responses to gracefully surface missing clips or authentication errors.