#
Partner Portal API
Partner staff manage member access through voucher codes, track usage, and review billing. Most endpoints use Partner JWT authentication (no client API key needed). Voucher management endpoints require the client API key.
Who are partners?
Partners are organisations (gyms, corporates, resellers) that distribute access to a sTvOS client. They generate voucher codes, monitor member activity, and receive billing reports.
#
Authentication
Partner staff authenticate via dedicated endpoints. See Authentication > Partner Staff for login, refresh, and profile endpoints.
#
Dashboard
GET /partner/dashboard
Auth: Partner JWT
Get partner dashboard overview.
{
"success": true,
"data": {
"totalMembers": 250,
"activeMembers": 180,
"totalWatchTimeMinutes": 45000,
"totalClassesWatched": 1200,
"trends": {
"membersChange": "+12%",
"watchTimeChange": "+8%"
}
}
}
#
Voucher Management
Voucher endpoints require the X-API-Key header (client API key).
#
Generate Vouchers
POST /partner/vouchers
Generate one or more voucher codes. Maximum 500 per request.
{
"quantity": 50,
"prefix": "STUDIO",
"expiresAt": "2026-12-31T23:59:59Z"
}
{
"success": true,
"data": {
"vouchers": [
{
"id": 1,
"code": "STUDIO-A1B2C3",
"status": "active",
"expiresAt": "2026-12-31T23:59:59Z"
}
]
}
}
#
List Vouchers
GET /partner/vouchers
#
Revoke Voucher
DELETE /partner/vouchers/:id
Revoke an active voucher. Cannot revoke already-redeemed vouchers.
#
Export Vouchers
GET /partner/vouchers/export
Export vouchers as a CSV file. Optional status filter.
#
Voucher Statistics
GET /partner/vouchers/stats
{
"success": true,
"data": {
"total": 500,
"active": 200,
"redeemed": 250,
"expired": 30,
"revoked": 20,
"redemptionRate": 50.0
}
}
#
Member Management
Auth: Partner JWT
#
List Members
GET /partner/members
#
Member Detail
GET /partner/members/:id
Get detailed member information including viewing history and aggregate statistics.
#
Export Members
GET /partner/members/export
Export all members as a CSV file with activity data.
#
Analytics
GET /partner/analytics
Auth: Partner JWT
Get usage analytics including watch time by day, popular categories, popular classes, and aggregate totals.
#
Billing
Auth: Partner JWT
#
Billing Report
GET /partner/billing
Get billing report for a specific month showing active member count and member list.
#
Export Billing
GET /partner/billing/export
Export billing report as CSV with member details.
#
Content Strings
GET /partner/strings
PUT /partner/strings
Auth: Partner JWT
Manage client-facing content strings such as the About Us page and Privacy Policy. These strings are rendered as HTML in the mobile app.
#
Get Strings
GET /partner/strings
{
"success": true,
"data": {
"st_aboutus": "<h1>About Us</h1><p>Your about us content...</p>",
"st_privacypolicy": "<h1>Privacy Policy</h1><p>Your privacy policy...</p>"
}
}
#
Update Strings
PUT /partner/strings
Merges provided keys with existing strings. Only send the keys you want to update.
{
"st_aboutus": "<h1>About Us</h1><p>Updated content...</p>",
"st_privacypolicy": "<h1>Privacy Policy</h1><p>Updated policy...</p>"
}
{
"success": true,
"data": {
"st_aboutus": "<h1>About Us</h1><p>Updated content...</p>",
"st_privacypolicy": "<h1>Privacy Policy</h1><p>Updated policy...</p>"
}
}
The app fetches these strings via GET /app/strings (requires X-API-Key), which returns:
{
"success": true,
"data": [
{
"st_aboutus": "...",
"st_privacypolicy": "..."
}
]
}
#
Products
Auth: Partner JWT
Partners can create and manage affiliate products that are shown in the mobile app's store section. Each product has a name, description, image, price, and an external buy link.
#
List Products
GET /partner/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,
"createdAt": "2026-03-01T00:00:00Z",
"updatedAt": "2026-03-01T00:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 5,
"totalPages": 1
}
}
}
#
Get Product
GET /partner/products/:id
Get a single product by ID.
#
Create Product
POST /partner/products
{
"name": "Protein Powder",
"description": "Premium whey protein isolate",
"image": "https://example.com/image.jpg",
"price": "29.99",
"currency": "USD",
"externalUrl": "https://shop.example.com/protein",
"productType": "Supplements",
"featured": false,
"status": "draft",
"sortOrder": 0
}
#
Update Product
PUT /partner/products/:id
Send only the fields you want to update.
#
Delete Product
DELETE /partner/products/:id
Permanently delete a product.
#
App-Facing Product Endpoints
The mobile app accesses products via these client-scoped endpoints (requires X-API-Key, only returns active products):
#
Partner Integration Flow
During onboarding, a client is created for the partner with branding and features, API keys are provisioned, and partner staff accounts are set up.
Staff authenticate at POST /partner-auth/login and receive a JWT token.
Use POST /partner/vouchers to create voucher codes with optional prefix and expiry. Distribute codes to employees or members.
Each member receives a voucher code. The mobile app validates the code at POST /auth/voucher/validate then registers the user at POST /auth/register with the voucher code. The user is mapped to the partner's client.
The partner portal shows member activity via GET /partner/members, usage analytics via GET /partner/analytics, and billing via GET /partner/billing. All data exportable as CSV.
#
FAQ
Can a partner see individual member viewing history?
Yes. GET /partner/members/:id returns detailed member information including viewing history and aggregate statistics like total watch time and classes completed.
What happens when a voucher expires?
Expired vouchers cannot be used for registration. Users who already redeemed the voucher are not affected -- their accounts remain active. Partners can see expired vouchers in the list with status=expired.
How is billing calculated?
Billing is based on active member count for the specified month. GET /partner/billing returns the count and member list. The actual billing arrangement is managed outside the platform.