Tracking sessions are used to correlate user actions across different API requests and provide analytics capabilities for understanding user behavior.
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.
| 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.
- 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.
- 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.
To initiate a new tracking session for analytics and user behavior tracking, use the following endpoint:
- API Endpoint:
POST /playouts/tracking/session
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.
user_id(optional): A user identifier to track users across multiple sessions
curl -X POST "https://your-api-domain/v1/playouts/tracking/session" \
-H "X-API-Key: your_api_key_here" \-icurl -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"}' \
-iThe response includes:
- A
Set-Cookieheader with the session ID - A custom
__Secure-jay_trackingheader with the session value (for clients that don't process cookies) - The session details in the response body
To retrieve an existing tracking session or verify if the client has an active valid session:
- API Endpoint:
GET /playouts/tracking/session
The API tries to retrieve the tracking session in this order:
- Cookie with name
__Secure-jay_tracking - 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" \
-iTo end a tracking session and stop the correlation of user actions across different API requests:
- API Endpoint:
DELETE /playouts/tracking/session
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" \
-iNote: 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.
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=LaxorSameSite=Strict - Is
Secure(only transmitted over HTTPS) - Has a limited lifespan (typically 24 hours by default)
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: trueandAccess-Control-Allow-Originwith your domain)
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):
- Create a tracking session as described above.
- Extract the session ID from the response.
- Add a
__Secure-jay_trackingheader with the session ID to all subsequent requests.
// 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;
}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
}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 sessionstart_time: ISO 8601 formatted timestamp of when the session startedsource: Identifier of the system or API version that created this sessionuser_id: Optional identifier to track users across multiple sessions
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.
- 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_idwhen 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.
Complete documentation of tracking endpoints:
POST /playouts/tracking/session- Create a new tracking sessionGET /playouts/tracking/session- Retrieve an existing sessionDELETE /playouts/tracking/session- Delete a tracking session
Support
For any questions or support needs during implementation, please contact the Jay Support Team.
- Session Persistence: Store the session ID securely on devices without cookie support.
- Error Handling: Implement mechanisms to handle failed tracking requests.