ODK API Portal
English
  • Overview
  • MediaIO
  • Continue Watching
  • Player Event
  • 지원 종료
  • 최근 변경
Information
Player Events v2 (ODK)
    First rendered framegetStart a playback sessiongetWatch-time tickget
Telemetry
Player Events v2 (Amasian legacy)
Schemas
powered by Zudoku
Player Event API V2
Player Event API V2

Player Events v2 (ODK)

Dedicated ODK routes. Path is the service identifier; the server stamps s=odk on every event regardless of what the client sends. Send s=odk, did, osdid, and mci (vod/shorts/short_drama) or ch (live/multiview) on all three events. No Continue Watching side effects.


First rendered frame

GET
https://pe.odkmedia.io
/api/v2/odk/firstplay

Once per ss, when the first video frame renders. A playlist without a matching firstplay is the drop-out (or Shorts swipe-away) signal. Carry did, osdid and mci or ch so the event is attributable on its own, without a join to playlist.

Validation: only missing required parameters return 422. All other parameters are stored as strings exactly as sent (types below are guidance). Undeclared query parameters are stored as well. Data-quality checks happen in the warehouse.

First rendered frame › query Parameters

ss
​string · required

Stream session id issued by the server in the playlist response. Missing = 422; any present value (even empty) is stored.

Stream session id issued by the server in the playlist response. Missing = 422; any present value (even empty) is stored.

Example: 5243ae4e-be43-4953-a972-170440161697
dt
​string · required

Client send time, epoch milliseconds. Example: 1756971928000

Client send time, epoch milliseconds. Example: 1756971928000

Example: 1756971930000
s
​

Send odk. The server overwrites this with odk whatever is sent.

Send odk. The server overwrites this with odk whatever is sent.

Example: odk
did
​

Client-generated persistent device id: in an app, stable across app restarts and app updates; on web, a first-party UUID in localStorage with a cookie fallback. Send on every event, and send the same value on player events and telemetry — it is the join key between the two surfaces, so two separately minted UUIDs break the join silently. (Audience counting lives on the telemetry surface, not on player events.)

Client-generated persistent device id: in an app, stable across app restarts and app updates; on web, a first-party UUID in localStorage with a cookie fallback. Send on every event, and send the same value on player events and telemetry — it is the join key between the two surfaces, so two separately minted UUIDs break the join silently. (Audience counting lives on the telemetry surface, not on player events.)

osdid
​

OS advertising identifier, raw, one kind per platform: idfa (ios/tvos), gaid (android/androidtv), rida (roku), afai (firetv), tifa (tizen), lgudid (webos), vida (vizio). Not applicable on web. Send the OS value as-is, never suppress; the pipeline honours islat.

OS advertising identifier, raw, one kind per platform: idfa (ios/tvos), gaid (android/androidtv), rida (roku), afai (firetv), tifa (tizen), lgudid (webos), vida (vizio). Not applicable on web. Send the OS value as-is, never suppress; the pipeline honours islat.

mci
​

Mediahub content id. Required by the ODK contract when st is vod, shorts or short_drama.

Mediahub content id. Required by the ODK contract when st is vod, shorts or short_drama.

ch
​

Channel slug. Required by the ODK contract when st is live or multiview.

Channel slug. Required by the ODK contract when st is live or multiview.

First rendered frame › Responses

Event accepted. Echoes ss.

Response of the playlist routes: the server-issued stream session id.
PlaylistResponse
stream_session_id
​string · required

Server-issued stream session id (ss). Carry it on firstplay and viewhour of the same session.

GET/api/v2/odk/firstplay
curl 'https://pe.odkmedia.io/api/v2/odk/firstplay?ss=<string>&dt=<string>'
Example Responses
{ "stream_session_id": "550e8400-e29b-41d4-a716-446655440000" }
json
application/json

Start a playback session

GET
https://pe.odkmedia.io
/api/v2/odk/playlist

Call once per playback session, before the CSAI preroll. The server issues stream_session_id (ss); carry it on every firstplay and viewhour of the same session. A client-sent ss is ignored.

