Skip to content

📡 Status

Overview

The POST /api/status endpoint is used to retrieve the status of the given source. It contains information about the source, channels, and other relevant information.

Request

POST /api/status

{
  "clientVersion": "2.1.2",
  // Your server's global options can be sent in the status request
  "sort": "new",
  "flavor": "mint chocolate chip"
}

Server Options

Your server's options can be used to customize the experience for the user. For example, you may return different categories, channels, or notices based on their preferences.

Response

{
  "id": "example-server",
  "name": "Example Video Server",
  "subtitle": "A demo video streaming service.",
  "description": "This is an example server demonstrating the Hot Tub API structure and capabilities.",
  "iconUrl": "https://example.com/icon.png",
  "color": "#007AFF",
  "status": "active",
  "notices": [
    {
      "status": "warning",
      "message": "Scheduled Maintenance",
      "details": "Our servers will undergo maintenance on January 15th from 2:00-4:00 AM UTC. Some features may be temporarily unavailable.",
      "priority": true,
      "url": null
    },
    {
      "status": "info",
      "message": "New Features Available",
      "details": "Check out our latest update with improved video quality and faster loading times!",
      "priority": false,
      "url": "https://example.com/changelog"
    }
  ],
  "channels": [
    {
      "id": "example-tube",
      "name": "Example Tube",
      "description": "A sample video channel demonstrating the API structure.",
      "premium": false,
      "favicon": "https://example.com/favicon.ico",
      "status": "active",
      "categories": ["Entertainment", "Education", "Music"],
      "options": [
        {
          "id": "quality",
          "title": "Video Quality",
          "systemImage": "video",
          "colorName": "blue",
          "multiSelect": false,
          "options": [
            {
              "id": "hd",
              "title": "HD",
              "description": "High definition videos only"
            },
            {
              "id": "any",
              "title": "Any Quality",
              "description": "Include all video qualities"
            }
          ]
        },
        {
          "id": "duration",
          "title": "Duration",
          "systemImage": "clock",
          "colorName": "orange",
          "multiSelect": true,
          "options": [
            {
              "id": "short",
              "title": "Short (< 5 min)",
              "description": "Videos under 5 minutes"
            },
            {
              "id": "medium",
              "title": "Medium (5-20 min)",
              "description": "Videos between 5-20 minutes"
            },
            {
              "id": "long",
              "title": "Long (> 20 min)",
              "description": "Videos over 20 minutes"
            }
          ]
        }
      ],
      "nsfw": false,
      "ytdlpCommand": "yt-dlp --format best",
      "cacheDuration": 1800
    }
  ],
  "nsfw": false,
  "categories": [
    "Funny",
    "Cute",
    "Action",
    "Adventure",
    "Animation",
    "Comedy",
    "Documentary",
    "Drama"
  ],
  "options": [
    {
      "id": "sort",
      "title": "Sort",
      "systemImage": "arrow.up.arrow.down",
      "colorName": "blue",
      "multiSelect": false,
      "options": [
        {
          "id": "new",
          "title": "New",
          "description": "Sort the videos by newest first."
        },
        {
          "id": "likes",
          "title": "Most Liked",
          "description": "Sort the videos by likes."
        }
      ]
    }
  ],
  "popup": null,
  "filtersFooter": "Help us improve our algorithms by selecting the categories that best describe you. These may not change search results on your source, but they help personalize the overall app experience."
}

Field Reference

ServerStatus Object

Field Type Required Description
id string ✅ Unique server identifier
name string ✅ Server display name
subtitle string âšĒ Brief server description
description string âšĒ Detailed server description
iconUrl string âšĒ Server icon/logo URL
color string âšĒ Brand color (hex code or Swift color names)
status ChannelStatus âšĒ Server operational status
notices Notice[] âšĒ Status notices/alerts
channels Channel[] âšĒ Available content channels
channelGroups ChannelGroup[] âšĒ Explicit channel picker sections (takes priority over per-channel groupKey/sortOrder)
nsfw boolean âšĒ Whether server contains adult content
categories string[] âšĒ Available content categories
options ChannelOption[] âšĒ Global server options
filtersFooter string âšĒ Footer text for filter UI

