StreamDek
Developers

Build on StreamDek

Connect an application to a viewer's account, subscribe to what happens on it, or publish an add-on. Everything the platform will and will not do is published, so you can design against it before you write anything.

Start here

Connecting to an account

OAuth 2.1 authorization code with PKCE. A viewer sees exactly which permissions you are asking for, in plain words, and can disconnect you from their account screen at any time — at which point your access stops on the next request rather than at the next token expiry.

Access tokens are short-lived and refresh tokens rotate. Presenting a refresh token twice is treated as theft and ends the whole grant, so store the newest one you were given and nothing else.

What a permission reaches

A scope is a permit list, not a category. An endpoint nobody has decided about is unreachable with a connected application's token, including endpoints added after you integrated.

PermissionReaches
devices:readGET /devices
history:readGET /history
history:writePUT /history/:ref, DELETE /history/:ref
library:readGET /library
profile:readGET /profile
progress:readGET /progress, GET /progress/:ref, GET /continue-watching
progress:writePUT /progress/:ref, DELETE /continue-watching/:ref
watchlist:readGET /watchlist
watchlist:writePUT /watchlist/:ref, DELETE /watchlist/:ref

Being told when something happens

Webhooks, signed and retried, so you do not have to poll. Each event type needs the permission that would let you read the same thing — a webhook is a standing read, and it is checked on every delivery rather than only when you subscribed.

  • watchlist.item.added — A title was added to the watchlist. (watchlist:read)
  • watchlist.item.removed — A title was removed from the watchlist. (watchlist:read)
  • progress.updated — A playback position moved. Emitted on every checkpoint. (progress:read)
  • media.started — Playback of a title began. (progress:read)
  • media.paused — Playback stopped part-way through. (progress:read)
  • media.completed — A title was watched to the end. (progress:read)
  • history.item.watched — A title was marked watched. (history:read)
  • history.item.unwatched — A title was marked unwatched. (history:read)
  • sync.completed — A write was mirrored to a connected tracking service. (progress:read)

Publishing an add-on

An add-on is an HTTP endpoint StreamDek calls — never code we run, and never given a database or an account. If you already ship a Stremio add-on, StreamDek reads the same manifest and you have most of these already.

  • metadata — Describes one title: name, year, artwork, episodes.
  • catalog — Serves a browsable list of titles.
  • search — Answers a text query. Derived from a catalog declaring a `search` extra.
  • recommendations — Suggests titles related to a seed. StreamDek decides how they are presented.
  • subtitles — Offers subtitle tracks for a title.
  • intros — Marks intro, recap and credits ranges. Feeds the Phase 3 timeline model.
  • streams — Returns stream candidates. Never resolved server-side -- see the note below.

What the platform will never do

Published so you can design around it rather than discover it when a request is refused.

  • No public or delegated route reaches source discovery, debrid resolution, or provider credentials.
  • Debrid resolution happens on the device, with the viewer own credentials. It is never performed server-side.
  • A delegated token reaches only the routes its scopes name. Everything else is refused, including endpoints added later.
  • An add-on is an HTTP endpoint StreamDek calls. It never receives an account id, a token, or any credential.
  • A webhook payload carries ids and canonical state. Never a credential, and never another account anything.
Build on StreamDek — StreamDek