General concept of the system

24TTL creates a web-page with rich content for a product. The web-page is converted to an e-package file which is a ZIP file containing HTML, CSS, iframe, JSON and media files along with a manifest JSON file (manifest.json). The manifest file contains the basic information on the e-package and the product described in it. The e-package is assigned a unique URL that is rendered to the CDN. The CDN creates a new equivalent link for this epackage and caches it.

24STREAM is triggered when a user visits a product page where the widget is embedded. The CDN uses the link to the manifest.json file to check if any relevant content is available.

If the content is available, the system responds with “200” and the widget, depending on the method you selected, either automatically delivers the rich content on the product page (the method findAndInsert) or provides an opportunity to handle the content manually (the method find). If there is no content, the system responds with “204”.

 

24STREAM rich content delivery tool

The 24STREAM widget is designed to broadcast rich content onto product pages of online marketplaces.

Rich content is the combination of text, images, video, animations, and inteactive media that provides more informative and engaging description of the product. Enhanced content encourages virtual interaction with the product, showcases its advantages, evokes vivid emotions, builds the brand awareness, and motivates to purchase.

The system provides for two types of rich content: minisite and AR (augmented reality).

The 24STREAM widget is embedded as a script in your online marketplace and provides methods for searching the relevant rich content and rendering it to the product page.   

Rich content is uploaded when a user of the marketplace visits the product page where the tool is embedded. The script contains the parameters that help to determine which rich product content of which brand should be rendered.

The widget neither collects nor processes any of your data.

The functions of the 24STREAM solution are as follows: building the path to the static HTML file located on the CDN; inserting the result (HTML code) into <div> block; monitoring the size of the block where the content is inserted; and, depending on the block size, changes the classes in the inserted HTML file. The content resolution is limited by width and has four types: maximum - 1200px; small pc - 1100 to 991px; tablet - 991 to 768px; and mobile - below 768 to 320px.

The page speed is not impacted because the widget does not use any external database queries, but only accesses the static content located on the CDN. Thus, regardless of the user's location, the content is always delivered from the nearest CDN server.

The content can be accessed directly without using the widget. To do this, the correct path should be built using the required attributes described in the section "Using the Widget". 

Connecting the widget

The widget is adapted to operate in various environments and offers two methods of connection: asynchronous and synchronous.

To run the tool in mobile applications, it is recommended to use WebView. Rich content will be displayed in a pop-up window.

Asynchronous connection

The asynchronous connection is recommended to have the code run in your browser client.

The asynchronous-connected widget will not block loading of the main content.

If it is completely inaccessible, it will neither cause any errors nor breal the main functionality of the website.

To integrate the widget, insert the following code into the end of the document body:


<script>
	(function (w, d, s, o) {
		var f = d.getElementsByTagName(s)[0];
		var j = d.createElement(s);
		w.TTLStreamReady = new Promise((resolve) => {
			j.async = true;
			j.src = '//content.24ttl.stream/widget.js';
			f.parentNode.insertBefore(j, f);
			j.onload = function () {
				w.ttlStream = new TTLStream(o);
				resolve(w.ttlStream);
			};
		});
	})(window, document, 'script', {});
</script>
								

The widget is ready for use!

Synchronous connection

The synchronous connection, unlike the asynchronous type, blocks the main traffic, and the scripts that follow the widget connection code will be loaded only after the widget loading.

This type of connection may be useful to those seeking to receive the data as soon as possible and to manipulate the data thereafter.

To integrate the widget, insert the following code into the end of the document body:


<script src="//content.24ttl.stream/widget.js"></script>
<script>
	window.TTLStreamReady = new Promise(resolve => { window.ttlStream = new TTLStream({}); resolve(); });
</script>
								

The widget is ready for use!

Using the widget

After you connected the widget, it is ready for use.

The widget settings differ depending on the content type (parameter).

Presently, 2 types of content are available: minisite and ar (augmented reality).

Content type 'minisite'

