Watch time by topic
US Region: https://public-api.sessionboard.com · EU Region: https://public-api-eu.sessionboard.com
Which topics keep people watching longest across your webinars. Live watch time is each attendee's minutes in the room divided by the webinar's scheduled length; on demand is the furthest each viewer got in the recording. Medians only. A webinar with two topics counts toward each. Topics with fewer than 5 people are left out and counted in suppressed. Defaults to the last 12 months. Read-only. Requires read:marketing. Also at GET /v1/marketing/results/topic-watch-time.
Request example
curl --request GET \ --url 'https://public-api.sessionboard.com/v1/organization/{orgId}/marketing/results/topic-watch-time' \ --header 'x-access-token: <api-token>'const response = await fetch('https://public-api.sessionboard.com/v1/organization/{orgId}/marketing/results/topic-watch-time', { method: 'GET', headers: { "x-access-token": "<api-token>" },});
const data = await response.json();console.log(data);import requests
response = requests.request( "GET", "https://public-api.sessionboard.com/v1/organization/{orgId}/marketing/results/topic-watch-time", headers={ "x-access-token": "<api-token>" },)
print(response.json())<?php
$curl = curl_init();
curl_setopt_array($curl, [ CURLOPT_URL => "https://public-api.sessionboard.com/v1/organization/{orgId}/marketing/results/topic-watch-time", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "x-access-token: <api-token>", ],]);
$response = curl_exec($curl);curl_close($curl);
echo $response;package main
import ( "fmt" "io" "net/http")
func main() { req, _ := http.NewRequest("GET", "https://public-api.sessionboard.com/v1/organization/{orgId}/marketing/results/topic-watch-time", nil) req.Header.Add("x-access-token", "<api-token>")
res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))}HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://public-api.sessionboard.com/v1/organization/{orgId}/marketing/results/topic-watch-time")) .header("x-access-token", "<api-token>") .method("GET", HttpRequest.BodyPublishers.noBody()) .build();
HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());Try it
Response headers
Authorizations
x-access-tokenstringheaderOrganization API token. Generate from Organization Settings → API Tokens.
AuthorizationBearer <token>headerorOAuth 2.1 access token. Obtained via the OAuth PKCE flow at
/oauth/token.
Send one of these. See Authentication.
Path parameters
orgIdstringpathrequiredYour organization ID. Any other organization returns
404.
Query parameters
eventIdintegerqueryOne webinar. Leave out for every webinar in the period.
fromstring<date>queryStart of the period,
YYYY-MM-DD.tostring<date>queryEnd of the period,
YYYY-MM-DD, inclusive.sortstringqueryOrder of
topics.- Allowed values
"live", "on_demand", "people"- Default
"live"
Responses
200application/json
OK
payloadWebinarTopicWatchTimeReportFields every webinar report carries.
Show child attributes
org_kindstring | nullCompany, association or event organizer.
nulluntil your organization sets it;labelsare then neutral.- Allowed values
"corporate", "association", "organizer", null
labelsOrgKindLabelsYour organization's own words, chosen by
org_kind. Use them for every word about people, organizations and money. For examplepeople_knownisCustomersfor a company,Membersfor an association andExhibitors and sponsorsfor an event organizer.Show child attributes
kind_namestring- Example
"Association"
people_knownstring- Example
"Members"
people_known_onestring- Example
"Member"
people_otherstring- Example
"Nonmembers"
organizationsstring- Example
"Member organizations"
organization_onestring- Example
"Member organization"
ownerstring- Example
"Staff contact"
system_of_recordstring- Example
"AMS"
questions_titlestring- Example
"Joining and renewal questions nobody has followed up"
outcomes_titlestring- Example
"Membership from people who attended"
createdstring- Example
"Became members"
closedstring- Example
"Renewed"
becamestring- Example
"Lapsed members back"
in_the_roomstring- Example
"In the room: annual dues of members who attended"
periodobjectShow child attributes
fromstring<date>tostring<date>
as_ofstring<date-time> | nullWhen the CRM or AMS was last read.
nullwhen nothing is connected.not_trackedobject[]What this report cannot measure, one plain sentence each.
Show child attributes
keystringreasonstring
truncatedbooleantruewhen the list was capped;<list>_totalthen gives the full count.orgobjectShow child attributes
webinarsintegermedian_live_sharenumber | nullmedian_on_demand_percentnumber | null
topics_totalintegertopicsobject[]Show child attributes
topicobjectShow child attributes
idstringnamestring
webinarsintegerpeopleintegerliveobject | nullShow child attributes
attendeesintegermedian_minutesnumbermedian_sharenumberShare of the scheduled length, 0 to 1.
on_demandobject | nullShow child attributes
viewersintegermedian_percentnumbercompleted_sharenumber
vs_orgobjectShow child attributes
live_pointsnumber | nullon_demand_pointsnumber | null
top_webinarsobject[]Show child attributes
event_idintegernamestringmedian_sharenumber
suppressedobjectShow child attributes
topicsintegerreasonstring
403
SCOPE_REQUIRED— the token lacksread:marketing(reads) orwrite:marketing(writes).ORG_WIDE_TOKEN_REQUIRED— the token is restricted to particular events; this operation reads the whole organization.FORBIDDEN— the organization's plan does not include Marketing, or the token's user cannot change goals (writes need an organization admin or the organization settings permission).
404
The event is not in your organization.
Response examples
{ "payload": { "org_kind": "corporate", "labels": { "kind_name": "Association", "people_known": "Members", "people_known_one": "Member", "people_other": "Nonmembers", "organizations": "Member organizations", "organization_one": "Member organization", "owner": "Staff contact", "system_of_record": "AMS", "questions_title": "Joining and renewal questions nobody has followed up", "outcomes_title": "Membership from people who attended", "created": "Became members", "closed": "Renewed", "became": "Lapsed members back", "in_the_room": "In the room: annual dues of members who attended" }, "period": { "from": "2026-01-15", "to": "2026-01-15" }, "as_of": "2026-01-15T09:30:00Z", "not_tracked": [ { "key": "<string>", "reason": "<string>" } ], "truncated": true, "org": { "webinars": 123, "median_live_share": 123.45, "median_on_demand_percent": 123.45 }, "topics_total": 123, "topics": [ { "topic": { "id": "<string>", "name": "<string>" }, "webinars": 123, "people": 123, "live": { "attendees": 123, "median_minutes": 123.45, "median_share": 123.45 }, "on_demand": { "viewers": 123, "median_percent": 123.45, "completed_share": 123.45 }, "vs_org": { "live_points": 123.45, "on_demand_points": 123.45 }, "top_webinars": [ { "event_id": 123, "name": "<string>", "median_share": 123.45 } ] } ], "suppressed": { "topics": 123, "reason": "<string>" } }}