Skip to content

Subscriber Management

Subscribers are the end users of your IPTV service who get access to watch TV channels. The Catena system provides flexible subscriber management, their channel package subscriptions, and access control.

What is a Subscriber

A subscriber in Catena is a user account that has access to watch channels through connected packages.

Key capabilities:

  • SMS authentication — primary login method for subscribers via code sent to phone
  • Subscription management — connecting and disconnecting channel packages
  • Access control — automatic channel access management based on subscriptions
  • Playback tokens — unique tokens for authorization during viewing
  • Activity monitoring — tracking viewing sessions and subscriber activity

Typical workflow:

  1. Create subscriber account with phone number
  2. Connect channel packages to subscriber
  3. Subscriber receives SMS with login code for the app
  4. After login, subscriber gets access to all channels from their packages
  5. System automatically manages access rights based on active subscriptions

Main Subscriber Parameters

Technical Parameters

Subscriber ID

  • Automatically generated when creating a subscriber
  • Format: base64-encoded Snowflake ID with +/= replaced by -_.
  • Example: aKl9SW3AAAE.
  • Used for programmatic access via API
  • Not editable after creation

Portal ID

  • Identifier of the portal the subscriber belongs to
  • Automatically set upon creation
  • Subscriber can only access channels and packages from their portal

Personal Information

Subscriber Name

  • Display name or user identifier
  • Can be full name, nickname, or identifier from external system
  • Used for display in management interface
  • Examples: "John Doe", "user123", "Apartment 42"

Phone Number (Phone)

  • Subscriber's phone number without country code
  • Used for SMS authentication — the primary login method
  • Digits only, no spaces or special characters
  • Validation pattern: ^[0-9]*$
  • Examples: 2345678901, 9161234567

Country Code (Phone Country Code)

  • Phone country code without plus sign
  • Used together with phone field to form complete number
  • Digits only
  • Validation pattern: ^[0-9]*$
  • Examples: 1 (USA), 44 (UK), 7 (Russia)

Complete phone number is formed as: +{phoneCountryCode}{phone}

Example: phoneCountryCode: "1" + phone: "2345678901" = +12345678901

Access Parameters

Playback Token

  • Unique token for authorization during video playback
  • Generated automatically by the system
  • Used by streaming server to verify access rights
  • Transmitted to app after successful authentication
  • Can be regenerated if needed

Package List (Packages)

  • Array of channel package identifiers the subscriber is connected to
  • Read-only field — displays current active subscriptions
  • Updated automatically when packages are connected/disconnected
  • Determines which channels the subscriber has access to
  • Example: ["pKl9SW3AAAE.", "bKl9SW3AAAE."]

Subscriber Authentication

SMS Login (Primary Method)

Catena uses SMS authentication as the primary login method for subscribers. This provides:

  • Ease of use — no need to remember passwords
  • Security — one-time codes tied to phone
  • Convenience — quick registration and login
  • Fraud protection — phone as authentication factor

SMS login process:

  1. Subscriber enters phone number in the app
  2. System sends SMS with one-time code to the specified number
  3. Subscriber enters code from SMS in the app
  4. System verifies code and issues access token
  5. Subscriber gets access to watch channels from their packages

Important: Phone number is the unique identifier of the subscriber in the system. Ensure numbers are entered correctly when creating accounts.

Automatic Subscriber Creation

The system can automatically create subscriber accounts on first login attempt via SMS if this feature is enabled in portal settings. This allows for self-service user registration.

Creating a Subscriber

Via Web Interface

  1. Open the "Subscribers" section in the Catena control panel
  2. Click the "Create Subscriber" button
  3. Fill in required fields:

  4. Name — subscriber name or identifier

  5. Phone Country Code — country code (e.g., 1 for USA)
  6. Phone — phone number without country code

  7. Save the subscriber

  8. Connect packages via subscription management section

After creation, the subscriber will receive a unique ID and can login to the system via SMS.

Via Management API

curl -X POST https://your-catena-domain.com/tv-management/api/v1/subscribers \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "phoneCountryCode": "1",
    "phone": "2345678901"
  }'

Response:

{
  "subscriberId": "sKl9SW3AAAE.",
  "portalId": "pKl9SW3AAAE.",
  "name": "John Doe",
  "phoneCountryCode": "1",
  "phone": "2345678901",
  "playback_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "packages": []
}

Viewing Subscriber List

Via Web Interface

The "Subscribers" section displays a table with all portal subscribers:

  • Name — subscriber name or identifier
  • Phone — complete phone number
  • Packages — number of connected packages
  • Last Activity — time of last login or viewing
  • Status — active/blocked
  • Actions — edit, package management, and delete buttons