This type of content is a landing page with images, text and video media.

For ease of use, the widget provides two operation methods:

- findAndInsert: the method provides for finding rich content and automatically inserting it into the block;

- find: the method is similar to findAndInsert, additionally provides the ability to manipulate the content.

Example of broadcast content

Using findAndInsert for minisite

The method findAndInsert, similar to find, takes a set of parameters using which the widget finds the content and inserts it into the block.
Unlike the method find, findAndInsert does not return the data for manipulations, but inserts it into the block.

The following parameters can be sent:

Parameter Required Value type Description
el yes string

CSS selector of the DOM element into which the content will be inserted. You can customize the type of rich content by adding your CSS rules. Prior to calling the widget, the block where the rich content will be inserted should be assigned styles via important, for example, having added the following JS script:

 var styleElement = document.createElement('style'); styleElement.innerHTML = 'body .exampleWrapperContent #stream-container * { '+ ' font-family: \'DINPro Technopark\' !important;'+ '}'; document.getElementsByTagName("head")[0].appendChild(styleElement); 

where .exampleWrapperContent should be replaced with the class of the element into which the rich content will be inserted

brand yes string The name of the brand for whose product rich content will be delivered onto your online marketplace
productId yes string The product identifier that makes the product of the brand unique for the brand's retailer
retailerDomain yes string The domain of the retailer where the rich product content will be delivered to
templateType yes string Returned template type, can take on the values 'master_template' (html template) and 'img_template' (tempalte of images)
contentType yes string Returned content type, can take the values 'minisite' and 'ar'
resultType yes string Returned result format, can take on the values 'html', a required parameter, determines the result
language no string

The country and language code for the rich content. To receive the content in a particular language for a particular country, a query should be sent in the format 'country_language'. The country code and the language code should be given in the ISO standard (the country code should be in accordance with ISO 3166-1, with the language code in ISO 639-1). If you require three pages in three languages, you should make three queries, having given in each the required parameters of the language

By default, the parameter is set to 'ru'

throwError no boolean

The value is not set or set to true: if no rich content is found, the console will show the error "404" (no content is found). You will have to resolve this error

If the value is set to false,in case no content is found, the error will not be given; therefore, there will be no necessity to resolve it

Code example


<script>
	TTLStreamReady.then(() => {
		ttlStream.findAndInsert({
			el: '.myCoolWrapper',
			brand: 'panasonic',
			productId: 'demoSKU',
			retailerDomain: 'beru.ru',
			templateType: 'master_template',
			resultType: 'html',
			contentType: 'minisite',
			language: 'ru',
		});
	});
</script>
								

The parameter resultType determines the data type which will be inserted onto the page. Below are its possible options:

html

HTML content will be inserted onto the page.

Using find for minisite

The method find takes a set of parameters using which the widget finds the content.

The following parameters can be sent:

Parameter Required Value type Description
brand  yes string The name of the brand for whose product rich content will be delivered onto your online marketplace
productId  yes string The product identifier that makes the product of the brand unique for the brand's retailer
retailerDomain  yes string The domain of the retailer where the rich product content will be delivered to
templateType  yes string Returned template type, can take on the values 'master_template' (html template) and 'img_template' (tempalte of images)
contentType  yes string Returned content type, can take on the values 'minisite' and 'ar'
resultType  yes string Returned result format, can take on the values 'html', determines the result. See the example below
language no string

The country and language code for the rich content. To receive the content in a particular language for a particular country, a query should be sent in the format 'country_language'. The country code and the language code should be given in the ISO standard (the country code should be in accordance with ISO 3166-1, with the language code in ISO 639-1). If you require three pages in three languages, you should make three queries, having given in each the required parameters of the language

By default, the parameter is set to 'ru'

Code example:


<script>
	TTLStreamReady.then(() => {
		ttlStream.find({
			brand: 'panasonic',
			productId: 'demoSKU',
			retailerDomain: 'beru.ru',
			templateType: 'master_template',
			resultType: 'html',
			contentType: 'minisite',
                       language: 'ru',
  }).then((data) => {
// The function will be called if the content is found successfully // The data variable will contain the found content }).catch((error) => { // The function will be called if the content is not found // The error variable will contain data of error reason }); }); </script>

The parameter resultType determines the data type which will be returned. Below are its possible options:

html

The variable data in the response will contain all html content of the requested page.

Content type 'ar' (augmented reality)

AR ("augmented reality") content is a visualization of a product in augmented reality that allows to show a detailed 3D copy of the product in space.

Example of broadcast AR content

Setting up AR

To set up the AR visualization, the method setArSettings is used.

The following parameters can be sent:

Parameter Description
preview A range of settings to customize the open button 
preview.html Button text

preview.style.backgroundColor

preview.style.backgroundImage

preview.style.backgroundSize

preview.style.backgroundRepeat

preview.style.backgroundPosition

Button styles. All styles are written as style object properties
viewer A number of settings to stylize the viewer
viewer.modalStyle Pop-up styles. All styles are written as style object properties
viewer.viewerStyle Viewer styles. All styles are written as style object properties
viewer.loaderColor Pre-loader bar color
viewer.closeStyle Viewer close button style. All styles are written as style object properties
qr A number of settings for QR code modal window 
qr.modal.style Modal window styles settings. All styles are written as style object properties
qr.box.style Settings of QR content block styles. All styles are written as style object properties
qr.btnOpen Settings of open button of QR code modal window
qr.btnOpen.html Buton text
qr.btnOpen.style Button styles. All styles are written as style object properties
qr.btnClose Settings of close button of QR code modal window
qr.btnClose.html Button text
qr.btnClose.style Button styles. All styles are written as style object properties
qr.title QR code title settings
qr.title.html Title text
qr.title.style Title styles. All styles are written as style object properties
qr.subtitle QR code subtitle settings
qr.subtitle.html Subtitle text
qr.subtitle.style Subtitle styles. All styles are written as style object properties

Code example


<script>
  TTLStreamReady.then(() => {
      ttlStream.setArSettings({
          preview: {
              html: '',
              style: {
                  backgroundColor: '#231010',
                  backgroundImage: "url('https://24ar.tech/staticCDN/desktop/assets/buttons/ar.svg')",
                  backgroundSize: 'cover',
                  backgroundRepeat: 'no-repeat',
                  backgroundPosition: 'center',
              },
          },
          viewer: {
              modalStyle: {},
              viewerStyle: {},
              loaderColor: '#bd0d0d',
              closeStyle: {},
          },
          qr: {
              modal: {
                  style: {},
              },
              box: {
                  style: {},
              },
              btnOpen: {
                  html: 'Hello world!',
                  style: {},
              },
              btnClose: {
                  html: 'Close',
                  style: {},
              },
              title: {
                  html: 'How to watch in AR',
                  style: {},
              },
              subtitle: {
                  html: 'Scan the QR code with your phone's camera to see the object in real life.',
                  style: {},
              },
          },
      });

      ttlStream.findAndInsert({
          el: '.myCoolWrapper',
          brand: 'panasonic',
          productId: 'demoSKU',
          retailerDomain: 'beru.ru',
          templateType: 'desktop',
          resultType: 'html',
          contentType: 'ar',
	  	});
	});
</script>
								
Using findAndInsert for AR

As applied to AR content type, the method findAndInsert is used.

The following parameters can be sent:

Parameter  Required Parameter type Description
el yes string CSS selector of the DOM element into which the content will be inserted
brand yes string The name of the brand for whose product rich content will be delivered onto your online marketplace
productId yes string The product identifier that makes the product of the brand unique for the brand's retailer
retailerDomain yes string The domain of the retailer where the rich product content will be delivered to
templateType no string A type of the device used, can have the values 'ios', 'android', 'desktop'. If the parameter is not given, the device type will be determined automatically
contentType yes string AR
resultType yes string Returned result format, can take on the value 'html'
language no string

The country and language code for the rich content. To receive the content in a particular language for a particular country, a query should be sent in the format 'country_language'. The country code and the language code should be given in the ISO standard (the country code should be in accordance with ISO 3166-1, with the language code in ISO 639-1). If you require three pages in three languages, you should make three queries, having given in each the required parameters of the language

By default, the parameter is set to 'ru'

throwError no boolean

The value is not set or set to true: if no rich content is found, the console will show the error "404" (no content is found). You will have to resolve this error

If the value is set to false, in case no content is found, the error will not be given; therefore, there will be no necessity to resolve it

Code example:


<script>
	TTLStreamReady.then(() => {
		ttlStream.findAndInsert({
			el: '.myCoolWrapper',
			brand: 'panasonic',
			productId: 'demoSKU',
			retailerDomain: 'beru.ru',
			templateType: 'desktop',
			resultType: 'html',
			contentType: 'ar',
              }); }); </script>
The incorporation of the widget into the mobile application
24STREAM Flutter

A flutter plugin for creating 24STREAM Rich Page widgets.

Installation

To install add stream24 plugin to your dependencies in your pubspec.yaml

dependencies:
  ...
stream24: ^0.1.15
...

Usage

Stream24RichPage

A webview widget with rich html contents and automatic height.

Parameter Parameter type Description
brand string Required. Brand name for the page
productId string Required. Prouct ID for the page
retailerDomain string Required. Domain of the retailer of the page
templateType string Required. Template type of the page
language string Language code for the page encoded as country_language. Country code should set according to ISO 3166-1 standard and the language code - to ISO 639-1. Defaults to ru
onError Function(String) A function to call when an error is occured
contentType Stream24ContentType Content type of the page. One of .shopInShops or .minisite. Defaults to .minisite

GetHtml

Returns HTML code of the page as a String.

Parameter Parameter type Description
brand string Required. Brand name for the page
productId string Required. Prouct ID for the page
retailerDomain string Required. Domain of the retailer of the page
templateType string Required. Template type of the page
language string Language code for the page encoded as country_language. Country code should set according to ISO 3166-1 standard and the language code - to ISO 639-1. Defaults to ru
contentType Stream24ContentType Content type of the page. One of .shopInShops or .minisite. Defaults to .minisite

Example

Using Stream24RichPage

import 'package:flutter/material.dart';
import 'package:stream24/stream24.dart';
import 'package:stream24/rich_page.dart';
import 'package:webview_flutter/webview_flutter.dart';



class WebViewPage extends StatefulWidget {
  WebViewPage({super.key});
  @override
  State<WebViewPage> createState() => _WebViewPageState();
}
class _WebViewPageState extends State<WebViewPage> {
  @override
  Widget build(BuildContext context) {
    return  Stream24RichPage(
            brand: 'Samsung',
            productId: '16651081549',
            retailerDomain: 'irshad.az',
            templateType: 'master_template',
            contentType: Stream24ContentType.shopInShops,
            onError: (errorMsg){ print(errorMsg); }
        );
    }
}

OR

Using getHtml

import 'package:flutter/material.dart';
import 'package:stream24/stream24.dart';
import 'package:webview_flutter/webview_flutter.dart';



class WebViewPage extends StatefulWidget {
  WebViewPage({super.key});
  @override
  State<WebViewPage> createState() => _WebViewPageState();
}



class _WebViewPageState extends State<WebViewPage> {
  late WebViewController controller;
    double height = 120;



  @override
  void initState() {
    super.initState();
       controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)



      // to automatically adjust height add the following block
      ..addJavaScriptChannel("FlutterWebviewHeight",
          onMessageReceived: (JavaScriptMessage msg) {
        setState(() {
          height = double.tryParse(msg.message) ?? 0;
        });
      })
      //////////////////////////////////////////////////////////////////



      //if you want to throw errors on 404 content add the following block
      ..addJavaScriptChannel("FlutterError",
          onMessageReceived: (JavaScriptMessage msg) {
            
        throw Exception(msg.message);
      })
      //////////////////////////////////////////////////////////////////



      ..loadHtmlString(Stream24.getHtml(
          brand: 'Samsung',
          productId: '16651081549',
          retailerDomain: 'irshad.az',
          templateType: 'master_template',
          contentType: Stream24ContentType.shopInShops));
  }



  @override
  Widget build(BuildContext context) {
    return SizedBox(
        height: height,
        child: WebViewWidget(
          controller: controller,
        ),
    );
  }
}
24STREAM Kotlin

An android library for generating 24STREAM HTML widgets to be used in WebView or any other nested browser.

Installation

To install the library you need to add JitPack repository first (if you haven't already).
For older projects in the root build.gradle file add maven { url 'https://jitpack.io' } inside allprojects->repositories like following:

 allprojects {
repositories {
 ...
maven { url 'https://jitpack.io' }
}
 }

For newer projects you need to add it to settings.gradle. It should be in dependencyResolutionManagement->repositories like following:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Then we need to add the dependency itself(in app module build.gradle):

dependencies {
    ...
    implementation 'stream.24ttl.git.pub:24stream_android:0.5.3'
}

Usage

RichPage

A webview widget with rich html contents and automatic height.

Parameter Parameter type Description
brand string Required. Brand name for the page
productId string Required. Prouct ID for the page
retailerDomain string Required. Domain of the retailer of the page
templateType string Required. Template type of the page
language string Language code for the page encoded as country_language. Country code should set according to ISO 3166-1 standard and the language code - to ISO 639-1. Defaults to ru
onError (String) -> Unit A function to call when an error is occured
contentType Stream24ContentType Content type of the page. One of .shopInShops or .minisite. Defaults to .minisite

GetHTML

Returns HTML code of the page.

Parameter Parameter type Description
brand string Required. Brand name for the page
productId string Required. Prouct ID for the page
retailerDomain string Required. Domain of the retailer of the page
templateType string Required. Template type of the page
language string Language code for the page encoded as country_language. Country code should set according to ISO 3166-1 standard and the language code - to ISO 639-1. Defaults to ru
contentType Stream24ContentType Content type of the page. One of .shopInShops or .minisite. Defaults to .minisite

Example

Using RichContent

import stream.ttl24.stream24.Stream24

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val rich = Stream24.RichContent(LocalContext.current, LocalDensity.current, "irshad.az", "Samsung", "16651081549",  "master_template", ::onError, "ru_ru",  Stream24.Stream24ContentType.shopInShops)
        setContentView(rich)
    }
}


fun onError(errorMessage:String){
    print(errorMessage)
}

Using GetHtml

import stream.ttl24.stream24.Stream24

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val webview = WebView(this)
        val html = Stream24.GetHTML("Samsung", "16651081549", "irshad.az", "master_template", Stream24.Stream24ResultType.html, Stream24.Stream24ContentType.shopInShops)
        webview.getSettings().javaScriptEnabled = true
        webview.loadData(html,
            "text/html", "UTF-8")
        setContentView(webview)
    }
}
24STREAM Swift