Shorts and Short Drama: one clip or episode = one session, so a new playlist on every swipe or episode change.

The server stamps s=odk and records the client IP and receive time. Events land in raw_odkr_*.

Validation: only missing required parameters return 422. All other parameters are stored as strings exactly as sent (types below are guidance). Undeclared query parameters are stored as well. Data-quality checks happen in the warehouse.

Start a playback session › query Parameters

dt
​string · required

Client send time, epoch milliseconds. Example: 1756971928000

Client send time, epoch milliseconds. Example: 1756971928000

Example: 1756971928000
s
​

Send odk. The server overwrites this with odk whatever is sent.

Send odk. The server overwrites this with odk whatever is sent.

Example: odk
did
​

Client-generated persistent device id: in an app, stable across app restarts and app updates; on web, a first-party UUID in localStorage with a cookie fallback. Send on every event, and send the same value on player events and telemetry — it is the join key between the two surfaces, so two separately minted UUIDs break the join silently. (Audience counting lives on the telemetry surface, not on player events.)

Client-generated persistent device id: in an app, stable across app restarts and app updates; on web, a first-party UUID in localStorage with a cookie fallback. Send on every event, and send the same value on player events and telemetry — it is the join key between the two surfaces, so two separately minted UUIDs break the join silently. (Audience counting lives on the telemetry surface, not on player events.)

Example: 3f2c1e4a-9b7d-4c11-a2f0-5e8d6b1c9a04
osdid
​

OS advertising identifier, raw, one kind per platform: idfa (ios/tvos), gaid (android/androidtv), rida (roku), afai (firetv), tifa (tizen), lgudid (webos), vida (vizio). Not applicable on web. Send the OS value as-is, never suppress; the pipeline honours islat.

OS advertising identifier, raw, one kind per platform: idfa (ios/tvos), gaid (android/androidtv), rida (roku), afai (firetv), tifa (tizen), lgudid (webos), vida (vizio). Not applicable on web. Send the OS value as-is, never suppress; the pipeline honours islat.

Example: 6D92078A-8246-4BA4-AE5B-76104861E7DC
islat
​

OS limit-ad-tracking flag as reported by the OS: 0 or 1. Apps and CTV. Same key on PEv2 (query string) and telemetry (JSON); both are stored as the string "0"/"1".

OS limit-ad-tracking flag as reported by the OS: 0 or 1. Apps and CTV. Same key on PEv2 (query string) and telemetry (JSON); both are stored as the string "0"/"1".

Example: 0
u
​

Logged-in account (user) id. Not sent for guests.

Logged-in account (user) id. Not sent for guests.

Example: 72407
pid
​

Viewing profile id within the account, int. Not sent for guests or when no profile.

Viewing profile id within the account, int. Not sent for guests or when no profile.

Example: 3
m
​

Membership tier: basic, plus, premium, premium-box. Not sent for guests.

Membership tier: basic, plus, premium, premium-box. Not sent for guests.

mu
​

Billing interval: month, year.

Billing interval: month, year.

p
​

Platform, keep granular: web, android, androidtv, ios, tvos, roku, tizen, webos, firetv, vizio, hoteltv, box, chromecast. Web sends plain web.

Platform, keep granular: web, android, androidtv, ios, tvos, roku, tizen, webos, firetv, vizio, hoteltv, box, chromecast. Web sends plain web.

Example: ios
si
​

Hotel TV site identifier {hotel}_{hotelCode}_{si}. Hotel TV only.

Hotel TV site identifier {hotel}_{hotelCode}_{si}. Hotel TV only.

st
​

Stream type: vod, live, multiview, shorts, short_drama, promo_clips. (on-demand is now vod.)

Stream type: vod, live, multiview, shorts, short_drama, promo_clips. (on-demand is now vod.)

Example: vod
mci
​

Mediahub content id. Required by the ODK contract when st is vod, shorts or short_drama.

Mediahub content id. Required by the ODK contract when st is vod, shorts or short_drama.