Via Management API

Get list of all subscribers:

curl -X GET https://your-catena-domain.com/tv-management/api/v1/subscribers \
  -H "X-Auth-Token: your-api-key"

Response:

{
  "subscribers": [
    {
      "subscriberId": "sKl9SW3AAAE.",
      "portalId": "pKl9SW3AAAE.",
      "name": "John Doe",
      "phoneCountryCode": "1",
      "phone": "2345678901",
      "playback_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "packages": ["pKl9SW3AAAE.", "bKl9SW3AAAE."]
    },
    {
      "subscriberId": "tKl9SW3AAAE.",
      "portalId": "pKl9SW3AAAE.",
      "name": "Jane Smith",
      "phoneCountryCode": "1",
      "phone": "2345678902",
      "playback_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "packages": ["pKl9SW3AAAE."]
    }
  ],
  "next": "cursor-for-next-page"
}

Pagination:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/subscribers?cursor=cursor-for-next-page" \
  -H "X-Auth-Token: your-api-key"

Getting Subscriber Information

Via Management API

curl -X GET https://your-catena-domain.com/tv-management/api/v1/subscribers/sKl9SW3AAAE. \
  -H "X-Auth-Token: your-api-key"

Response: Similar to subscriber object from the list.

Editing a Subscriber

Via Web Interface

  1. Open the subscriber list
  2. Find the needed subscriber and click the "Edit" button
  3. Change parameters:

  4. Name — subscriber name

  5. Phone Country Code — country code
  6. Phone — phone number

  7. Save changes

Note: When changing phone number, subscriber will need to re-authenticate via SMS with the new number.

Via Management API

curl -X PUT https://your-catena-domain.com/tv-management/api/v1/subscribers/sKl9SW3AAAE. \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Michael Doe",
    "phoneCountryCode": "1",
    "phone": "2345678901"
  }'

Managing Package Subscriptions

Connecting Package to Subscriber

Via Web Interface:

  1. Open subscriber card
  2. Go to "Packages" section
  3. Click "Add Package"
  4. Select package from available list
  5. Confirm addition

The subscriber immediately gets access to all channels from the added package.

Via Management API:

curl -X POST https://your-catena-domain.com/tv-management/api/v1/packages-subscribers \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriberId": "sKl9SW3AAAE.",
    "packageId": "pKl9SW3AAAE."
  }'

Response:

{
  "subscriberId": "sKl9SW3AAAE.",
  "packageId": "pKl9SW3AAAE.",
  "portalId": "pKl9SW3AAAE."
}

Disconnecting Package from Subscriber

Via Web Interface:

  1. Open subscriber card
  2. Go to "Packages" section
  3. Find package in active list
  4. Click "Remove"
  5. Confirm disconnection

The subscriber immediately loses access to all channels from the disconnected package.

Via Management API:

curl -X DELETE https://your-catena-domain.com/tv-management/api/v1/packages-subscribers \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriberId": "sKl9SW3AAAE.",
    "packageId": "pKl9SW3AAAE."
  }'

Bulk Subscription Management

For bulk connecting or disconnecting packages use loops or scripts. Example of adding a package to multiple subscribers:

#!/bin/bash
SUBSCRIBERS=("sKl9SW3AAAE." "tKl9SW3AAAE." "uKl9SW3AAAE.")
PACKAGE_ID="pKl9SW3AAAE."

for SUBSCRIBER_ID in "${SUBSCRIBERS[@]}"; do
  curl -X POST https://your-catena-domain.com/tv-management/api/v1/packages-subscribers \
    -H "X-Auth-Token: your-api-key" \
    -H "Content-Type: application/json" \
    -d "{
      \"subscriberId\": \"$SUBSCRIBER_ID\",
      \"packageId\": \"$PACKAGE_ID\"
    }"
done

Deleting a Subscriber

Via Web Interface

  1. Open the subscriber list
  2. Find the subscriber to delete
  3. Click "Delete" button
  4. Confirm deletion

Warning: When deleting a subscriber:

  • Account will be completely deleted
  • All package subscriptions will be cancelled
  • Viewing history will be preserved for analytics
  • Subscriber will lose access to watch channels
  • Account recovery will be impossible

Via Management API

curl -X DELETE https://your-catena-domain.com/tv-management/api/v1/subscribers/sKl9SW3AAAE. \
  -H "X-Auth-Token: your-api-key"

Monitoring Subscriber Activity

Viewing Playback Sessions

Catena automatically registers all channel viewing sessions by subscribers. This allows tracking activity, channel popularity, and identifying issues.

Get sessions for specific subscriber:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?subscriberId=sKl9SW3AAAE." \
  -H "X-Auth-Token: your-api-key"