An iOS plugin for generating 24STREAM HTML widgets to be used in WKWebView or any other nested browser.

Installation

24STREAM is available through CocoaPods and Swift Package Manager.

To install it using Cocoapods, add the following line to your Podfile:

pod '24stream'

To install it using Swift Package Manager:

File -> Add packages... -> Search 'https://git.24ttl.stream/pub/24stream_swift' -> Add package

Usage

You need to import it as import _24stream. After that you can use Stream24 namespace which contains:

WebView

Parameter Parameter type Description
brand string Required. Brand name for the page
productId string Required. Prouct ID for the page
retailerDomain string Required. Domain of the retailer of the page
templateType string Required. Template type of the page
language string Language code for the page encoded as country_language. Country code should set according to ISO 3166-1 standard and the language code - to ISO 639-1. Defaults to ru
page string Page name. Defaults to index.html
onError Function((Float) -> Void) Error handling function. The function will be fired on any error thrown on the widget
contentType Stream24ContentType Content type of the page. One of .shopInShops or .minisite. Defaults to .minisite
onHeightSet Function((Float) -> Void) Action to perform once the page is loaded. scrollHeight passed as input parameter. Usually used to set dynamic height of the webview

Example

import SwiftUI
import _24stream

struct ExamplePage: View {

    //necessary for automatic height calculation
    @State var richHeight: CGFloat = 0
    func setHeight(height:Float ) {
        richHeight = CGFloat(height)
    }

