# Partner Portal API

Voucher management, member oversight, analytics, and billing for partners.

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.


# 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

Parameter Type Description
status string Filter: active, redeemed, expired, revoked
search string Search by voucher code
page number Page number
limit number Results per page

# 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

Parameter Type Description
search string Search by name or email
status string Filter: active, inactive
sort string Sort field
page number Page number
limit number Results per page

# 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.

Parameter Type Description
period string Predefined: week, month, quarter
startDate string Custom start date (YYYY-MM-DD)
endDate string Custom end date (YYYY-MM-DD)

# Billing

Auth: Partner JWT

# Billing Report GET /partner/billing

Get billing report for a specific month showing active member count and member list.

Parameter Type Description
month number Month (1-12)
year number Year

# Export Billing GET /partner/billing/export

Export billing report as CSV with member details.

Parameter Type Description
month number Month (1-12)
year number Year

# 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

Parameter Type Description
status string Filter: active, draft, archived
productType string Filter by product type
search string Search by name or description
sort string Sort: newest, oldest, price_asc, price_desc, sort_order
page number Page number
limit number Results per page (max 50)
{
  "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
}
Field Type Required Description
name string Yes Product name
description string No Product description
image string No Image URL
price string No Price (decimal)
currency string No Currency code (default: USD)
externalUrl string No External buy link
productType string No Free-text category (e.g., Supplements, Apparel)
featured boolean No Whether product is featured (default: false)
status string No draft, active, or archived (default: draft)
sortOrder number No Display order (default: 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):

Method Path Description
GET /products List active products (pagination, filter, search, sort)
GET /products/:id Get product detail
GET /products/types List product types with counts

# 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