Repository navigation
Dashboard HTTP API
The web dashboard is a static page talking to a small JSON API
on the same port. The API can also be used directly — from a script, a
home-automation system or curl — for example to read the current HDR format
or to switch VS10 modes.
The API is an internal interface of the dashboard. It is stable in practice but not versioned; check this page after updates.
Base URL: http://<box-ip>:<port> (port 8099 by default).
Send the access token in the X-TinyPPI-Token header, or as a token
query parameter (used by the page for the event stream and image URLs, where
headers cannot be set):
curl -H 'X-TinyPPI-Token: ABCD2345' http://192.168.1.20:8099/api/state
curl 'http://192.168.1.20:8099/api/state?token=ABCD2345'| Route type | Token required |
|---|---|
GET /api/hello |
never |
Other GET routes ("readers") |
only with Require the token for reading too on, or under an untrusted Host name (see Dashboard Security) |
All POST routes ("writers") |
always, and Allow VS10 switching from the dashboard must be on |
Errors are JSON: {"error": "<message>"}.
| Status | Body | Meaning |
|---|---|---|
| 400 |
bad body length, bad JSON, unknown mode, command failed, playback failed, update failed, watched required, no title named
|
The request was not understood or the action failed. |
| 401 | token required |
Missing or wrong token. |
| 403 | control disabled |
A write with Allow VS10 switching off. |
| 403 | library disabled |
The film/series library is switched off (or control is off). |
| 404 |
no such route, no such artwork, no artwork, no such series
|
Unknown path, or nothing to return. |
| 429 |
too many wrong tokens (+ retry_ms, Retry-After) |
The address is locked out for guessing. |
| 503 |
too many streams / shutting down (+ retry_ms) |
All six stream slots are taken, or Kodi is shutting down. |
| 503 | library unavailable |
The video database could not be read. |
Start-up information for the page. No token, no player state.
{
"name": "TinyPPI",
"version": "2.14.0",
"auth_read": false,
"control": true,
"library": true,
"series": true,
"interval_ms": 200,
"strings": { "...": "localized UI strings" }
}| Field | Meaning |
|---|---|
auth_read |
Whether this request would need the token to read (setting or untrusted host). |
control |
Allow VS10 switching from the dashboard. |
library / series
|
Whether the film / series shelves are offered (each needs its setting and control). |
interval_ms |
How often a watched snapshot is rebuilt (200 ms). |
The current snapshot, once. Use it for polling when you don't want a stream.
While something plays the snapshot contains, among others:
| Key | Content |
|---|---|
seq |
Snapshot sequence number. |
playing, paused
|
Player state. |
title, filename
|
Title; the file name only when Show file name is on. |
hdr_type |
Source format: "" (SDR), hdr10, hdr10plus, hlg, dolbyvision. |
effective |
The type the overlay layout follows (differs during VS10 conversion). |
output_type |
The format actually being output. |
time, duration, finish
|
Position, duration, and the clock time it ends at (box's regional format). |
metrics |
Cache, frame rate and other figures for the metric tiles. |
groups |
The overlay's rows as cards: [{id, title, rows: [{id, label, value, detail}]}]. Card ids: video, processing, audio, system, hdr, dv, metadata. |
metadata |
The Dolby Vision metadata list (only for Dolby Vision, with Show the Dolby Vision metadata view on). |
vs10 |
{"options": [{"mode", "label"}], "output": "…"} — the switchable modes for this source and the current output. |
art |
Tags of the playing title's artwork (used in /api/art URLs). |
media |
year, genre, show, season, episode. |
controls |
What the remote can offer: audio tracks, subtitles, chapters … |
session |
{seq, switches, warnings} — when seq changes, re-read /api/history. |
library |
The library version; when it changes, re-read the shelves. |
control |
Same as in /api/hello. |
streams_full |
Whether a stream request would currently be refused. |
With nothing playing: playing: false, empty groups/metadata, plus last
— the summary of the title that ended within the last ten minutes
(title, position, ago, switches, warnings, peak, events).
Example — read the source format with jq:
curl -s http://192.168.1.20:8099/api/state | jq -r '.hdr_type, .output_type'A Server-Sent Events stream of snapshots. One stream slot of six is held while connected.
| Event | Data |
|---|---|
state |
The first frame: a complete snapshot (as /api/state). |
delta |
Every following frame: only what changed (see below). |
bye |
{"retry_ms": 20000} — the server is stopping; wait before reconnecting. |
: ping (comment)
|
Heartbeat every 15 s on an idle stream. |
A delta frame has the shape:
{
"seq": 1234,
"set": { "time": "01:12:45", "metrics": { "...": "..." } },
"del": ["some_key"],
"groups": { "rows": [["<row id>", "<value>", "<detail>"]] },
"metadata": { "rows": [[17, "<value or cells>"]] }
}-
set— top-level keys whose value changed, sent whole. -
del— top-level keys that disappeared. -
groups/metadata— either{"rows": [...]}with only the changed rows (while the card/row layout is unchanged), or the complete new list when the layout changed.
Frames come at most five times a second, and only when something moved.
curl -N 'http://192.168.1.20:8099/api/stream?token=ABCD2345'The chart and event history of the current (or just finished) title:
{
"now": 4380.2, "step": 1.0,
"t": [0.0, 1.0, "..."], "max": [812.3, "..."], "avg": [96.1, "..."],
"events": [{"t": 1203.4, "pos": "00:20:03", "kind": "audio", "...": "..."}],
"seq": 7, "switches": 3
}t is seconds since playback started; max / avg are L1 peak and average in
nits (null outside Dolby Vision). Event kinds: vs10, mode, audio,
subtitle, fps, temperature, cpu.
The film library: {"movies": [...], "count": N, "tag": "…"}. Each film:
id, title, poster (tag), and when known year, duration (seconds),
watched, resume, rating, added. The response has an ETag; send it
back as If-None-Match to get a cheap 304 Not Modified.
The series library: {"shows": [...], "count": N, "tag": "…"}.
The episodes of one series: {"tvshowid", "title", "episodes": [...], "count", "tag"}.
404 no such series means the library changed; reload /api/series.
Films and episodes stopped part-way, newest first (up to 30):
{"items": [{"kind": "movie" | "episode", ...}], "count", "tag"}.
Artwork: kind is poster, fanart or thumb. Without an id, the playing
title's artwork. With a v tag the answer is cacheable for a week
(immutable). Images are served from Kodi's texture cache where possible.
All take a JSON body (max 4 KB), need the token and Allow VS10 switching.
curl -X POST -H 'X-TinyPPI-Token: ABCD2345' -H 'Content-Type: application/json' \
-d '{"mode": "hdr10"}' http://192.168.1.20:8099/api/modeAccepted modes are exactly the dashboard's buttons: original_sdr, hdr10,
dv, original_hdr, sdr8, original_dv. The call returns at once
({"ok": true, "mode": "hdr10"}); the switch runs in the background, and a
newer request replaces one still waiting. For sdr10 and original_hlg use
RunScript(script.tinyppi,run_mode,…) (see
Launching and Keymaps).
Body: {"action": "<action>", "value": <value>}.
| Action | Value | Effect |
|---|---|---|
playpause |
— | Toggle pause. |
stop |
— | Stop playback. |
seek |
seconds, −3600 … 3600 | Relative seek. |
seek_percent |
0 … 100 | Absolute seek (relative to the EPG event on live TV). |
volume_up / volume_down / mute
|
— | Sent as remote actions (CEC-friendly). |
volume |
0 … 100 | Absolute Kodi volume (kept for older clients). |
chapter_previous / chapter_next
|
— | Chapter skip; fails without at least two chapters. |
audio |
stream index 0 … 64 | Select an audio track. |
subtitle |
index 0 … 64, or −1 | Select and enable a subtitle; −1 turns subtitles off. |
curl -X POST -H 'X-TinyPPI-Token: ABCD2345' -H 'Content-Type: application/json' \
-d '{"action": "seek", "value": 30}' http://192.168.1.20:8099/api/command{"movieid": 123} or {"episodeid": 456}; add "resume": false to start from
the beginning (anything else resumes).
{"movieid": 123, "watched": true} — or tvshowid (every episode) or
episodeid. watched must be a boolean.
{"movieid": 123} or {"episodeid": 456}.
/, /index.html, /metadata, /metadata.html, /manifest.webmanifest,
/icon.png, /fanart.png, and the page's own css/, js/ and icons/
files. They are served gzip-compressed (when the browser accepts it) with an
ETag, so a revisit is answered with 304.
User guide
- Installation
- Getting Started
- Launching and Keymaps
- The TinyPPI Overlay
- Dolby Vision Metadata View
- VS10 Output Modes
- Codec Logos
- Channel Layout Graphic
- IMAX Detection
- Colors and Themes
Web dashboard
Reference
Developers
Project