    // for handling any errors
    func onError(error: String) {
        print(error)
    }
    
    var body: some View  {
        ScrollView{
            RichPage(  brand: "TestBrand",
                       retailerDomain: "24ttl.ru",
                       productId: "920-969696",
                       templateType: "master_template",
                       language: "ru",
                       page: "index.html",
                       contentType: _24StreamContentType.minisite,
                       onHeightSet: setHeight,
                       onError: onError).frame(height:richHeight)
        }
        
    }
}

struct ExamplePage_Previews: PreviewProvider {
    static var previews: some View {
        ExamplePage()
    }
}
Backend integration

Server-side retrieval of the card list and rich content via REST API

General information

Backend integration allows a retailer to receive 24STREAM rich content directly on its server, without using the browser widget. It suits scenarios where the content needs to be loaded into the retailer's own database or CMS and served on product pages by the platform itself.

Rich content is a combination of text, images, video and animation that provides a more engaging description of the product. Each unit of rich content corresponds to a card (e-package). Working with the API takes two steps: first, the retailer gets the list of cards available to it, then downloads the HTML content of each card by its identifier.

Workflow

  • Get the list of cards available to your platform (the /search method).
  • Match the cards with your products by the skuId field.
  • Download the rich content HTML by the card identifier (/download).
  • Periodically request updates using the updatedAt filter and synchronize your database.

 