Example: 581003
ch
​

Channel slug. Required by the ODK contract when st is live or multiview.

Channel slug. Required by the ODK contract when st is live or multiview.

Example: kbs-world
sl
​

Initial subtitle language: en, ko, zh-chs, zh-cht, vi, or empty.

Initial subtitle language: en, ko, zh-chs, zh-cht, vi, or empty.

r
​

Recommendation engine name, empty when none. Required when attr_val=click_recommendation.

Recommendation engine name, empty when none. Required when attr_val=click_recommendation.

attr
​

Entry surface: where the user started this playback chain. Set once at entry and sent unchanged on every chained playlist; it resets when the user starts a new playback from any surface on this list, a deeplink or push included. Values: search, main_banner, continue_watching (the rail, not "resumed"), startover, shorts_feed, shorts_feed:pinned, home_rail, favorite, category, category_banner, deeplink, push, tv_guide, live_channel_list. Start Over on a live channel begins a new chain: new playlist with attr=startover, st=live and ch (no mci). Shorts always sends shorts_feed or shorts_feed:pinned, even when a deeplink or push opened it. direct_play is an attr_val value, not an attr value. A surface not on this list: omit attr; never invent a value and never send unmapped. Registry: PM spec §8 (v2.1.7).

Entry surface: where the user started this playback chain. Set once at entry and sent unchanged on every chained playlist; it resets when the user starts a new playback from any surface on this list, a deeplink or push included. Values: search, main_banner, continue_watching (the rail, not "resumed"), startover, shorts_feed, shorts_feed:pinned, home_rail, favorite, category, category_banner, deeplink, push, tv_guide, live_channel_list. Start Over on a live channel begins a new chain: new playlist with attr=startover, st=live and ch (no mci). Shorts always sends shorts_feed or shorts_feed:pinned, even when a deeplink or push opened it. direct_play is an attr_val value, not an attr value. A surface not on this list: omit attr; never invent a value and never send unmapped. Registry: PM spec §8 (v2.1.7).

Example: home_rail
attr_val
​

Playback trigger, recorded fresh on every playlist and never inherited. Values: direct_play (the default; missing is read as direct_play, except on Shorts), next_episode, click_next_episode, episode_list_click, auto_next_play, click_recommendation (also send r). Shorts: the feed ordering mode (random, popularity_vh, recency) when the feed API reports it, otherwise omit; on st=shorts a missing attr_val means the ordering mode was not reported, not direct_play. Registry: PM spec §8 (v2.1.7).

Playback trigger, recorded fresh on every playlist and never inherited. Values: direct_play (the default; missing is read as direct_play, except on Shorts), next_episode, click_next_episode, episode_list_click, auto_next_play, click_recommendation (also send r). Shorts: the feed ordering mode (random, popularity_vh, recency) when the feed API reports it, otherwise omit; on st=shorts a missing attr_val means the ordering mode was not reported, not direct_play. Registry: PM spec §8 (v2.1.7).

Example: next_episode
fpos
​

Shorts only. Position of the clip in the feed, int.

Shorts only. Position of the clip in the feed, int.

Example: 3
sp
​

Shorts only. Full-screen sponsored item, bool true or false.

Shorts only. Full-screen sponsored item, bool true or false.

Example: false
av
​

App version.

App version.

Example: 9.9.9
c
​

Stream delivery domain (CDN).

Stream delivery domain (CDN).

Example: ol.ondemandkorea.com

Start a playback session › Responses

Event accepted. Use stream_session_id on the rest of the session.

Response of the playlist routes: the server-issued stream session id.
PlaylistResponse
stream_session_id
​string · required

Server-issued stream session id (ss). Carry it on firstplay and viewhour of the same session.

GET/api/v2/odk/playlist
curl 'https://pe.odkmedia.io/api/v2/odk/playlist?dt=<string>'
Example Responses
{ "stream_session_id": "5243ae4e-be43-4953-a972-170440161697" }
json
application/json

Watch-time tick

