curl --request GET \
--url https://api.tella.com/v1/analytics \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.tella.com/v1/analytics"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.tella.com/v1/analytics', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tella.com/v1/analytics",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.tella.com/v1/analytics"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.tella.com/v1/analytics")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tella.com/v1/analytics")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"endDate": "<string>",
"geoBreakdown": [
{
"country": "US",
"uniqueSessions": 0,
"views": 0
}
],
"pagination": {
"hasMore": true,
"nextCursor": "eyJpZCI6IjEyMyJ9"
},
"referrerBreakdown": [
{
"referrerDomain": "linkedin.com",
"uniqueSessions": 0,
"views": 0
}
],
"retention": [
{
"percent": 42,
"uniqueViewers": 0,
"watchCount": 0
}
],
"scope": "workspace",
"startDate": "<string>",
"summary": {
"avgPercentViewed": 63.5,
"pageOpens": 1610,
"totalViews": 1280,
"totalWatchTimeSeconds": 48210.4,
"uniqueSessions": 940
},
"timezone": "UTC",
"topVideos": [
{
"avgPercentViewed": 71.2,
"name": "Q3 product update",
"uniqueSessions": 0,
"videoId": "vid_abc123def456",
"views": 0
}
],
"viewsOverTime": [
{
"date": "2026-01-14",
"uniqueSessions": 0,
"views": 0
}
]
}{
"docsUrl": "https://docs.tella.com/",
"error": "bad_request",
"message": "The request was malformed or contained invalid parameters."
}{
"docsUrl": "https://docs.tella.com/",
"error": "unauthorized",
"message": "Authentication is required. Provide a valid API key."
}{
"docsUrl": "https://docs.tella.com/",
"error": "forbidden",
"message": "You don't have permission to access this resource."
}{
"docsUrl": "https://docs.tella.com/",
"error": "not_found",
"message": "The requested resource was not found."
}{
"docsUrl": "https://docs.tella.com/",
"error": "conflict",
"message": "The request conflicts with the resource's current state, e.g. an Idempotency-Key whose first request is still in progress. Retry once it settles."
}{
"docsUrl": "https://docs.tella.com/",
"error": "rate_limited",
"message": "You have exceeded the rate limit. Please slow down."
}{
"docsUrl": "https://docs.tella.com/",
"error": "server_error",
"message": "An unexpected error occurred"
}{
"docsUrl": "https://docs.tella.com/",
"error": "not_implemented",
"message": "The requested operation is not implemented."
}{
"docsUrl": "https://docs.tella.com/",
"error": "unavailable",
"message": "A dependency was unavailable and the request was not executed. Safe to resend unchanged after the Retry-After delay."
}Get workspace analytics
Viewing analytics aggregated across videos: by default every video shared with the workspace, or with scope=mine only the videos you created. Includes the same summary, plays per day, retention, geography and referrer breakdowns as a single video, plus the videos ranked by plays. Only topVideos is paginated; pass pagination.nextCursor as cursor for the next page. Dates are whole UTC days; omit both for all time.
curl --request GET \
--url https://api.tella.com/v1/analytics \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.tella.com/v1/analytics"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.tella.com/v1/analytics', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tella.com/v1/analytics",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.tella.com/v1/analytics"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.tella.com/v1/analytics")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tella.com/v1/analytics")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"endDate": "<string>",
"geoBreakdown": [
{
"country": "US",
"uniqueSessions": 0,
"views": 0
}
],
"pagination": {
"hasMore": true,
"nextCursor": "eyJpZCI6IjEyMyJ9"
},
"referrerBreakdown": [
{
"referrerDomain": "linkedin.com",
"uniqueSessions": 0,
"views": 0
}
],
"retention": [
{
"percent": 42,
"uniqueViewers": 0,
"watchCount": 0
}
],
"scope": "workspace",
"startDate": "<string>",
"summary": {
"avgPercentViewed": 63.5,
"pageOpens": 1610,
"totalViews": 1280,
"totalWatchTimeSeconds": 48210.4,
"uniqueSessions": 940
},
"timezone": "UTC",
"topVideos": [
{
"avgPercentViewed": 71.2,
"name": "Q3 product update",
"uniqueSessions": 0,
"videoId": "vid_abc123def456",
"views": 0
}
],
"viewsOverTime": [
{
"date": "2026-01-14",
"uniqueSessions": 0,
"views": 0
}
]
}{
"docsUrl": "https://docs.tella.com/",
"error": "bad_request",
"message": "The request was malformed or contained invalid parameters."
}{
"docsUrl": "https://docs.tella.com/",
"error": "unauthorized",
"message": "Authentication is required. Provide a valid API key."
}{
"docsUrl": "https://docs.tella.com/",
"error": "forbidden",
"message": "You don't have permission to access this resource."
}{
"docsUrl": "https://docs.tella.com/",
"error": "not_found",
"message": "The requested resource was not found."
}{
"docsUrl": "https://docs.tella.com/",
"error": "conflict",
"message": "The request conflicts with the resource's current state, e.g. an Idempotency-Key whose first request is still in progress. Retry once it settles."
}{
"docsUrl": "https://docs.tella.com/",
"error": "rate_limited",
"message": "You have exceeded the rate limit. Please slow down."
}{
"docsUrl": "https://docs.tella.com/",
"error": "server_error",
"message": "An unexpected error occurred"
}{
"docsUrl": "https://docs.tella.com/",
"error": "not_implemented",
"message": "The requested operation is not implemented."
}{
"docsUrl": "https://docs.tella.com/",
"error": "unavailable",
"message": "A dependency was unavailable and the request was not executed. Safe to resend unchanged after the Retry-After delay."
}Authorizations
API key obtained from your Tella account settings
Query Parameters
First day of the range, inclusive, as YYYY-MM-DD in UTC. Omit to start from the first recorded view.
^\d{4}-\d{2}-\d{2}$"2026-01-01"
Last day of the range, inclusive, as YYYY-MM-DD in UTC. Omit to run through today.
^\d{4}-\d{2}-\d{2}$"2026-01-01"
IANA time zone used to bucket viewsOverTime into days (default: UTC)
"America/New_York"
Which videos to aggregate (default: workspace)
workspace, mine "workspace"
Top videos per page (default: 20, max: 100)
1 <= x <= 10020
Opaque cursor for the next page of top videos, from the previous response's pagination.nextCursor
Response
OK
Viewing analytics aggregated across the workspace's videos. Everything except topVideos covers the whole scope; only topVideos is paginated.
The endDate that was applied, or null for no upper bound
Plays by country, up to 100 rows by views
Hide child attributes
Hide child attributes
Pagination metadata for list responses. Results are sorted by updatedAt descending.
Hide child attributes
Hide child attributes
Whether there are more items to fetch
true
Cursor for next page. Pass this value as the 'cursor' query parameter to fetch the next page. Null if no more pages. This is an opaque value - do not decode or modify it.
"eyJpZCI6IjEyMyJ9"
Plays by referring domain, up to 100 rows by views
Hide child attributes
Hide child attributes
Domain the viewer arrived from; null for direct or unknown traffic
"linkedin.com"
-9007199254740991 <= x <= 9007199254740991-9007199254740991 <= x <= 9007199254740991Watch counts per one-percent slice of the video, ascending
Hide child attributes
Hide child attributes
Position in the video as a percentage of its duration
0 <= x <= 10042
Distinct viewers who watched this slice
-9007199254740991 <= x <= 9007199254740991Times this one-percent slice was watched, including replays by the same viewer
-9007199254740991 <= x <= 9007199254740991workspace: every video shared with the workspace. mine: videos the authenticated user created.
workspace, mine "workspace"
The startDate that was applied, or null for no lower bound
Headline viewing metrics
Hide child attributes
Hide child attributes
Average share of the video watched per play, from 0 to 100. Null when nothing was watched in the range.
63.5
Times the video page was opened, whether or not playback started
-9007199254740991 <= x <= 90071992547409911610
Plays in the range. A play is counted once a viewer starts the video.
-9007199254740991 <= x <= 90071992547409911280
Total time viewers spent watching, in seconds
48210.4
Distinct viewer sessions that started a play
-9007199254740991 <= x <= 9007199254740991940
Time zone used to bucket viewsOverTime
"UTC"
Videos ranked by plays in the range, descending
Hide child attributes
Hide child attributes
Average share of the video watched per play, 0 to 100
71.2
Video title; null when the video has since been deleted but its views remain counted
"Q3 product update"
-9007199254740991 <= x <= 9007199254740991"vid_abc123def456"
-9007199254740991 <= x <= 9007199254740991Plays per day, ascending
Hide child attributes
Hide child attributes
Day as YYYY-MM-DD in the requested timezone
"2026-01-14"
Distinct viewer sessions that day
-9007199254740991 <= x <= 9007199254740991Plays that day
-9007199254740991 <= x <= 9007199254740991Was this page helpful?