# How to fetch Data from the Playout API This guide provides a step-by-step walkthrough on how to fetch playout data, such as episode information and content groups, using the Jay Playout API. This process typically involves initiating a tracking session, identifying the specific episode you're interested in, and then fetching detailed data for that episode. ## Prerequisites Before you begin, ensure you have the following: - `playoutId`: This is a unique identifier for the streaming platform, which you should receive from Jay. - `episodeId`: The internal identifier for the episode you want to fetch data for. The `episodeId` can be defined by the streaming platform as a custom asset ID in the Jay curator. The Playout API will resolve this to the internal episode ID. Alternatively the `episodeId` can be retrieved by fetching the list of episodes for a given `playoutId` and searching for the desired episode by its name or other attributes. See the "First-Steps Guide" below for more details. ## Content Structure The content in the Jay marketplace is structured in multiple ways. Here are two common options, that can be combined or used separately: - **Menu Based Content**: This is typically used for main menus or navigation sections, where content is grouped by categories or themes. The content stays the same across the whole episode, and is used to navigate through the content. - **Time Based Content**: This is used show different content depending on the current time code of the episode. This is useful for interactive content, where the user can pause the video and explore different items related to the current scene or time code. Menu Based Content Menu based content structure Time Based Content Time based content structure ## First-Steps Guide ### 1. Obtain a Tracking Session A tracking session is used to correlate user actions and gather analytics. You should initiate a new session or retrieve an existing one. - To **initiate a new session**, make a POST request. The API will respond with session details and attempt to set a `__Secure-jay_tracking` cookie. - To **retrieve an existing session** (if the client might already have one), make a GET request. The API checks for the session in cookies or headers. Read more about tracking in the [How to do tracking Guide](/platform/how-to/do-tracking). ### 2. Find the `episodeId` Once you have a tracking session, you need to find the internal `episodeId` for the desired `episodeName`. - Fetch the list of all available episodes for your `playoutId`. - Iterate through the list on the client-side to find the episode that matches your `episodeName` and extract its `id` (which is the `episodeId`). **API Endpoint:** - [`GET /playouts/{playoutId}/episodes`](/apis/playout/latest/openapi#operation/api_get_playout_episodes_playouts__playoutId__episodes_get) **Example (Fetch Episodes):** Replace `{playoutId}` with your actual playout ID. ```bash curl -X GET "https://your-api-domain/v1/playouts/{playoutId}/episodes" \ -H "X-API-Key: your_api_key_here" \ -H "Cookie: __Secure-jay_tracking=your_session_value_here" # or -H "__Secure-jay_tracking: your_session_value_here" ``` **Example (Client-side JavaScript to find `episodeId`):** ```javascript async function findEpisodeId(playoutId, episodeName, trackingSessionValue) { const response = await fetch(`/v1/playouts/${playoutId}/episodes`, { headers: { // Choose one: Cookie or custom header 'Cookie': `__Secure-jay_tracking=${trackingSessionValue}`, 'X-API-Key': 'your_api_key_here' // '__Secure-jay_tracking': trackingSessionValue } }); if (!response.ok) { console.error("Failed to fetch episodes:", await response.text()); return null; } const episodes = await response.json(); // Assuming response is an array of episode objects // The actual structure of an episode object might vary. // Consult the 'PlayoutEpisodeEntry' schema in /apis/playout/@latest/openapi.json. // Let's assume each episode object has 'name' and 'id' properties. const targetEpisode = episodes.find(ep => ep.name === episodeName); // Adjust 'ep.name' if property is different if (targetEpisode) { return targetEpisode.id; // Adjust 'ep.id' if property is different } else { console.error(`Episode with name "${episodeName}" not found.`); return null; } } // Usage: // const playoutId = "your_playout_id"; // const episodeName = "The Pilot Episode"; // const trackingValue = "retrieved_session_value"; // findEpisodeId(playoutId, episodeName, trackingValue).then(episodeId => { // if (episodeId) { // console.log("Found episodeId:", episodeId); // // Proceed to next steps // } // }); ``` ### 3. Fetch detailed Episode Information With the `playoutId` and the retrieved `episodeId`, you can now fetch comprehensive details for that specific episode. **API Endpoint:** - [`GET /playouts/{playoutId}/episodes/{episodeId}`](/apis/playout/latest/openapi#operation/api_get_playout_episodes_playouts__playoutId__episodes__episodeId__get) **Example (Fetch Episode Details):** Replace `{playoutId}` and `{episodeId}` with actual values. ```bash curl -X GET "https://your-api-domain/v1/playouts/{playoutId}/episodes/{episodeId}" \ -H "X-API-Key: your_api_key_here" \ -H "Cookie: __Secure-jay_tracking=your_session_value_here" ``` The response will contain detailed information about the episode, as defined by the `PlayoutEpisode` schema. ### 4. Fetch Episode Groups (e.g., for Main Menu) To construct UI elements like a main menu or categorized content sections, you can fetch groups associated with the episode. - Fetch all groups for the episode. - On the client-side, you will need to filter or interpret these groups to build your desired UI. For example, a group intended for a "main menu" might be identified by a specific `name`, `type`, or a custom attribute within its properties (e.g., a flag like `isMainMenu: true` if such a convention exists in your data). Consult the `PlayoutGroup` schema and your content curation guidelines. **API Endpoint:** - [`GET /playouts/{playoutId}/episodes/{episodeId}/groups`](/apis/playout/latest/openapi#operation/api_collect_playout_data_playouts__playoutId__episodes__episodeId__groups_get) **Example (Fetch Episode Groups):** Replace `{playoutId}` and `{episodeId}` with actual values. ```bash curl -X GET "https://your-api-domain/v1/playouts/{playoutId}/episodes/{episodeId}/groups" \ -H "X-API-Key: your_api_key_here" \ -H "Cookie: __Secure-jay_tracking=your_session_value_here" ``` **Example (Client-side JavaScript to identify main menu groups):** ```javascript async function getMainMenuGroups(playoutId, episodeId, trackingSessionValue) { const response = await fetch(`/v1/playouts/${playoutId}/episodes/${episodeId}/groups`, { headers: { 'Cookie': `__Secure-jay_tracking=${trackingSessionValue}`, 'X-API-Key': 'your_api_key_here' } }); if (!response.ok) { console.error("Failed to fetch groups:", await response.text()); return []; } const groups = await response.json(); // Assuming response is an array of group objects // Example: Filter groups that are designated for the main menu. // This logic depends on how main menu groups are identified in your data // (e.g., by name, a specific property, or type). // Refer to the 'PlayoutGroup' schema. const mainMenuGroups = groups.filter(group => { // return group.name === "Main Menu" || (group.attributes && group.attributes.isMainMenu === true); // Adjust the condition above based on your actual data structure for identifying main menu groups. // For this example, let's assume a group named "Main Menu" is the target. return group.name === "Main Menu"; // Adjust 'group.name' if property is different }); return mainMenuGroups; } // Usage: // getMainMenuGroups(playoutId, episodeId, trackingValue).then(menuGroups => { // console.log("Main menu groups:", menuGroups); // // Use menuGroups to build your UI // }); ``` ## Further Data Fetching The Playout API provides many other endpoints to fetch specific data related to an episode, such as: - Products: [`/playouts/{playoutId}/episodes/{episodeId}/products`](/apis/playout/latest/openapi#tag/Episode-items/paths/~1playouts~1%7BplayoutId%7D~1episodes~1%7BepisodeId%7D~1products/get) - Actors: [`/playouts/{playoutId}/episodes/{episodeId}/actors`](/apis/playout/latest/openapi#tag/Episode-items/paths/~1playouts~1%7BplayoutId%7D~1episodes~1%7BepisodeId%7D~1actors/get) - Scenes: [`/playouts/{playoutId}/episodes/{episodeId}/scenes`](/apis/playout/latest/openapi#tag/Episode-items/paths/~1playouts~1%7BplayoutId%7D~1episodes~1%7BepisodeId%7D~1scenes/get) - And more (chapters, locations, costumes, etc.) Refer to the [Playout API documentation](/apis/playout/latest/openapi) for a complete list of available endpoints and their details. Remember to replace placeholders like `{playoutId}`, `{episodeId}`, and `{productId}` with actual values in your requests. Support For any questions or support needs during implementation, please contact the [Jay Support Team](mailto:support@transfermedia.de).