Media Analytics
4 endpoints from the published OpenAPI import.
Media Analytics Overview
Library analytics rollup: video totals + most-viewed assets + the catalog kind/tier breakdown, joined to PeerTube views/viewers via one batched call.
If PeerTube is unreachable the catalog data still returns with total_views null and source="unavailable" — never a 500.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/media/analytics/overview' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/media/analytics/overview",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/media/analytics/overview", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/media/analytics/overview", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Media Asset Analytics
Per-asset engagement. 404 if the asset doesn't exist for the tenant.
Video assets carry PeerTube views/viewers (source="peertube", or "unavailable" if the fetch failed — views null, never a 500). Non-video assets return engagement_available=false + source="not_applicable" (graceful — analytics is video-centric for now), NOT a 404/500.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
asset_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Media Asset Trend
Per-asset view/viewer TREND over time, from the daily snapshot rollup (public.media_stats_daily). 404 if the asset doesn't exist for the tenant.
points is the [{date, views, viewers}] series ascending by date. It's [] for a non-video asset, a video never snapshotted, or a brand-new video on day-0 — trends accrue FORWARD (PeerTube has no historical per-day series), so day-1 is a single point and fills in nightly. Unlike the live-PeerTube analytics routes, this reads only the local rollup, so it never depends on PeerTube being reachable at request time.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
asset_id | path | string | true | |
range | query | string | false | Window: 7d | 30d | 90d |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}/trend' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}/trend",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}/trend", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}/trend", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Media Asset Watchtime
Per-asset watch-time / retention (4.3b), proxied from PeerTube's owner-stats via the LLM11 import-api. 404 if the asset doesn't exist for the tenant.
Video assets carry an overall block (watch-time in seconds, viewers, peak, countries) + a daily timeseries (viewers + watch-time-seconds). A non-video asset (or a video with no peertube_uuid) returns engagement_available=false + overall=null/timeseries=null (graceful empty-state, NOT a 404/500). RESILIENCE: if LLM11/PeerTube is unreachable the response is source="unavailable" with null blocks — NEVER a 500.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
asset_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}/watchtime' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}/watchtime",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}/watchtime", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/media/analytics/assets/{asset_id}/watchtime", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |