API HTTPplayback-svc

POST /sessions

Abrir una sesión de playback (PlaybackIntent → SessionDescriptor)

ImplementadoSin versión del tren todavía· generada desde apps/docs/generated/openapi/playback-svc.json

Página generada desde apps/playback-svc/src/app.aot.ts. No se edita a mano: bun run docs:gen la regenera y bun run docs:check falla si difiere.

POST /sessions

El Planner resuelve el intent en un PlaybackPlan composicional (mode derivado, no lo manda el cliente) y la entrega; la sesión y su capability quedan ligadas al actor. Sin MediaIndex del asset: PLAYBACK_NO_CAPABILITIES.

Acceso: Bearer de identity con policy resource:asset:play.

CampoValor
Servicioplayback-svc
operationIdpostSessions
Policy (dec-0118 §3)resource:asset:play
Tagsplayback

Cuerpo

Requerido: sí.

application/json

{
  "type": "object",
  "required": [
    "intent"
  ],
  "properties": {
    "intent": {
      "type": "object",
      "required": [
        "assetId",
        "client"
      ],
      "properties": {
        "assetId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        },
        "client": {
          "type": "object",
          "required": [
            "video",
            "audio",
            "containers"
          ],
          "properties": {
            "video": {
              "type": "array",
              "items": {},
              "maxItems": 64
            },
            "audio": {
              "type": "array",
              "items": {},
              "maxItems": 64
            },
            "containers": {
              "type": "array",
              "items": {},
              "maxItems": 64
            },
            "dynamicRange": {
              "type": "array",
              "items": {},
              "maxItems": 64
            },
            "subtitles": {
              "type": "array",
              "items": {},
              "maxItems": 64
            },
            "supportsRemux": {
              "type": "boolean"
            }
          }
        },
        "preferences": {
          "type": "object",
          "properties": {
            "forceSubtitleLang": {
              "type": "string"
            },
            "forceAudioLang": {
              "type": "string"
            },
            "maxQuality": {
              "type": "string"
            },
            "preferHdr": {
              "type": "boolean"
            },
            "mediaEngine": {
              "type": "string",
              "enum": [
                "zig",
                "libav",
                "auto"
              ]
            }
          }
        }
      }
    }
  },
  "description": "Intent de reproducción: asset y capabilities del cliente (video, audio y contenedores obligatorios), con preferencias opcionales. Las entradas de capability viajan sin cerrar su vocabulario (forward-compat)."
}

Respuestas

200

Descriptor de la sesión: el PlaybackPlan público (sin URIs de origen), la entrega (transporte, endpoint y, si se empaqueta, la capability) y caducidad.

application/json

