#
Content & Classes API
Browse and discover fitness content, manage live class schedules, and track user viewing sessions. All endpoints require the X-API-Key header. Endpoints marked with
Bearer
also require Authorization: Bearer <token>.
#
Content Discovery
#
Home Feed
GET /content/discover
Bearer
Get the home screen content feed. Returns structured sections for building the main app screen.
{
"success": true,
"data": {
"featured": [
{
"id": 1,
"name": "Morning HIIT Blast",
"thumbnailUrl": "https://...",
"trainer": { "name": "Coach Mike" },
"duration": 30,
"intensity": "high"
}
],
"continueWatching": [ ],
"upcomingLive": [ ],
"categories": [ ],
"newThisWeek": [ ]
}
}
#
Browse Classes
GET /content/classes
Browse classes with filtering and pagination.
#
Class Detail
GET /content/classes/:id
Get full class details including trainer information and related classes.
{
"success": true,
"data": {
"class": {
"id": 42,
"name": "Morning HIIT Blast",
"description": "A high-energy 30-minute workout...",
"thumbnailUrl": "https://...",
"videoUrl": "https://...",
"duration": 30,
"intensity": "high",
"isPremium": false,
"trainer": {
"id": 5,
"name": "Coach Mike",
"image": "https://..."
},
"category": {
"id": 2,
"name": "HIIT"
},
"relatedClasses": [
{ "id": 43, "name": "Evening HIIT", "duration": 25 }
]
}
}
}
#
Search
GET /content/search
Full-text search across class names, descriptions, trainer names, and category names.
curl "https://api.studiostv.net/api/v1/content/search?q=yoga&limit=10" \
-H "X-API-Key: your-api-key"
const response = await fetch(
`${BASE_URL}/content/search?q=${encodeURIComponent(query)}&limit=10`,
{ headers: { 'X-API-Key': apiKey } }
);
const { data } = await response.json();
#
Categories
GET /content/categories
List all active categories assigned to this client with class counts.
{
"success": true,
"data": {
"categories": [
{ "id": 1, "name": "Yoga", "classCount": 24, "image": "https://..." },
{ "id": 2, "name": "HIIT", "classCount": 18, "image": "https://..." },
{ "id": 3, "name": "Pilates", "classCount": 12, "image": "https://..." }
]
}
}
#
Class Browsing (Alternative)
An alternative set of class endpoints with a slightly different response structure, useful for building browse/discover pages.
#
Live Classes
#
Schedule
GET /live/schedule
Get all upcoming live classes grouped by date.
{
"success": true,
"data": {
"schedule": {
"2026-03-01": [
{
"id": 10,
"name": "Live Yoga Flow",
"trainer": { "name": "Sarah" },
"scheduledTime": "09:00",
"duration": 60
}
],
"2026-03-02": [ ]
}
}
}
#
Add to My Schedule
POST /live/schedule/:classId
Bearer
Add a live class to the current user's schedule.
#
Remove from Schedule
DELETE /live/schedule/:classId
Bearer
Remove a live class from the current user's schedule.
#
My Schedule
GET /live/my-schedule
Bearer
Get the current user's scheduled live classes.
#
Session Tracking
Track user viewing progress for on-demand classes. Sessions persist progress so users can resume where they left off.
#
Start Session
POST /sessions/start
Bearer
Start a new viewing session. If the user already has an in-progress session for the same class, the existing session is returned.
{
"classId": 42,
"deviceType": "mobile"
}
{
"success": true,
"data": {
"session": {
"id": 1,
"classId": 42,
"userId": 1,
"status": "in_progress",
"progressSeconds": 0,
"startedAt": "2026-02-28T10:00:00Z"
}
}
}
#
Update Progress
POST /sessions/:id/progress
Bearer
Send progress updates. Call this every ~30 seconds from the client player.
{
"progressSeconds": 540,
"totalDurationSeconds": 1800,
"castingMethod": "chromecast"
}
Auto-completion
Sessions automatically complete at 90% progress. You do not need to explicitly call the complete endpoint in most cases.
#
Complete Session
POST /sessions/:id/complete
Bearer
Manually mark a viewing session as complete.
#
Viewing History
GET /sessions/history
Bearer
Get the user's viewing history with class details and progress percentages.
#
App Strings
GET /app/strings
Get client-specific content strings such as About Us and Privacy Policy. These are HTML strings managed by partners via the Partner Portal.
Auth: X-API-Key required
{
"success": true,
"data": [
{
"st_aboutus": "<h1>About Us</h1><p>Content...</p>",
"st_privacypolicy": "<h1>Privacy Policy</h1><p>Policy...</p>"
}
]
}
Render the HTML in a WebView or HTML renderer. Fetch once and cache locally.
#
Products
GET /products
Browse affiliate products created by the partner. Only returns products with status active.
Auth: X-API-Key required
#
List Products
GET /products
{
"success": true,
"data": {
"products": [
{
"id": "uuid",
"name": "Protein Powder",
"description": "Premium whey protein...",
"image": "https://...",
"price": "29.99",
"currency": "USD",
"externalUrl": "https://shop.example.com/protein",
"productType": "Supplements",
"featured": true,
"status": "active",
"sortOrder": 0
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 5,
"totalPages": 1
}
}
}
#
Product Detail
GET /products/:id
Get a single product by ID. The externalUrl field should be opened in an external browser for the "Buy Now" action.
#
Product Types
GET /products/types
List distinct product types for the current client with counts. Use to build category/filter navigation in the store.
{
"success": true,
"data": [
{ "productType": "Apparel", "count": 3 },
{ "productType": "Supplements", "count": 5 }
]
}
#
Building a Content Experience
Here is a recommended approach for building a content-driven app:
Call GET /content/discover to populate the home screen with featured content, continue watching, and upcoming live classes. This single endpoint provides everything needed for the main screen.
Use GET /content/classes with filter parameters to build a browsable catalogue. Fetch categories with GET /content/categories for the filter UI.
When a user taps play, call POST /sessions/start to create or resume a session. Send progress heartbeats every 30 seconds with POST /sessions/:id/progress. The session auto-completes at 90%.
Wire up GET /content/search?q= to a search bar. Results span classes, trainers, and categories.