Access and authentication

Accessing the API requires an API key generated by 24TTL. To receive the key and the retailer identifier (retailerId), please contact your retail manager.

Base URL:

https://panel.24ttl.stream/api/v1

All requests are made over HTTPS using the POST method.

Request headers

Header Value Description
Authorization ApiKey <your_key> Required. The API key is passed only in the header, not in the request body.
Content-Type application/json Required
Accept-Charset utf-8 Recommended

General conventions

Date and time format

All dates are sent and returned in ISO 8601 format, for example 2026-08-01 00:00:00.

Pagination

List methods use cursor-based pagination. The response contains a cursor field; to get the next page, pass this value in the cursor field of the next request. An empty or missing cursor in the response means there are no more pages.

Response codes

Code Meaning
200 The request was processed successfully.
400 Invalid request body (parameter validation error).
401 Missing or invalid API key.
404 The requested content was not found.
429 Request limit exceeded. Please retry later.
Method 1. List of cards

Returns a paginated list of rich content cards available to your platform. The method is used both for the initial export of the full list and for getting only the updated cards with the updatedAt filter.

Request

curl -X POST https://panel.24ttl.stream/api/v1/retailers/{retailerId}/retailer-epackages/search \
-H "Accept-Charset: utf-8" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey generatedApiKey" \
-d '{
"limit": 1000,
"cursor": "###",
"fields": ["name", "brand"],
"filters":{
  "updatedAt":{
    "gte": "yyyy-mm-dd hh:mm:ss",
    "gt": "yyyy-mm-dd hh:mm:ss",
    "lte": "yyyy-mm-dd hh:mm:ss",
    "lt": "yyyy-mm-dd hh:mm:ss"
  },
  "isActive":{
    "eq": true
  },
  "skuId":{
    "in": ["example_sku_id"]
  },
  "reId":{
    "in": ["example_re_id"]
  }
}
}'