Get only active sessions:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?subscriberId=sKl9SW3AAAE.&active=true" \
  -H "X-Auth-Token: your-api-key"

Filter by time:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?subscriberId=sKl9SW3AAAE.&opened_at_gte=1714233600&opened_at_lt=1714320000" \
  -H "X-Auth-Token: your-api-key"

Response:

{
  "sessions": [
    {
      "sessionId": "sessKl9SW3AAAE.",
      "subscriberId": "sKl9SW3AAAE.",
      "channelId": "chKl9SW3AAAE.",
      "channelName": "sport1",
      "portalId": "pKl9SW3AAAE.",
      "openedAt": 1714233600,
      "closedAt": 1714237200,
      "active": false,
      "bytes": 5242880000,
      "ip": "192.168.1.100",
      "userAgent": "VLC/3.0.16"
    }
  ],
  "next": "cursor-for-next-page"
}

Operations Log

All changes in subscriber accounts (creation, deletion, subscription changes) are recorded in the operations log.

Get operations for a subscriber:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/operations?subscriberId=sKl9SW3AAAE." \
  -H "X-Auth-Token: your-api-key"

Filter by operation type:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/operations?subscriberId=sKl9SW3AAAE.&type=createPackageSubscriber" \
  -H "X-Auth-Token: your-api-key"

Response:

{
  "operations": [
    {
      "operationId": "opKl9SW3AAAE.",
      "type": "createSubscriber",
      "subscriberId": "sKl9SW3AAAE.",
      "portalId": "pKl9SW3AAAE.",
      "createdAt": "2024-10-16T10:00:00Z",
      "payload": {
        "name": "John Doe",
        "phone": "+12345678901"
      }
    },
    {
      "operationId": "opKl9SW3AAAB.",
      "type": "createPackageSubscriber",
      "subscriberId": "sKl9SW3AAAE.",
      "packageId": "pKl9SW3AAAE.",
      "portalId": "pKl9SW3AAAE.",
      "createdAt": "2024-10-16T10:05:00Z",
      "payload": {
        "packageId": "pKl9SW3AAAE."
      }
    }
  ],
  "next": "cursor-for-next-page"
}

Typical Use Cases

Creating New Subscriber with Basic Package

Task: Register a new subscriber and connect basic package

Steps:

  1. Create subscriber account via API
  2. Get subscriberId from response
  3. Connect basic package via packages-subscribers API
  4. Subscriber receives SMS to login to app
  5. After login, subscriber sees channels from basic package

Example script:

#!/bin/bash

# 1. Create subscriber
RESPONSE=$(curl -s -X POST https://your-catena-domain.com/tv-management/api/v1/subscribers \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "New Subscriber",
    "phoneCountryCode": "1",
    "phone": "2345678901"
  }')

# 2. Extract subscriber ID
SUBSCRIBER_ID=$(echo $RESPONSE | jq -r '.subscriberId')

# 3. Connect basic package
curl -X POST https://your-catena-domain.com/tv-management/api/v1/packages-subscribers \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d "{
    \"subscriberId\": \"$SUBSCRIBER_ID\",
    \"packageId\": \"basic-package-id\"
  }"

echo "Subscriber created with ID: $SUBSCRIBER_ID"

Upgrading Subscriber to Premium Package

Task: Move subscriber from basic to premium package

Option 1: Add premium to basic

# Subscriber will get access to channels from both packages
curl -X POST https://your-catena-domain.com/tv-management/api/v1/packages-subscribers \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriberId": "sKl9SW3AAAE.",
    "packageId": "premium-package-id"
  }'

Option 2: Replace basic with premium

# First disconnect basic
curl -X DELETE https://your-catena-domain.com/tv-management/api/v1/packages-subscribers \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriberId": "sKl9SW3AAAE.",
    "packageId": "basic-package-id"
  }'

# Then connect premium
curl -X POST https://your-catena-domain.com/tv-management/api/v1/packages-subscribers \
  -H "X-Auth-Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriberId": "sKl9SW3AAAE.",
    "packageId": "premium-package-id"
  }'

Integration with Billing System

Task: Automatically manage subscriptions based on payments

Concept:

  1. Billing system tracks subscriber payments
  2. On successful payment, billing calls Catena API to connect package
  3. On subscription expiry, billing disconnects package via API
  4. Catena automatically manages channel access

Example webhook from billing:

import requests

