Last updated

How to do Tracking

This guide explains how to integrate the Jay tracking system into your application to monitor user interactions and deliver personalized content.

Tracking System Overview

The Jay tracking system enables the monitoring of user interactions and sessions to provide relevant content and enhance the user experience. Tracking sessions are used to correlate user actions across different API requests and provide analytics capabilities for understanding user behavior.

Key Concepts

  • Tracking Session: A unique session that tracks user interactions over a specific period.
  • Session ID: A unique identifier (in the cookie or header __Secure-jay_tracking) used to identify the session.
  • User ID: An optional identifier that identifies a logged-in user and can track them across multiple sessions.

Basic Flow

IntegratorJay Playout APIIf user rejects trackingRequest Tracking Session (optional userId)Response with Session ID for Cookie/HeaderStore session Id locallySubsequent API Requests with Session IDProcess Request with Session ContextDelete SessionDelete local session IdSubsequent API Requests with no Session IDProcess Request with no Session ContextIntegratorJay Playout API
  • Consent Required: Before tracking users, you need their explicit consent according to local privacy laws (GDPR in Europe, CCPA in California, etc.).
  • Anonymous Tracking: Without a User ID, sessions cannot be tracked across different user sessions.
  • Transparency: Inform users about what data is collected and how it is used.

Managing Tracking Sessions

1. Create a New Session

To initiate a new tracking session for analytics and user behavior tracking, use the following endpoint:

This creates a new tracking session with a unique ID and current timestamp, and sets it as both a cookie and header in the response.

Parameters:

  • user_id (optional): A user identifier to track users across multiple sessions

Example (without User ID):

curl -X POST "https://your-api-domain/v1/playouts/tracking/session" \
  -H "X-API-Key: your_api_key_here" \-i

Example (with User ID for registered users):

curl -X POST "https://your-api-domain/v1/playouts/tracking/session" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{"user_id": "user-123-xyz"}' \
     -i