{
  "type": "object",
  "required": [
    "descriptor"
  ],
  "properties": {
    "descriptor": {
      "type": "object",
      "required": [
        "sessionId",
        "assetId",
        "plan",
        "delivery",
        "actor",
        "createdAt",
        "expiresAt"
      ],
      "properties": {
        "sessionId": {
          "type": "string"
        },
        "assetId": {
          "type": "string"
        },
        "plan": {
          "type": "object",
          "required": [
            "source",
            "container",
            "video",
            "audio",
            "subtitles",
            "delivery",
            "reasons",
            "estimatedCost",
            "mode"
          ],
          "properties": {
            "source": {
              "type": "object",
              "required": [
                "kind",
                "score"
              ],
              "properties": {
                "kind": {
                  "type": "string"
                },
                "score": {
                  "type": "number"
                }
              }
            },
            "container": {
              "type": "object",
              "required": [
                "action",
                "input",
                "output"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "enum": [
                    "copy",
                    "remux",
                    "package"
                  ]
                },
                "input": {
                  "type": "string",
                  "enum": [
                    "matroska",
                    "mp4",
                    "webm",
                    "mpegts",
                    "flac",
                    "ogg",
                    "unknown"
                  ]
                },
                "output": {
                  "type": "string",
                  "enum": [
                    "matroska",
                    "mp4",
                    "webm",
                    "mpegts",
                    "flac",
                    "ogg",
                    "unknown"
                  ]
                }
              }
            },
            "video": {
              "type": "object",
              "required": [
                "action",
                "codec",
                "filters"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "enum": [
                    "copy",
                    "transcode"
                  ]
                },
                "codec": {
                  "type": "string",
                  "enum": [
                    "h264",
                    "hevc",
                    "av1",
                    "vp9",
                    "vp8",
                    "vvc"
                  ]
                },
                "filters": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "kind",
                      "params"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": [
                          "scale",
                          "tonemap",
                          "deinterlace",
                          "fps",
                          "crop"
                        ]
                      },
                      "params": {
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "number"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            },
            "audio": {
              "type": "object",
              "required": [
                "action",
                "codec"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "enum": [
                    "copy",
                    "transcode"
                  ]
                },
                "codec": {
                  "type": "string",
                  "enum": [
                    "aac",
                    "ac3",
                    "eac3",
                    "truehd",
                    "dts",
                    "dts-hd",
                    "opus",
                    "flac",
                    "pcm",
                    "mp3",
                    "mp2",
                    "vorbis"
                  ]
                },
                "channels": {
                  "type": "string",
                  "enum": [
                    "mono",
                    "stereo",
                    "5.1",
                    "7.1",
                    "5.1.2",
                    "7.1.4"
                  ]
                }
              }
            },
            "subtitles": {
              "type": "object",
              "required": [
                "action"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "enum": [
                    "none",
                    "passthrough",
                    "convert",
                    "burn"
                  ]
                },
                "format": {
                  "type": "string",
                  "enum": [
                    "srt",
                    "vtt",
                    "ass",
                    "pgs",
                    "dvd-sub",
                    "teletext"
                  ]
                }
              }
            },
            "delivery": {
              "type": "object",
              "required": [
                "transport",
                "url",
                "tokenTtlMs"
              ],
              "properties": {
                "transport": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "tokenTtlMs": {
                  "type": "number"
                }
              }
            },
            "reasons": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "kind",
                  "message"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "container-direct",
                      "container-remux",
                      "video-direct",
                      "video-transcode",
                      "video-tonemap-hdr",
                      "audio-direct",
                      "audio-transcode",
                      "subtitle-none",
                      "subtitle-passthrough",
                      "subtitle-convert",
                      "subtitle-burn",
                      "source-selected",
                      "media-engine",
                      "media-engine-fallback"
                    ]
                  },
                  "message": {
                    "type": "string"
                  }
                }
              }
            },
            "estimatedCost": {
              "type": "object",
              "required": [
                "tier",
                "score",
                "serverSideCompute"
              ],
              "properties": {
                "tier": {
                  "type": "string",
                  "enum": [
                    "free",
                    "cheap",
                    "moderate",
                    "expensive"
                  ]
                },
                "score": {
                  "type": "number"
                },
                "serverSideCompute": {
                  "type": "boolean"
                }
              }
            },
            "mode": {
              "type": "string",
              "enum": [
                "direct",
                "adapted",
                "video-transcode"
              ]
            }
          }
        },
        "delivery": {
          "type": "object",
          "required": [
            "transport",
            "endpoint"
          ],
          "properties": {
            "transport": {
              "type": "string"
            },
            "endpoint": {
              "type": "string"
            },
            "tcpEndpoint": {
              "type": "string"
            },
            "certHash": {
              "type": "string"
            },
            "tokenTtlMs": {
              "type": "integer"
            },
            "packaging": {
              "type": "object",
              "required": [
                "packagingId",
                "engine",
                "codecs",
                "segments",
                "targetDurationS",
                "capability"
              ],
              "properties": {
                "packagingId": {
                  "type": "string"
                },
                "engine": {
                  "type": "string",
                  "enum": [
                    "zig",
                    "libav"
                  ]
                },
                "codecs": {
                  "type": "string"
                },
                "segments": {
                  "type": "integer",
                  "minimum": 1
                },
                "targetDurationS": {
                  "type": "integer",
                  "minimum": 1
                },
                "capability": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 512
                }
              }
            }
          }
        },
        "actor": {
          "type": "object",
          "required": [
            "service"
          ],
          "properties": {
            "userId": {
              "type": "string"
            },
            "sessionId": {
              "type": "string"
            },
            "service": {
              "type": "string"
            },
            "roles": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "createdAt": {
          "type": "string"
        },
        "expiresAt": {
          "type": "string"
        }
      }
    }
  },
  "description": "Descriptor de la sesión: el PlaybackPlan público (sin URIs de origen), la entrega (transporte, endpoint y, si se empaqueta, la capability) y caducidad."
}