Request body parameters

Parameter Required Description
limit No Number of items per page. Default is 100, maximum is 1000.
cursor No Pagination cursor. To get the next page, pass the cursor value from the previous response.
fields No Additional fields in the response. Allowed values: name, brand.
filters.updatedAt.gte No Update date “greater than or equal to”.
filters.updatedAt.gt No Update date “greater than”.
filters.updatedAt.lte No Update date “less than or equal to”.
filters.updatedAt.lt No Update date “less than”.
filters.isActive.eq No Filter by card status (true / false).
filters.skuId.in No List of custom identifiers (skuId) to select specific cards.
filters.reId.in No List of card identifiers (reId).

The updatedAt filters are convenient for regularly getting only the cards that have changed — for example, once an hour or once a day for the previous period.

Response 200

{
 "code": 200,
 "message": "",
 "data":{
   "cursor": "eyJpZCI6...",
   "items": [
     {
       "reId": "12345678-1234-1234-1234-123456789012",
       "skuId": "ABC12",
       "isActive": true,
       "updatedAt": "2026-08-01 10:30:00",
       "name": "Product name",
"brand": "Brand name"
     }

   ]
 }
}

Response fields

 Field  Description
data.cursor Cursor for getting the next page.
items[].reId Card identifier. Used in the content download methods.
items[].skuId Custom card identifier (for matching with your product).
items[].isActive Card active flag.
items[].updatedAt Date and time of the card's last update.
items[].name Product name. Returned only if requested in fields.
items[].brand Brand name. Returned only if requested in fields.
Method 2. Downloading a single card

Returns the rich content HTML for a single card by its reId.

Request

curl -X POST https://panel.24ttl.stream/api/v1/retailer-epackages/{reId}/download \
-H "Accept-Charset: utf-8" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey generatedApiKey" \
-d '{
  "locale": "ar_en",
  "contentType": "minisite",
  "template": "master_template",
  "format": "html",
  "source": "index.html"
  }'

Parameters

 Parameter  Required  Description
{reId} Yes Card identifier from Method 1 (in the request path).
locale Yes Rich content locale, for example ar_en.
contentType No Content type. Default is minisite.
template No Template. Default is master_template.
format No Content format. Default is html.
source No Content source. Default is index.html.

Responses

 Code  Response body
200 The card's rich content HTML “as is”.
404 The card or its content was not found. The response body is JSON with an error code (see below).

Response 404

Possible values of the code field in a 404 response:

{
 "code": 4040,
 "message": "Epackage retailer not found",
 "data": []
}
Code Meaning
4040 Card not found.
4041 Card content not found.
Use cases

Initial rich content loading

  • Call Method 1 and go through all pages to get all available cards.
  • Match your products with the cards by skuId. Save reId, skuId and updatedAt.
  • Download the rich content HTML by reId (Method 2) and link it to your product by the reId + skuId pair.

 

Getting updates (with the updatedAt filter)

  • Take the maximum saved updatedAt from your database (lastUpdatedAt = max(updatedAt)) and call Method 1 with the filter filters.updatedAt.gt = lastUpdatedAt. This can be done once an hour or once a day.
  • Compare the received list of updated cards with the current state of your database and apply the actions from the table below.
  • Use Method 2 to add or update content.

 

Decision matrix

isActive in the response skuId in your database Action
true Found Update the rich content.
true Not found Create a record and add the rich content.
false Found Delete / remove the rich content, if any.
false Not found Do nothing.

Getting updates (full export)

  • Get the full list of cards available to your platform (Method 1 without a date filter).
  • Find the corresponding product by skuId and apply the actions from the decision matrix above (add, update or remove rich content).

To receive your API key, retailer identifier and connection parameters, please contact your retail manager.

Sandbox

For hands-on examples, we have developed the Sandbox where you can play with the parameters.