ChannelGroup Object

An explicit, ordered section definition for the channel picker. When present, channelGroups takes full priority over per-channel groupKey and sortOrder.

Field Type Required Description
id string ✅ Unique group identifier
title string ✅ Section heading displayed in the channel picker
channelIds string[] ✅ Ordered list of channel IDs belonging to this group

Channel Picker Section Logic

The channel picker builds sections using the following priority order:

  1. channelGroups (top-level, on ServerStatus) — explicit sections with named titles and an ordered list of channel IDs. Use this for full control over grouping and order.
  2. groupKey + sortOrder (per-channel fields) — lightweight fallback. Channels are grouped by their groupKey string; within each group they are sorted by sortOrder (ascending), then alphabetically. Use this when you don't want a separate top-level structure.
  3. Default — if neither is provided, channels are split into a "Premium" section and a general "Channels" section, each sorted alphabetically.
// Option A: channelGroups (explicit, recommended for complex layouts)
{
  "channelGroups": [
    { "id": "featured", "title": "Featured", "channelIds": ["tube-a", "tube-b"] },
    { "id": "niche",    "title": "Niche",    "channelIds": ["tube-c"] }
  ]
}

// Option B: groupKey + sortOrder (per-channel, simpler)
{ "id": "tube-a", "groupKey": "Featured", "sortOrder": 1 }
{ "id": "tube-b", "groupKey": "Featured", "sortOrder": 2 }
{ "id": "tube-c", "groupKey": "Niche",    "sortOrder": 1 }

Channel Object

Field Type Required Description
id string ✅ Unique channel identifier
name string ✅ Channel display name
favicon string âšĒ Channel favicon URL
status ChannelStatus âšĒ Channel operational status
categories string[] âšĒ Content categories for this channel — drives the home screen category browser (tapping one runs a search for that term)
tags ChannelTag[] âšĒ Specialization chips shown in the channel picker (e.g. "4K", "Amateur")
options ChannelOption[] âšĒ Channel-specific filter options
maintainers ChannelMaintainer[] âšĒ Attribution entries shown in video cells
premium boolean âšĒ Whether channel requires premium
description string âšĒ Channel description
image string âšĒ Channel banner/hero image URL
nsfw boolean âšĒ Whether channel contains adult content
default boolean âšĒ Whether this channel is selected by default
sortOrder number âšĒ Display order when channelGroups is not used — lower values appear first
groupKey string âšĒ Section key for grouping channels (e.g. "favorites", "premium", or a category name)
ytdlpCommand string âšĒ Custom yt-dlp command
cacheDuration number âšĒ Cache duration in seconds — yt-dlp re-extracts video details when expired

Categories vs Tags

  • categories is a flat list of content keywords (e.g. "Comedy", "Action") shared across videos from this channel. They populate the home screen category browser — tapping one runs a search using that term.
  • tags are specialization labels for the channel itself (e.g. "4K", "Amateur", "VR") displayed as chips in the channel picker UI. They describe what the site is known for, not individual video content.

ChannelTag Object

Tags can be supplied as a plain string (legacy) or a typed object — the app accepts both transparently.

Field Type Required Description
name string ✅ Tag label displayed on the channel chip
systemImage string âšĒ SF Symbol name shown alongside the tag label
// Plain string (legacy — still accepted)
"categories": ["4K", "Amateur"]

// Object format (recommended — supports icons)
"tags": [
  { "name": "4K", "systemImage": "4k.tv" },
  { "name": "VR", "systemImage": "visionpro" }
]

ChannelMaintainer Object

Field Type Required Description
id string ✅ Maintainer identifier
name string ✅ Display name
avatar string âšĒ Avatar image URL (canonical)
role string âšĒ "maintainer" (built the integration) or "upstream" (federated proxy)

