Help menu

Server-to-Server (S2S) Measurement

Advanced measurement where you send data directly from your server to the Sklik endpoint.

S2S is suitable for websites where you need maximum accuracy without relying on third-party cookies. It can also be used for measuring conversions from mobile applications or for sending offline conversions.

The frontend script (sul.js) is required even for S2S
Even with S2S measurement, the frontend script sul.js must be deployed on the website with your SEM ID. It creates cookies sid and udid that you must read and pass in every S2S request. The S2S payload itself also contains SEM ID (parameter sem_id) – that is a different identifier. Without cookies from sul.js, user identity cannot be correctly matched.

Prerequisites

  • Frontend script deployed on all pages of the website (generates cookies sid and udid)
  • Ability to read cookies sid and udid from the server
  • Ability to hash personal data with SHA-256 on the server
  • SEM ID for S2S – a special identifier used exclusively for S2S measurement. It differs from the standard SEM ID (for the script and GTM). See Where to find SEM ID? If you have Seznam Shopping store outlets, each outlet has its own SEM ID for S2S.

Endpoint

Send all S2S requests as POST to:

POST https://sem.seznam.cz/rtgconv
Content-Type: application/json

HTTP headers

HeaderRequiredDescription
Content-TypeRequiredAlways application/json
X-Client-IdRecommendedName of your application or library sending the data (e.g. my-eshop-pluginshoptet-sem)
X-Client-VersionRecommendedApplication version (e.g. 1.4.2)

Why provide X-Client-Id and X-Client-Version?
These headers help us debug issues on your side – we can quickly identify which application and version sent the data. They have no effect on event processing, but significantly speed up diagnostics.

User identification

The S2S payload must contain the sid and udid cookies generated by the frontend script. Read them on the frontend and pass them to the server, where you include them in the user_ids.user_data object.

sid and udid require user consent
The sid and udid cookies are only written by the frontend script after consent with ad_storage: 'granted' is received. Make sure your website passes consent via updateConsent (or uses IAB TCF) before the first PageView – otherwise the cookies will not be available and user session matching will not be possible. See Setting up consent for details.

function getCookie(name) {
  const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)'));
  return match ? decodeURIComponent(match[1]) : null;
}

const sid  = getCookie('sid');   // pass to server as user_ids.user_data.sid
const udid = getCookie('udid');  // pass to server as user_ids.user_data.udid

Another key identifier is sznaiid – the click ID from Sklik. This value is found in the URL parameter after a click on an ad and is used for anonymous conversion modelling. It can be safely stored on the server without user consent.

Hash personal data before sending
Unlike the frontend script, which hashes automatically, with S2S you must hash yourself using SHA-256 all personal data fields: em, ph, fn, ln, ge, db, ct, zp, sr, country. Exception: review_email must not be hashed even with S2S.

Payload structure

ParameterTypeRequiredDescription
schema_versionstringRequiredAlways "v2"
event_namestringRequiredEvent name, e.g. "Purchase"
event_typestringRequiredAlways "rtgconv"
event_timeintegerRequiredUnix timestamp in milliseconds (UTC)
event_urlstringRequiredURL of the page where the event occurred
event_sourcestringRequired"web" or "app"
event_idstringRecommendedUnique event ID (ideally UUID-7) for deduplication
user_idsobjectRequiredObject with user identifiers (see below)
event_dataobjectRequiredEvent data – same structure as frontend measurement (see Event reference) + parameters sem_id and sznaiid
consent_stringstringRecommendedIIAB TCF consent string (if available)
consent_modeobjectRecommendedGoogle Consent Mode (alternative to TCF)
s2s_headersobjectRecommendedIP address and User Agent for more accurate identification

user_ids.user_data object

ParameterDescriptionHash?
sidSession cookie from seznam.cz – read from browserNo
udid
Session cookie generated by sul.js
No
emUser email address (key identifier)Yes (SHA-256)
phPhone numberYes (SHA-256)
fnFirst nameYes (SHA-256)
lnLast nameYes (SHA-256)
geGender (mf or o)Yes (SHA-256)
dbDate of birth (format YYYYMMDD)Yes (SHA-256)
ctCityYes (SHA-256)
zpPostal codeYes (SHA-256)
srStreet and house numberYes (SHA-256)
countryCountry code (ISO 3166-1 alpha-2, e.g. cz)Yes (SHA-256)

Special parameters in event_data for S2S

