# How to do Tracking Tracking sessions are used to correlate user actions across different API requests and provide analytics capabilities for understanding user behavior. ## Tracking System Overview As the tracking doesn't store personal data, it can be used without user consent. But if the user has agreed to tracking, a tracking session should be created with the User ID to correlate user actions across different API requests. ## Tracking Scenarios Matrix | Scenario | User Logged In | User Agreed | Session Tracking | Set User ID | | --- | --- | --- | --- | --- | | Guest user (declined) | ❌ | ❌ | ✅ * | ❌ | | Guest user (agreed) | ❌ | ❌ | ✅ | ❌ | | Logged in user (no consent) | ✅ | ❌ | ✅ | ❌ | | Logged in user (agreed) | ✅ | ✅ | ✅ | ✅ | * A session can be created, but without a User ID, it cannot be tracked across different sessions and no personal data is stored. ### 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 ```mermaid sequenceDiagram participant IA as Integrator participant JP as Jay Playout API IA-->>JP: Request Tracking Session (optional userId) JP-->>IA: Response with Session ID for Cookie/Header IA->>IA: Store session Id locally IA->>JP: Subsequent API Requests with Session ID JP->>IA: Process Request with Session Context note over IA, JP: If user rejects tracking IA ->>JP: Delete Session IA->>IA: Delete local session Id IA-->>JP: Subsequent API Requests with no Session ID JP-->>IA: Process Request with no Session Context ``` ### Privacy and Legal Requirements - **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: - **API Endpoint**: [`POST /playouts/tracking/session`](/apis/playout/latest/openapi#operation/api_create_tracking_session_playouts_tracking_session_post) 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): ```bash 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): ```bash 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: - **API Endpoint**: [`GET /playouts/tracking/session`](/apis/playout/latest/openapi#operation/api_get_tracking_session_from_header_playouts_tracking_session_get) 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` ```bash 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: - **API Endpoint**: [`DELETE /playouts/tracking/session`](/apis/playout/latest/openapi#operation/api_delete_tracking_session_playouts_tracking_session_delete) This removes the tracking session cookie from the client by sending appropriate cookie deletion headers. ```bash 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. ### Cookie Integration 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: ```javascript 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; } } ``` ### CORS Cookie Management 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: ```javascript // 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; } } ``` ## Tracking without Cookie Features 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: ```javascript // 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: ```kotlin // 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: ```json { "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: - [`POST /playouts/tracking/session`](/apis/playout/latest/openapi#operation/api_create_tracking_session_playouts_tracking_session_post) - Create a new tracking session - [`GET /playouts/tracking/session`](/apis/playout/latest/openapi#operation/api_get_tracking_session_from_header_playouts_tracking_session_get) - Retrieve an existing session - [`DELETE /playouts/tracking/session`](/apis/playout/latest/openapi#operation/api_delete_tracking_session_playouts_tracking_session_delete) - Delete a tracking session Support For any questions or support needs during implementation, please contact the [Jay Support Team](mailto:support@transfermedia.de). # Best Practices - **Session Persistence**: Store the session ID securely on devices without cookie support. - **Error Handling**: Implement mechanisms to handle failed tracking requests.