Skip to main content

Session API integration (S2S)

Integrate with Rokt server-to-server using the unified Session API (v2) — the same /v2/sessions/* endpoints that power Rokt's SDKs. Your server calls Rokt to retrieve an offer, renders it, and reports engagement and conversion events back.

Work with your Rokt account team to obtain credentials.

EndpointsDirect link to Endpoints

PurposeMethodURL
Get offersPOSThttps://api.rokt.com/v2/sessions/offers
Report eventsPOSThttps://api.rokt.com/v2/sessions/events

For the full request/response reference for each endpoint, see the Offers API specification and the Events API specification.

Server-to-server traffic classifies as Web by default. If your Rokt pages are configured for a native platform (iOS or Android), set the rokt-platform-type header to that platform on every offers call — otherwise the request is treated as Web, your native-configured pages will not match, and page detection returns no offers. Web-configured pages need no header. Accepted values are iOS, Android, Web, WebDesktop, and WebMobile (case-insensitive); anything else falls back to Web.

note

To validate before going live, send the rokt-test-session: true header on the same endpoints — there is no separate sandbox URL. Test sessions are tagged and filtered out of production metrics; the header marks reporting only — it does not force an offer to serve. For deterministic end-to-end testing, your account team can configure a staging page with dedicated test campaigns. Remove the header to go live.

AuthenticationDirect link to Authentication

  • The rokt-account-id header is required on every call (offers and events) — it is the source of account identity on the Session API.
  • Offers call — on your first, session-less call, authenticate with Authorization: Basic base64(rpub:rsec), where rpub and rsec are the public and secret API keys provided by your account team. (Authorization: Bearer <session_token> is used only to continue an existing session.)
  • Events call — authenticate with Authorization: Basic base64(rpub:rsec), using the same public and secret API keys as the offers call.

1. Request offersDirect link to 1. Request offers

Send a typed request body and set channel.type to "s2s". All values below are synthetic examples.

POST https://api.rokt.com/v2/sessions/offers
Authorization: Basic base64(rpub:rsec)
rokt-account-id: <your Rokt account ID>
rokt-platform-type: <iOS | Android | Web>
Content-Type: application/json
{
"channel": { "type": "s2s" },
"page": { "page_identifier": "checkout" },
"customer": {
"email": "jane.doe@example.com",
"first_name": "Jane",
"last_name": "Doe",
"gender": "F",
"postal_code": "10001",
"language": "en"
},
"transaction": {
"transaction_value": 19.99,
"currency": "USD",
"confirmation_ref": "ORDER-000123"
},
"payment": { "type": "card" },
"device": {
"user_agent": "YourApp/1.0 (mobile)"
},
"attributes": {
"your_custom_attribute": "value"
}
}
  • Top-level objects (page, customer, transaction, payment, device, cart, shipping) are typed and accept only their defined fields; put any partner-specific signal that doesn't fit them into the free-form attributes string map.
  • Send only values you own. Rokt-derived attributes — geo, age and other demographics (from the Rokt profile), device type/OS/version (parsed from the user agent), payment method/sub-method (from the card BIN), and ML/Carbon signals — are computed server-side and overwritten if sent; don't include them.

2. Parse the offers responseDirect link to 2. Parse the offers response

A 2xx returns the offer directly (there is no success/errors envelope). plugins may be empty — a valid no-fill and a real share of production traffic: render nothing and continue your page. slots contains only the slots that actually filled, up to the maximum your layout defines. Read the offer from the nested plugin structure; on any non-2xx, parse the structured error body.

What you needPath in the response
Offerplugins[].plugin.config.slots[].offer
Title / copy…offer.creative.copy["creative.title"]
Image…offer.creative.copy["creative.image.src"]
Advertiser…offer.creative.advertiser
Positive action + URL…offer.creative.response_options_map.positive.url
Decline action…offer.creative.response_options_map.negative
Element instance IDs (use as event parent_id)…slots[].instance_guid, …offer.creative.instance_guid, …response_options_map[key].instance_guid
Page instance (event page_instance_guid)page_instance_guid
Session ID (event session_id)session_id
Session token (refreshed session reference)session_token.token

Errors return a semantic HTTP status with a body of { "error": "<code>", "message": "<detail>" } (validation failures add a details[] array).

3. Render the offerDirect link to 3. Render the offer

How you render depends on how your account's layouts are configured — confirm with your Rokt team which contract your account serves:

  • Self-render (data integration) — the response carries the offer's components (creative copy, image, response options — the paths in step 2) with no layout description: you draw the offer in your own UI to match your page, and report each engagement event yourself (step 4).
  • Rokt UX Helper (Rokt-designed layouts) — the response's plugins[] carry a full layout description that Rokt's open-source UX Helper libraries (Web, iOS, Android) render inside your UI, raising the engagement events for you to forward. Note the UX Helpers consume the Experiences API payload shape; the Session API returns the same layout content in a different envelope (snake_case), so pairing them with /v2/sessions/offers currently requires a small response adaptation — ask your Rokt team.

You can tell the contracts apart from the response itself: a data-integration account returns offers with empty layout schemas, while a layout account returns populated outer_layout_schema and per-slot layout_variant fields.

4. Report eventsDirect link to 4. Report events

Report engagement and conversion events to /v2/sessions/events, authenticated with the same Basic credentials as the offers call. Identify the session with single_session: true and the top-level session_id returned by the offers response on each event.

POST https://api.rokt.com/v2/sessions/events
Authorization: Basic base64(rpub:rsec)
rokt-account-id: <your Rokt account ID>
Content-Type: application/json
{
"channel": { "type": "s2s" },
"single_session": true,
"events": [
{
"event_type": "impression",
"instance_id": "018f1234-5678-7abc-8def-0123456789ab",
"session_id": "018f2a1b-2222-7abc-8def-session00001",
"timestamp": 1751234567000,
"data": {
"parent_id": "018f2a1b-3333-7abc-8def-creative001",
"page_instance_guid": "018f2a1b-0000-7abc-8def-page00000001",
"token": "<event-token>",
"capture_method": "ClientProvided"
}
}
]
}
  • event_type — the event kind as a snake_case string. Common values:

    Eventevent_type
    Impressionimpression
    Viewedviewed
    Positive / negative responsesignal_response
    Dismissaldismissal
    Conversionconversion_signal
    Purchasepurchase
  • instance_id — a client-generated UUID identifying this event, used to deduplicate.

  • session_id — the top-level session_id returned by the offers response.

  • data.parent_id — the instance_guid of the element the event is about, taken from the offers response (e.g. the creative's instance_guid for an impression, a response option's for a response). Builds the session tree. Echo the value verbatim; it may carry a type prefix such as ad:<uuid>.

  • data.page_instance_guid — the page_instance_guid from the offers response.

  • data.token — the event token for that element from the offers response.

  • timestamp — Unix epoch milliseconds.

  • Set single_session to true and include session_id on every event in the request.

A successful call returns 202 Accepted with session_token (refreshed for the next call), event_ids[], errors[] (per-event {index, code, message}), and warnings[].

ChecklistDirect link to Checklist

  • Confirm credentials and the full API reference with your Rokt account team.
  • Call /v2/sessions/offers with the typed body, channel.type: "s2s", and the rokt-account-id header (plus rokt-platform-type if your pages are configured for a native platform).
  • Parse the offer from plugins[].plugin.config.slots[].offer.creative; use the HTTP status for success/failure, and handle empty plugins (no-fill) by rendering nothing.
  • Render the offer yourself or via a UX Helper library, per your account's layout configuration.
  • Capture session_id and report events to /v2/sessions/events using Basic authentication, single_session: true, a per-event session_id, and the response's data.parent_id and data.page_instance_guid values.
  • Validate with the rokt-test-session: true header (reporting-only — it does not force an offer to serve), then remove it to cut over to production.
Was this article helpful?