400

Problem Details (RFC 9457), status 400. Códigos: parse, PLAYBACK_INVALID_INPUT.

application/problem+json

{
  "anyOf": [
    {
      "type": "object",
      "required": [
        "type",
        "title",
        "status",
        "code"
      ],
      "properties": {
        "type": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "status": {
          "type": "number",
          "const": 400
        },
        "code": {
          "type": "string",
          "const": "parse"
        },
        "detail": {
          "type": "string"
        }
      },
      "x-styx-media-type": "application/problem+json"
    },
    {
      "type": "object",
      "required": [
        "type",
        "title",
        "status",
        "code",
        "retryable",
        "category"
      ],
      "properties": {
        "type": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "status": {
          "type": "number",
          "const": 400
        },
        "code": {
          "type": "string",
          "const": "PLAYBACK_INVALID_INPUT"
        },
        "detail": {
          "type": "string"
        },
        "instance": {
          "type": "string"
        },
        "retryable": {
          "type": "boolean"
        },
        "category": {
          "type": "string",
          "enum": [
            "transient",
            "permanent",
            "recoverable"
          ]
        }
      },
      "x-styx-media-type": "application/problem+json"
    }
  ]
}

401

Problem Details (RFC 9457), status 401. Códigos: unauthenticated, reauth-required.

application/problem+json

{
  "type": "object",
  "required": [
    "type",
    "title",
    "status",
    "code"
  ],
  "properties": {
    "type": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "status": {
      "type": "number",
      "const": 401
    },
    "code": {
      "type": "string",
      "enum": [
        "unauthenticated",
        "reauth-required"
      ]
    },
    "detail": {
      "type": "string"
    }
  },
  "x-styx-media-type": "application/problem+json"
}

403

Problem Details (RFC 9457), status 403. Códigos: forbidden.

application/problem+json

{
  "type": "object",
  "required": [
    "type",
    "title",
    "status",
    "code"
  ],
  "properties": {
    "type": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "status": {
      "type": "number",
      "const": 403
    },
    "code": {
      "type": "string",
      "const": "forbidden"
    },
    "detail": {
      "type": "string"
    }
  },
  "x-styx-media-type": "application/problem+json"
}

404

Problem Details (RFC 9457), status 404. Códigos: PLAYBACK_SOURCE_UNRESOLVED, PLAYBACK_SESSION_NOT_FOUND.

application/problem+json

{
  "type": "object",
  "required": [
    "type",
    "title",
    "status",
    "code",
    "retryable",
    "category"
  ],
  "properties": {
    "type": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "status": {
      "type": "number",
      "const": 404
    },
    "code": {
      "type": "string",
      "enum": [
        "PLAYBACK_SOURCE_UNRESOLVED",
        "PLAYBACK_SESSION_NOT_FOUND"
      ]
    },
    "detail": {
      "type": "string"
    },
    "instance": {
      "type": "string"
    },
    "retryable": {
      "type": "boolean"
    },
    "category": {
      "type": "string",
      "enum": [
        "transient",
        "permanent",
        "recoverable"
      ]
    }
  },
  "x-styx-media-type": "application/problem+json"
}

409

Problem Details (RFC 9457), status 409. Códigos: PLAYBACK_NO_CAPABILITIES.

application/problem+json