GET
https://pe.odkmedia.io
/api/v2/odk/viewhour

Every 5 seconds while playing. v is the seconds watched in this tick: 5 by default, and the measured remainder on the final tick (a 2 second view ends with v=2).

Guaranteed last tick (mandatory for Shorts and Short Drama): measure locally and send on exit, swipe-away or background. Web: sendBeacon on visibilitychange; native: lifecycle hooks plus a persisted local queue re-sent on next launch.

Carry did, osdid and mci or ch on every tick. No Continue Watching side effects on this route.

Validation: only missing required parameters return 422. All other parameters are stored as strings exactly as sent (types below are guidance). Undeclared query parameters are stored as well. Data-quality checks happen in the warehouse.

Watch-time tick › query Parameters

ss
​string · required

Stream session id issued by the server in the playlist response. Missing = 422; any present value (even empty) is stored.

Stream session id issued by the server in the playlist response. Missing = 422; any present value (even empty) is stored.

Example: 5243ae4e-be43-4953-a972-170440161697
dt
​string · required

Client send time, epoch milliseconds. Example: 1756971928000

Client send time, epoch milliseconds. Example: 1756971928000

Example: 1756971935000
v
​string · required

Seconds watched in this tick, number. Default 5; the final tick carries the measured value. Stored as sent, not shape-validated (a malformed last tick must not be dropped).

Seconds watched in this tick, number. Default 5; the final tick carries the measured value. Stored as sent, not shape-validated (a malformed last tick must not be dropped).

Example: 5
s
​

Send odk. The server overwrites this with odk whatever is sent.

Send odk. The server overwrites this with odk whatever is sent.

Example: odk
did
​

Client-generated persistent device id: in an app, stable across app restarts and app updates; on web, a first-party UUID in localStorage with a cookie fallback. Send on every event, and send the same value on player events and telemetry — it is the join key between the two surfaces, so two separately minted UUIDs break the join silently. (Audience counting lives on the telemetry surface, not on player events.)

Client-generated persistent device id: in an app, stable across app restarts and app updates; on web, a first-party UUID in localStorage with a cookie fallback. Send on every event, and send the same value on player events and telemetry — it is the join key between the two surfaces, so two separately minted UUIDs break the join silently. (Audience counting lives on the telemetry surface, not on player events.)

osdid
​

OS advertising identifier, raw, one kind per platform: idfa (ios/tvos), gaid (android/androidtv), rida (roku), afai (firetv), tifa (tizen), lgudid (webos), vida (vizio). Not applicable on web. Send the OS value as-is, never suppress; the pipeline honours islat.

OS advertising identifier, raw, one kind per platform: idfa (ios/tvos), gaid (android/androidtv), rida (roku), afai (firetv), tifa (tizen), lgudid (webos), vida (vizio). Not applicable on web. Send the OS value as-is, never suppress; the pipeline honours islat.

mci
​

Mediahub content id. Required by the ODK contract when st is vod, shorts or short_drama.

Mediahub content id. Required by the ODK contract when st is vod, shorts or short_drama.

ch
​

Channel slug. Required by the ODK contract when st is live or multiview.

Channel slug. Required by the ODK contract when st is live or multiview.

wp
​

Current playback position in seconds. Recommended; completion and drop-off are derived from it.

Current playback position in seconds. Recommended; completion and drop-off are derived from it.

Example: 12.5
sl
​

Currently selected subtitle language, empty when none.

Currently selected subtitle language, empty when none.

Watch-time tick › Responses

Event accepted. Echoes ss.

Response of the playlist routes: the server-issued stream session id.
PlaylistResponse
stream_session_id
​string · required

Server-issued stream session id (ss). Carry it on firstplay and viewhour of the same session.

GET/api/v2/odk/viewhour
curl 'https://pe.odkmedia.io/api/v2/odk/viewhour?ss=<string>&dt=<string>&v=<string>'
Example Responses
{ "stream_session_id": "550e8400-e29b-41d4-a716-446655440000" }
json
application/json

Telemetry