再生API
1人の視聴者に1エピソードを認可し、WebViewですぐ再生できるホスト型リンクと自社プレイヤー用の同等な署名付きHLS/DASHマニフェストを取得します。任意の非PII設定でWebViewをパーソナライズできます。playback:tokenが必要です。
エンドポイント
| メソッド | パス | 用途 |
|---|---|---|
| POST | /playback/tokens | エピソードを認可 → WebViewリンク+署名付きマニフェスト |
| GET | /playback/sessions/{session_id} | 再生セッションを取得 |
| POST | /playback/sessions/{session_id}/revoke | アクティブセッションを終了 |
トークンリクエスト
curl -X POST "https://signal-partners.newunivers.ai/v1/playback/tokens" \
-H "Authorization: Bearer nsp_live_xxx" \
-H "X-NU-Partner-Id: org_acme" \
-H "X-NU-Request-Id: req_playback_0001" \
-H "Content-Type: application/json" \
-d '{
"title_id": "ttl_abc",
"episode_id": "ep_001",
"viewer_id_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"country": "KR",
"device": "web",
"origin": "https://app.acme.example",
"preferences": {
"preferred_languages": ["ko", "en"],
"preferred_genres": ["romance", "thriller"],
"subtitle_language": "ko",
"audio_language": "ko",
"autoplay_next": true,
"maturity_rating": "15"
},
"expires_in": 1800
}'| フィールド | 必須 | 備考 |
|---|---|---|
title_id | はい | |
episode_id | はい | タイトルに属する必要あり |
viewer_id_hash | はい | パートナー側SHA-256(stable_viewer_id + salt)。Productionは64文字の小文字16進数、Sandboxは従来のopaque IDも許可。生のPIIは禁止。 |
country | Productionは必須 / Sandboxは任意 | ISO 3166-1 alpha-2。Productionでは必須で契約地域と照合します。Sandboxでは任意で、指定時は表示可能な権利地域と照合します。 |
device | いいえ | 例: web、ios、android |
origin | 条件付き | キーにallowed_originsがある場合は必須で、そのいずれかと一致する必要があります。 |
preferences | いいえ | ホスト型WebView用の非PII視聴者設定。下記参照。 |
expires_in | いいえ | トークンTTL(秒)。既定1,800、絶対最大7,200、Production既定上限1,800。 |
preferences(視聴者シグナル)
ホスト型WebViewが字幕・音声の既定、自動再生、推薦へ適用し、分析用にセッション保存する任意オブジェクトです。スキーマは厳格で不明キーは422。生のPIIは禁止で、@や空白を含む値は422 validation_failedです。
| フィールド | 型 | 備考 |
|---|---|---|
preferred_languages | string[] (≤20) | 優先順のBCP-47・ISO言語コード |
preferred_genres | string[] (≤50) | パートナー側ジャンルタグ |
subtitle_language | string | 既定の字幕トラック |
audio_language | string | 既定の音声・吹替トラック |
autoplay_next | boolean | 次のエピソードを自動再生 |
maturity_rating | string | 視聴者の最大年齢レーティング |
このエンドポイントは任意のX-NU-Request-Idで冪等です。同じIDの再試行は元のレスポンスを返し、処理中の同時重複はconflict(409)を返します。
レスポンス
{
"data": {
"playback_session_id": "pbs_123",
"expires_at": "2026-06-24T00:30:00Z",
"webview_url": "https://signal-partners.newunivers.ai/w/pbs_123?t=...",
"manifest": {
"hls": "https://signal-partners.newunivers.ai/media/hls/pbs_123/signal-city/ep001/master.m3u8?token=...",
"dash": "https://signal-partners.newunivers.ai/media/dash/pbs_123/signal-city/ep001/manifest.mpd?token=..."
},
"tracking": {
"event_endpoint": "https://signal-partners.newunivers.ai/v1/events",
"required_events": [
"EPISODE_STARTED",
"PLAYBACK_PROGRESS",
"EPISODE_COMPLETED"
]
}
}
}同じ認可済みセッションを再生する2つの同等な方法があります。1つ選んでください。
webview_url(推奨): NUホストの再生専用ページです。WebView(WKWebView/android.webkit.WebView)または<iframe>で開きます。マニフェストを内部解決し、保存済みpreferencesを適用するためプレイヤー統合は不要です。セッションIDと署名付き?t=を含むのでシークレットとして扱い、expires_at後はキャッシュしません。manifest(自社プレイヤー): プレイヤー運用パートナー向け署名付きHLS/DASH URLです。各マニフェスト・セグメント要求で署名、TTL、セッションID、承認済みメディアパスを検証し、元マスターは返しません。検証はアプリの/mediaまたは同等のCloudflare edge workerで行い、URL規約は同じです。
両方式とも同じplayback_session_idに紐づき、イベント報告方法も同じです。
テストWebView
実セッション取得前にテストプレイヤーでWebView・iframe統合を検証します。トークン、セッション、メディア設定なしでEpisode 009 Confessionの9:16プレビューをすぐ再生します。
https://signal-partners.newunivers.ai/w/test?subtitle=ko&audio=ko&lang=ko&autoplay=1テストはwebview_urlと同じプレイヤーを使います。縦型サンプルがWebViewで動けば、実リンクも同じ9:16表示ポリシーです。
検証順序
検査は順番に行われます。タイトル・エピソードがなければresource_not_found(404)。解決後の認可失敗は403を返し、BLOCKEDセッションにblock_reasonを記録します。
- APIキーが有効で
playback:tokenを持ちます。キー環境がカタログとセッションのアクセス範囲を決めます。 - タイトルが環境に表示され、エピソードが所属する必要があります。違反すると
resource_not_foundです。 - 権利パッケージが未失効で、
status ∈ {CLEAR, RESTRICTED}とapiStreamingAllowed = trueを満たす必要があります。 - エピソードが
READYで、承認済み・未削除・HLS準備済み動画アセットがあり、権利はCLEARまたはRESTRICTEDである必要があります。 - Production:
countryが必須で、ACTIVE契約がタイトル・地域を含み、production_api_enabled = trueで、準備済み動画アセットをaccessLevel = streamとして含む必要があります。Sandbox: 契約不要で、country指定時は表示可能な権利地域と照合します。 - キーに
allowed_originsがある場合、originは必須で一致が必要です。allowed_ips設定時はトークン発行リクエストIPが一致する必要があります。発行時だけ適用され、トークンは視聴者IPに紐づきません。 - 同時セッション上限: Productionの契約またはSandboxのタイトルごとに
viewer_id_hash当たり最大PLAYBACK_MAX_CONCURRENT_SESSIONS件(既定3)。超過発行はBLOCKEDセッションを作りplayback_concurrency_limit(429)を返します。
エラー理由
| error.code | HTTP | 原因 |
|---|---|---|
resource_not_found | 404 | タイトルが環境に非表示、エピソードがない、または別タイトルに所属 |
missing_scope | 403 | キーにplayback:tokenがない |
license_not_active | 403 | ACTIVE契約がない、production_api_enabledがfalse、または表示可能なストリーミング権利パッケージがない |
territory_not_allowed | 403 | Productionのcountry不足、契約・権利地域外、必須origin不足、またはorigin/IPブロック |
episode_not_licensed | 403 | エピソードがREADYでない、準備済み動画がない、またはライセンス対象外 |
validation_failed | 422 | viewer_id_hashが生PIIに見える、またはpreferencesに不明キーや生PII('@'・空白)がある |
playback_concurrency_limit | 429 | この視聴者と契約・タイトルのアクティブセッションが多すぎる |
conflict | 409 | 処理中X-NU-Request-Idを使う同時重複リクエスト |
セッション
curl "https://signal-partners.newunivers.ai/v1/playback/sessions/pbs_123" \
-H "Authorization: Bearer nsp_live_xxx" -H "X-NU-Partner-Id: org_acme"{
"data": {
"playback_session_id": "pbs_123",
"title_id": "ttl_abc",
"episode_id": "ep_001",
"status": "issued",
"block_reason": null,
"preferences": { "subtitle_language": "ko", "autoplay_next": true },
"expires_at": "2026-06-24T00:30:00Z",
"started_at": null,
"completed_at": null
}
}APIは保存済みセッション状態を小文字で返します。フロー: issued → started → completed | expired | revoked | blocked。トークン発行でissuedを作り、EPISODE_STARTEDがstartedへ進めstarted_atを設定、EPISODE_COMPLETEDがcompletedへ進めcompleted_atを設定します。TTL後の読取はexpiredを投影し、このGETではDBに保存しません。認可失敗はblock_reason付きblockedを保存。不明IDはinvalid_playback_session(400)。
セッションを失効
curl -X POST "https://signal-partners.newunivers.ai/v1/playback/sessions/pbs_123/revoke" \
-H "Authorization: Bearer nsp_live_xxx" -H "X-NU-Partner-Id: org_acme"アクティブなissued/startedをrevokedにし同時数から除外します。レスポンスは実最終状態を返し、終了済みはcompleted、expiredなどを維持します。アプリの/mediaは次のマニフェスト要求で失効確認しますが、既存edge tokenはTTL中有効な場合があるためTTLは短くします。
viewer_id_hashと有効期限
viewer_id_hashは安定した視聴者IDとサーバー保管saltのSHA-256です。Productionは64文字小文字16進数、Sandboxは従来opaque IDを維持。NUはpreferencesを含め生PIIを受領・保存せず、@や空白を含む値を拒否します。- トークンは短命です: 既定1,800秒、絶対最大7,200、Production既定上限1,800。失効時に再発行し、
expires_at後はwebview_urlやマニフェストURLをキャッシュしません。webview_urlは署名トークンを含むためログ・共有リンクは禁止です。 - キー失効や契約無効化は発行済み再生トークンを取り消しません。TTLを短くし失効時に再発行してください。
返却されたplayback_session_idを使いイベントAPIで再生活動を報告します。