See JSON key names for naming conventions and the legacy profile_picture_url avatar key.

Notice Object

Field Type Required Description
status string ✅ Notice type ("success", "info", "error", "warning", etc.)
message string âšĒ Notice title/message
details string âšĒ Detailed notice description
priority boolean âšĒ Whether to display prominently on home page
url string âšĒ Action URL for the notice

ChannelOption Object

Field Type Required Description
id string ✅ Unique option identifier
title string ✅ Option display title
options ChannelOptionChoice[] ✅ Available choices for this option
systemImage string âšĒ SF Symbol name for option icon
colorName string âšĒ Swift color name for theming
multiSelect boolean âšĒ Whether multiple choices can be selected
value string\|number\|boolean âšĒ Current option value

ChannelOptionChoice Object

Field Type Required Description
id string ✅ Unique choice identifier
title string ✅ Choice display title
description string âšĒ Choice description
options ChannelOption[] âšĒ Nested options shown when this choice is selected

ChannelStatus Enum

Value Description
active Channel is online and fully functional (same as normal / ok)
normal Alias for active
ok Alias for active
inactive Channel deliberately disabled or suspended
degraded Channel working with reduced quality or performance
maintenance Channel temporarily unavailable due to planned work
restricted Access is limited (e.g. region-locked, paywalled, or subject to a takedown)
error Channel encountered a critical issue
unknown Channel status is not known
testing Channel is in testing mode for development

Implementation Notes

  • Only id and name are truly required for both ServerStatus and Channel
  • Options create hierarchical filter UIs — choices can have nested options
  • priority notices appear on the home page; others only appear on the lock screen
  • Colors support both hex codes (#FF0000) and Swift color names (purple)
  • Channel tags accept either plain strings (legacy) or { name, systemImage } objects — mixing both in the same array is fine
  • sortOrder and groupKey are the per-channel fallback for sectioning; channelGroups on the server response takes priority when present

Popup System

The popup system allows servers to display onboarding flows, age verification, preferences, and other modal content. Here's an example multi-page onboarding popup:

{
  "popup": {
    "id": "onboarding",
    "pages": [
      {
        "id": "ageVerification",
        "title": "Welcome to",
        "subtitle": "Example Server",
        "warning": "âš ī¸ Adult Content Warning",
        "body": "This source contains adult content. You must be 18 years or older to use it. By continuing, you confirm that you meet this requirement and agree to use the app responsibly.",
        "items": [
          {
            "type": "section",
            "title": "Age Verification",
            "items": [
              {
                "type": "toggle",
                "id": "termsToggle",
                "title": "I am over 18 years of age",
                "systemImage": "checkmark.seal.fill",
                "color": "gray",
                "state": false
              }
            ]
          }
        ],
        "actions": [
          {
            "title": "Continue",
            "systemImage": "arrow.right.circle.fill",
            "color": "blue",
            "actionType": "next",
            "enabledBy": "termsToggle"
          }
        ]
      },
      {
        "id": "preferences",
        "title": "Choose your Preferences",
        "subtitle": "Personalize Your Experience",
        "body": "Select the type of content you'd like to explore. This can be changed later in the filters menu.",
        "items": [
          {
            "type": "custom",
            "view": "ServerFiltersView"
          }
        ],
        "actions": [
          {
            "title": "Continue",
            "systemImage": "arrow.right.circle.fill",
            "color": "blue",
            "actionType": "next"
          }
        ]
      }
    ]
  }
}

Popup Features:

  • Multi-page flows - Create step-by-step onboarding experiences
  • Conditional actions - Use enabledBy to require toggle states before proceeding
  • Custom views - Embed specialized UI like ServerFiltersView for complex interactions
  • Rich content - Support for titles, subtitles, warnings, body text, and actions
  • Interactive controls - Toggles, buttons, and sections for user input
Was this page helpful?