The response includes:

  • A Set-Cookie header with the session ID
  • A custom __Secure-jay_tracking header with the session value (for clients that don't process cookies)
  • The session details in the response body

2. Retrieve an Existing Session

To retrieve an existing tracking session or verify if the client has an active valid session:

The API tries to retrieve the tracking session in this order:

  1. Cookie with name __Secure-jay_tracking
  2. Header with name __Secure-jay_tracking
curl -X GET "https://your-api-domain/v1/playouts/tracking/session" \
     -H "X-API-Key: your_api_key_here" \
     -H "Cookie: __Secure-jay_tracking=your_session_id" \
     -i

3. Delete a Tracking Session

To end a tracking session and stop the correlation of user actions across different API requests:

This removes the tracking session cookie from the client by sending appropriate cookie deletion headers.

curl -X DELETE "https://your-api-domain/v1/playouts/tracking/session" \
     -H "X-API-Key: your_api_key_here" \
     -H "Cookie: __Secure-jay_tracking=your_session_id" \
     -i

Note: This only affects the cookie, not any header values the client might be storing independently. Clients using header-based tracking should stop sending the tracking header after calling this endpoint.

Tracking in Browsers

In browsers, tracking sessions are preferably managed with cookies.

After creating a session, the API automatically sets a __Secure-jay_tracking cookie. This cookie:

  • Is HttpOnly (not accessible via JavaScript)
  • Is configured as SameSite=Lax or SameSite=Strict
  • Is Secure (only transmitted over HTTPS)
  • Has a limited lifespan (typically 24 hours by default)

JavaScript Example for Browser Applications:

async function createTrackingSession(userId = null) {
  const options = {
    method: 'POST',
    credentials: 'include', // Important for cookie handling
    headers: {
      'Content-Type': 'application/json',
      'x-jay-api-version': '2025-05-19', // Specify the API version
      'X-API-Key': 'your_api_key_here'
    }
  };
  
  // Add User ID if available
  if (userId) {
    options.body = JSON.stringify({ userId });
  }
  
  try {
    const response = await fetch('https://your-api-domain/v1/playouts/tracking/session', options);
    if (!response.ok) {
      throw new Error(`Error creating tracking session: ${response.status}`);
    }
    const sessionData = await response.json();
    console.log('Tracking session created:', sessionData);
    return sessionData;
  } catch (error) {
    console.error('Could not create tracking session:', error);
    return null;
  }
}

For cross-origin requests, you must:

  • Set credentials: 'include' in fetch requests
  • Ensure the server sends the appropriate CORS headers (Access-Control-Allow-Credentials: true and Access-Control-Allow-Origin with your domain)

Managing the Tracking Session Lifecycle

You can implement a complete session management flow:

// Create a new tracking session
async function createTracking(userId = null) {
  return await createTrackingSession(userId);
}

// Check if a user has an existing session
async function checkTrackingSession() {
  try {
    const response = await fetch('https://your-api-domain/v1/playouts/tracking/session', {
      credentials: 'include',
      headers: {
        'x-jay-api-version': '2025-05-19',
        'X-API-Key': 'your_api_key_here'
      }
    });
    
    if (response.ok) {
      return await response.json();
    }
    return null;
  } catch (error) {
    console.error('Error checking tracking session:', error);
    return null;
  }
}

// End a user's tracking session
async function endTrackingSession() {
  try {
    const response = await fetch('https://your-api-domain/v1/playouts/tracking/session', {
      method: 'DELETE',
      credentials: 'include',
      headers: {
        'x-jay-api-version': '2025-05-19',
        'X-API-Key': 'your_api_key_here'
      }
    });
    
    if (response.ok) {
      console.log('Tracking session deleted successfully');
      return true;
    }
    return false;
  } catch (error) {
    console.error('Error deleting tracking session:', error);
    return false;
  }
}

For platforms without cookie support (e.g., native apps, Smart TVs, Tizen):

Header-based Tracking Session

  1. Create a tracking session as described above.
  2. Extract the session ID from the response.
  3. Add a __Secure-jay_tracking header with the session ID to all subsequent requests.

Example for Requests without Cookies:

// Create a session and store the ID
async function setupTracking(userId = null) {
  const options = {
    method: 'POST',
    headers: { 
      'Content-Type': 'application/json',
      'x-jay-api-version': '2025-05-19',
      'X-API-Key': 'your_api_key_here'
    }
  };
  
  if (userId) {
    options.body = JSON.stringify({ userId });
  }
  
  const response = await fetch('https://your-api-domain/v1/playouts/tracking/session', options);
  const data = await response.json();
  
  // Extract the session ID from the response
  const sessionId = data.session_id;
  
  // Store the session ID locally (e.g., localStorage, AsyncStorage, etc.)
  saveSessionId(sessionId);
  
  return sessionId;
}

// Example for a request with the stored session ID
async function fetchWithTracking(url) {
  const sessionId = getStoredSessionId(); // Implement this function according to your storage method
  
  const response = await fetch(url, {
    headers: {
      '__Secure-jay_tracking': sessionId,
      'x-jay-api-version': '2025-05-19',
      'X-API-Key': 'your_api_key_here'
    }
  });
  
  return response.json();
}

// Example to delete a tracking session
async function deleteTrackingSession() {
  const sessionId = getStoredSessionId();
  
  const response = await fetch('https://your-api-domain/v1/playouts/tracking/session', {
    method: 'DELETE',
    headers: {
      '__Secure-jay_tracking': sessionId,
      'x-jay-api-version': '2025-05-19',
      'X-API-Key': 'your_api_key_here'
    }
  });
  
  if (response.ok) {
    // Clear the stored session ID
    clearSessionId();
    return true;
  }
  
  return false;
}

Native App Implementation Example

Here's a simplified example for Android using Kotlin and OkHttp:

// Setup a tracking session
fun setupTracking(userId: String? = null): String? {
    val client = OkHttpClient()
    val requestBuilder = Request.Builder()
        .url("https://your-api-domain/v1/playouts/tracking/session")
        .header("x-jay-api-version", "2025-05-19")
        .header("X-API-Key", "your_api_key_here")
    
    if (userId != null) {
        val json = "{\"userId\":\"$userId\"}"
        val requestBody = json.toRequestBody("application/json".toMediaType())
        requestBuilder.post(requestBody)
    } else {
        requestBuilder.post("".toRequestBody(null))
    }
    
    val request = requestBuilder.build()
    
    client.newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            val jsonData = JSONObject(response.body!!.string())
            val sessionId = jsonData.getString("session_id")
            
            // Store session ID in shared preferences or secure storage
            saveSessionIdToPreferences(sessionId)
            
            return sessionId
        }
    }
    
    return null
}

Tracking Session Data Structure

The tracking session contains the following information:

{
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "start_time": "2023-01-15T14:30:24.123456",
  "source": "jay.api.playout.1.0.0",
  "user_id": "user-123456"  // Only present if provided
}

Fields:

  • session_id: Unique identifier for the tracking session
  • start_time: ISO 8601 formatted timestamp of when the session started
  • source: Identifier of the system or API version that created this session
  • user_id: Optional identifier to track users across multiple sessions

API Versioning

To use a specific version of the API, include the x-jay-api-version header in your requests. If not specified, the latest version is used (currently "2025-05-19").

The response header x-jay-api-version returns the version the request was processed with.

Best Practices

  • Session Persistence: Store the session ID securely on devices without cookie support.
  • Error Handling: Implement mechanisms to handle failed tracking requests.
  • Tracking Optimization: Minimize the number of tracking calls to reduce network load.
  • User Consent: Implement a proper consent system according to local privacy laws.
  • Cross-Session Tracking: Only use user_id when you have explicit consent from users.
  • Cookie Alternatives: For environments without cookie support, consistently use the header-based approach.
  • Session Cleanup: End sessions when they're no longer needed to prevent resource waste.

API Reference

Complete documentation of tracking endpoints:

Support

For any questions or support needs during implementation, please contact the Jay Support Team.

Best Practices

  • Session Persistence: Store the session ID securely on devices without cookie support.
  • Error Handling: Implement mechanisms to handle failed tracking requests.