def on_payment_success(subscriber_phone, package_name):
    # 1. Find subscriber by phone
    subscribers = requests.get(
        f"https://catena.example.com/tv-management/api/v1/subscribers",
        headers={"X-Auth-Token": "your-api-key"}
    ).json()

    subscriber = next(
        s for s in subscribers['subscribers']
        if f"+{s['phoneCountryCode']}{s['phone']}" == subscriber_phone
    )

    # 2. Connect paid package
    requests.post(
        "https://catena.example.com/tv-management/api/v1/packages-subscribers",
        headers={"X-Auth-Token": "your-api-key"},
        json={
            "subscriberId": subscriber['subscriberId'],
            "packageId": get_package_id(package_name)
        }
    )

def on_subscription_expired(subscriber_phone, package_name):
    # Similar, but via DELETE
    pass

Bulk Subscriber Migration

Task: Migrate subscribers from old system to Catena

Steps:

  1. Export subscriber data from old system (CSV/JSON)
  2. Create bulk import script via API
  3. Create accounts in Catena
  4. Connect corresponding packages
  5. Notify subscribers about transition to new system

Example import script:

import csv
import requests

API_URL = "https://catena.example.com/tv-management/api/v1"
API_KEY = "your-api-key"

def import_subscribers(csv_file):
    with open(csv_file, 'r') as f:
        reader = csv.DictReader(f)
        for row in reader:
            # Create subscriber
            response = requests.post(
                f"{API_URL}/subscribers",
                headers={"X-Auth-Token": API_KEY},
                json={
                    "name": row['name'],
                    "phoneCountryCode": row['country_code'],
                    "phone": row['phone']
                }
            )

            subscriber_id = response.json()['subscriberId']

            # Connect packages
            for package_id in row['packages'].split(','):
                requests.post(
                    f"{API_URL}/packages-subscribers",
                    headers={"X-Auth-Token": API_KEY},
                    json={
                        "subscriberId": subscriber_id,
                        "packageId": package_id.strip()
                    }
                )

            print(f"Imported: {row['name']} ({subscriber_id})")

import_subscribers('subscribers.csv')

Best Practices

Managing Phone Numbers

Recommendations:

  • Input validation — verify number format before sending to API
  • Uniqueness — one phone number = one subscriber
  • International format — store country code and number separately
  • Number change — require confirmation via SMS to new number
  • Deactivation — promptly update data when operator disconnects number

Security

Protecting playback tokens:

  • Don't transmit playback_token to third parties
  • Use HTTPS for all API requests
  • Regularly update tokens if compromise suspected
  • Log access attempts with invalid tokens

Access control:

  • Limit number of simultaneous sessions per subscriber
  • Track suspicious activity (different IPs, different devices)
  • Block subscribers upon fraud detection

Subscription Management

Recommendations:

  • Smooth transition — notify about subscription changes in advance
  • Automation — integrate with billing for automatic management
  • Free packages — use portal free packages for demo content
  • Trial periods — temporarily connect premium packages for trial
  • Change history — use operations log for audit

Subscriber Communication

When to send notifications:

  • Upon account creation
  • Upon subscription changes
  • Upon paid period expiry
  • Upon phone number change
  • Upon access blocking

Communication channels:

  • SMS — for login codes and critical notifications
  • Email — for informational newsletters (if available in your system)
  • Push notifications — via mobile app
  • In-app messages — upon app login

Troubleshooting

Subscriber Cannot Login via SMS

Possible causes:

  • Phone number incorrectly specified during registration
  • SMS not delivered (carrier issues)
  • Code from SMS expired
  • Phone number blocked in SMS gateway

Solution:

  1. Check phone number in subscriber account
  2. Ensure number format is correct (+country_code + number)
  3. Check SMS gateway logs for message delivery
  4. Try sending SMS again
  5. If SMS doesn't arrive — check SMS gateway balance and settings

Subscriber Doesn't See Channels

Possible causes:

  • Subscriber has no connected packages
  • Packages contain no channels
  • Playback token expired or invalid
  • Technical issues with streaming server

Solution:

  1. Check package list in subscriber's packages field
  2. Ensure packages contain channels
  3. Verify channels are active and working
  4. Regenerate playback_token if needed
  5. Check streaming server logs

Errors When Connecting Package

Possible causes:

  • Package already connected to subscriber
  • Incorrect packageId or subscriberId specified
  • Package and subscriber belong to different portals
  • Package doesn't exist or deleted

Solution:

  1. Check subscriber's current packages via GET /subscribers/{id}
  2. Ensure package and subscriber IDs are correct
  3. Verify package exists via GET /packages/{id}
  4. Ensure portalId matches for package and subscriber

Duplicate Phone Numbers

Problem: Attempt to create subscriber with existing number

Solution:

  • API should return error when creating duplicate
  • Check for subscriber with such number before creation
  • Use UPDATE instead of CREATE for existing subscribers
  • Implement phone number search in your interface

See Also