Skip to content

Content types and ids

webstats('content', ...) takes a type and one or more ids. type is a closed list of 12 values. Providers inside ids are open: any provider: id pair is accepted and stored.

typeProviders, primary firstExample (one is enough)
movietmdb, imdb{ tmdb: '278' }
tvshowtmdb, tvdb, imdb{ tmdb: '1399' }
animemal, anilist{ mal: '16498' }
mangamal, anilist{ mal: '2' }
musicmbid{ mbid: '5b11f4ce-a62d-471e-81fc-a69a8278c7da' }
audiobookasin, olid{ asin: 'B002V1OF70' }
bookisbn, olid{ isbn: '9780140328721' }
comiccv{ cv: '4000-1699' }
videogameigdb{ igdb: '1020' }
podcastpodcastindex{ podcastindex: '75075' }
sporttsdb, sr{ tsdb: '133602' }
personwd{ wd: 'Q937' }

One id is enough; extra ids improve catalog matching. The primary provider forms the stored key, so send it when you have it. IMDb ids keep their tt prefix; every other id is the raw value.

A type outside this list is rejected and the declaration is dropped.

For tvshow, anime, and podcast, the top-level ids are the series. The episode block is optional and gives you per-episode numbers on top of the series total.

webstats('content', {
type: 'tvshow',
ids: { tmdb: '1399' },
title: 'Game of Thrones',
episode: { ids: { tmdb: '63056' }, season: 1, number: 1, title: 'Winter Is Coming' },
});

Every field in episode is optional, including ids.

Use self with any stable id of your own:

webstats('content', { type: 'movie', ids: { self: 'film-9931' }, title: 'Our Original Film' });

Cross-source matching is skipped, everything else works. Any unrecognised provider is accepted and stored the same way; it may just not be enriched with poster and metadata yet.

sport has no fixed duration, so completion, retention, and the 25/50/75/100% milestones are skipped automatically. Engagement and playback quality still record.

RuleLimit
Providers per declaration12
Provider name24 characters
Id value128 characters
title256 characters

Ids beyond the limit are dropped, not rejected. An empty ids object drops the declaration.