再生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は禁止。
countryProductionは必須 / 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_languagesstring[] (≤20)優先順のBCP-47・ISO言語コード
preferred_genresstring[] (≤50)パートナー側ジャンルタグ
subtitle_languagestring既定の字幕トラック
audio_languagestring既定の音声・吹替トラック
autoplay_nextboolean次のエピソードを自動再生
maturity_ratingstring視聴者の最大年齢レーティング

このエンドポイントは任意の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を記録します。

  1. APIキーが有効でplayback:tokenを持ちます。キー環境がカタログとセッションのアクセス範囲を決めます。
  2. タイトルが環境に表示され、エピソードが所属する必要があります。違反するとresource_not_foundです。
  3. 権利パッケージが未失効で、status ∈ {CLEAR, RESTRICTED}とapiStreamingAllowed = trueを満たす必要があります。
  4. エピソードがREADYで、承認済み・未削除・HLS準備済み動画アセットがあり、権利はCLEARまたはRESTRICTEDである必要があります。
  5. Production: countryが必須で、ACTIVE契約がタイトル・地域を含み、production_api_enabled = trueで、準備済み動画アセットをaccessLevel = streamとして含む必要があります。Sandbox: 契約不要で、country指定時は表示可能な権利地域と照合します。
  6. キーにallowed_originsがある場合、originは必須で一致が必要です。allowed_ips設定時はトークン発行リクエストIPが一致する必要があります。発行時だけ適用され、トークンは視聴者IPに紐づきません。
  7. 同時セッション上限: Productionの契約またはSandboxのタイトルごとにviewer_id_hash当たり最大PLAYBACK_MAX_CONCURRENT_SESSIONS件(既定3)。超過発行はBLOCKEDセッションを作りplayback_concurrency_limit(429)を返します。

エラー理由

error.codeHTTP原因
resource_not_found404タイトルが環境に非表示、エピソードがない、または別タイトルに所属
missing_scope403キーにplayback:tokenがない
license_not_active403ACTIVE契約がない、production_api_enabledがfalse、または表示可能なストリーミング権利パッケージがない
territory_not_allowed403Productionのcountry不足、契約・権利地域外、必須origin不足、またはorigin/IPブロック
episode_not_licensed403エピソードがREADYでない、準備済み動画がない、またはライセンス対象外
validation_failed422viewer_id_hashが生PIIに見える、またはpreferencesに不明キーや生PII('@'・空白)がある
playback_concurrency_limit429この視聴者と契約・タイトルのアクティブセッションが多すぎる
conflict409処理中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で再生活動を報告します。