ParameterRequiredDescription
sem_idRequired for S2SSEM ID for S2S – a separate identifier visible after enabling advanced settings. Different from the SEM ID for the script/GTM.
sznaiidRecommendedClick ID from Sklik – URL parameter after clicking on an ad. Used for anonymous conversion modelling.

Complete payload example

{
  "schema_version": "v2",
  "event_source": "web",
  "event_name": "Purchase",
  "event_type": "rtgconv",
  "event_time": 1770134113676,
  "event_id": "018e4f2a-1234-7abc-9def-0123456789ab",
  "event_url": "https://vas-eshop.cz/dekujeme",

  "user_ids": {
    "user_data": {
      // Cookies from sul.js – read from browser (do not hash)
      "sid": "id=1922397029101872874|t=1737450723.526|te=1756971615.061|c=0F247CCA",
      "udid": "01958f34-71d5-7ec2-ae01-cb3c80a1d0a0",

      // Personal data – hash with SHA-256 on the server
      "em": "6db68d052788e70eb459463eb34370fe983ef838db65641902f02326fabc37a7",
      "ph": "ca6faa7abf120a739e8ce3bcf581553af9ad983b3290ed8cdf8cc40b9d4fefcf",
      "fn": "6a0ac0fd972c325d6ca5512b67a5e0ad996c4a3e9b59971d125164e6d4db1a1c",
      "ln": "64118260ecb916c23621d8f2768d8dc75d1f5710b1b7e4f2c41ad41e6bc4d688",
      "ct": "f377db9f1f0af132866afd5c4381512a5c9a3b3a32e9ca2f88f0aced18264568"
    }
  },

  "consent_mode": {
    "ad_storage": "granted",
    "ad_user_data": "granted",
    "ad_personalization": "granted",
    "functionality_storage": "denied",
    "analytics_storage": "denied"
  },

  "s2s_headers": {
    "client_ip_address": "77.75.74.172",
    "user_agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36...",
    "sec_ch_ua_mobile": "?0",
    "sec_ch_ua_platform": "\"Windows\""
  },

  "event_data": {
    "sem_id": "VASE_SEM_ID_PRO_S2S",
    "sznaiid": "2627214859780792651",
    "order_id": "OBJ-987654",
    "content_type": "product",
    "currency": "CZK",  // only CZK is supported
    "value": 27364,          // total value excluding VAT (in CZK)
    "value_tax": 5746,
    "delivery_type": "CESKA_POSTA",
    "delivery_price": 121,       // including VAT
    "other_costs": -500,         // discount including VAT
    "payment_type": "karta",
    "contents": [
      {
        "id": "ABC12345",
        "quantity": 1,
        "unit_price": 33490,       // including VAT
        "content_name": "iPhone 15 Pro Max",
        "content_category": "Elektronika | Mobilní telefony | Apple"
      }
    ]
  }
}

Sending the request

Send the payload as an HTTP POST request to the endpoint https://sem.seznam.cz/rtgconv with the Content-Type: application/json header.

curl -X POST https://sem.seznam.cz/rtgconv \
  -H "Content-Type: application/json" \
  -H "X-Client-Id: my-eshop-plugin" \
  -H "X-Client-Version: 1.0.0" \
  -d '{ ... your payload ... }'
await fetch('https://sem.seznam.cz/rtgconv', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Client-Id': 'my-eshop-plugin',
    'X-Client-Version': '1.0.0',
  },
  body: JSON.stringify(payload)
});
import requests

response = requests.post(
    'https://sem.seznam.cz/rtgconv',
    json=payload,
    headers={
        'X-Client-Id': 'vas-eshop-plugin',
        'X-Client-Version': '1.0.0',
    }
)
response.raise_for_status()

Error handling and recommendations

HTTP statusMeaningRecommended action
200 OKEvent received and processed
400 Bad RequestInvalid payload – missing required field or incorrect formatFix the payload, do not retry automatically
401 / 403Invalid SEM ID or inaccessible endpointCheck the SEM ID for S2S
5xxServer-side errorRetry with exponential backoff (see below)

Retry strategy
For 5xx errors or network timeouts, we recommend retrying the request with exponential backoff: 1 s → 2 s → 4 s, up to 3 attempts. Do not retry 4xx errors – they indicate a problem with the payload, not a temporary outage.

Timeout
Set the request timeout to 3–5 seconds. S2S calls must not block order processing on your server – send events asynchronously (e.g. in a background queue).

Potřebujete další pomoc?

Pokud si stále nevíte rady, obraťte se na naše specialisty. 95 % vašich dotazů umíme vyřešit do 2 hodin.