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
- The API reference — every endpoint, generated from the running service.
- The OpenAPI document — point a client generator at it.
- Base URL
https://api.streamdek.net/api/v1, version v1.
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.
| Permission | Reaches |
|---|---|
devices:read | GET /devices |
history:read | GET /history |
history:write | PUT /history/:ref, DELETE /history/:ref |
library:read | GET /library |
profile:read | GET /profile |
progress:read | GET /progress, GET /progress/:ref, GET /continue-watching |
progress:write | PUT /progress/:ref, DELETE /continue-watching/:ref |
watchlist:read | GET /watchlist |
watchlist:write | PUT /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.