{
  "type": "object",
  "required": [
    "type",
    "title",
    "status",
    "code",
    "retryable",
    "category"
  ],
  "properties": {
    "type": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "status": {
      "type": "number",
      "const": 409
    },
    "code": {
      "type": "string",
      "const": "PLAYBACK_NO_CAPABILITIES"
    },
    "detail": {
      "type": "string"
    },
    "instance": {
      "type": "string"
    },
    "retryable": {
      "type": "boolean"
    },
    "category": {
      "type": "string",
      "enum": [
        "transient",
        "permanent",
        "recoverable"
      ]
    }
  },
  "x-styx-media-type": "application/problem+json"
}

422

Problem Details (RFC 9457), status 422. Códigos: validation, PLAYBACK_PLAN_FAILED.

application/problem+json

{
  "anyOf": [
    {
      "type": "object",
      "required": [
        "type",
        "title",
        "status",
        "code"
      ],
      "properties": {
        "type": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "status": {
          "type": "number",
          "const": 422
        },
        "code": {
          "type": "string",
          "const": "validation"
        },
        "on": {
          "type": "string"
        },
        "property": {
          "type": "string"
        },
        "detail": {
          "type": "string"
        }
      },
      "x-styx-media-type": "application/problem+json"
    },
    {
      "type": "object",
      "required": [
        "type",
        "title",
        "status",
        "code",
        "retryable",
        "category"
      ],
      "properties": {
        "type": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "status": {
          "type": "number",
          "const": 422
        },
        "code": {
          "type": "string",
          "const": "PLAYBACK_PLAN_FAILED"
        },
        "detail": {
          "type": "string"
        },
        "instance": {
          "type": "string"
        },
        "retryable": {
          "type": "boolean"
        },
        "category": {
          "type": "string",
          "enum": [
            "transient",
            "permanent",
            "recoverable"
          ]
        }
      },
      "x-styx-media-type": "application/problem+json"
    }
  ]
}

429

Problem Details (RFC 9457), status 429. Códigos: rate-limited, PLAYBACK_TOO_MANY_SESSIONS.

application/problem+json

{
  "anyOf": [
    {
      "type": "object",
      "required": [
        "type",
        "title",
        "status",
        "code"
      ],
      "properties": {
        "type": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "status": {
          "type": "number",
          "const": 429
        },
        "code": {
          "type": "string",
          "const": "rate-limited"
        },
        "detail": {
          "type": "string"
        }
      },
      "x-styx-media-type": "application/problem+json"
    },
    {
      "type": "object",
      "required": [
        "type",
        "title",
        "status",
        "code",
        "retryable",
        "category"
      ],
      "properties": {
        "type": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "status": {
          "type": "number",
          "const": 429
        },
        "code": {
          "type": "string",
          "const": "PLAYBACK_TOO_MANY_SESSIONS"
        },
        "detail": {
          "type": "string"
        },
        "instance": {
          "type": "string"
        },
        "retryable": {
          "type": "boolean"
        },
        "category": {
          "type": "string",
          "enum": [
            "transient",
            "permanent",
            "recoverable"
          ]
        }
      },
      "x-styx-media-type": "application/problem+json"
    }
  ]
}

502

Problem Details (RFC 9457), status 502. Códigos: PLAYBACK_CATALOG_UNAVAILABLE.

application/problem+json

{
  "type": "object",
  "required": [
    "type",
    "title",
    "status",
    "code",
    "retryable",
    "category"
  ],
  "properties": {
    "type": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "status": {
      "type": "number",
      "const": 502
    },
    "code": {
      "type": "string",
      "const": "PLAYBACK_CATALOG_UNAVAILABLE"
    },
    "detail": {
      "type": "string"
    },
    "instance": {
      "type": "string"
    },
    "retryable": {
      "type": "boolean"
    },
    "category": {
      "type": "string",
      "enum": [
        "transient",
        "permanent",
        "recoverable"
      ]
    }
  },
  "x-styx-media-type": "application/problem+json"
}