Catálogo federado de styx (Work → Edition → MediaAsset → SourceBinding): lectura de works y sus assets reproducibles, y alta de ficheros por escaneo con los facts del motor de medios del daemon. ## Errores Todo error es un Problem Details (RFC 9457) servido como `application/problem+json`, con `type`, `title`, `status` y un `code` estable. Los errores de dominio añaden `retryable` y `category` (`transient`, `permanent` o `recoverable`). Los de framework son `400 parse` (JSON roto), `404 not-found` (ruta inexistente) y `422 validation` (con `on`; `property` y `detail` sólo fuera de producción). Las denegaciones del Bearer son `401 unauthenticated` o `reauth-required`, `403 forbidden` y `429 rate-limited` (con `Retry-After`). Ningún problem repite el valor recibido y un recurso de otro actor responde 404, sin oráculo.
Responde 200 mientras el proceso atiende peticiones; no comprueba dependencias. La usan el HEALTHCHECK de la imagen y el compose (con GET: HEAD es opt-in en Elysia 2).
application/json
curl -X GET "https://example.com/health"{ "status": "ok", "timestamp": 0, "uptime": 0, "version": "string"}Kinds registrados (los 6 audiovisuales del core y los de los plugins content-type) con su descriptor de presentación. Un cliente trata un kind que no conoce con la presentación genérica (dec-0132 §4.2).
application/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X GET "https://example.com/kinds"{ "kinds": [ { "actions": [ "string" ], "editionKinds": [ "string" ], "facets": [ "string" ], "family": "string", "finite": true, "id": "string", "label": "string", "layouts": [ "file" ], "pipelines": [ "string" ], "relations": [ "string" ], "requiredFacets": [ "string" ] } ]}Pide los facts del fichero al motor de medios del daemon (qry.media.probe sobre una raíz de STYX_MEDIA_ROOTS, nunca una ruta absoluta), crea o actualiza el asset y su MediaIndex y publica evt.catalog.assetIndexed. Un fichero que el motor dice que no es un medio entra como asset unidentified (indexed=false, sin índice) en vez de rechazarse. Gasta un presupuesto propio por actor (5/s, ráfaga 20) además del del servicio.
Acceso: Bearer de identity con policy resource:asset:scan.
bearerAuth Access token de identity-svc (JWT EdDSA, caducidad corta). Se verifica en local y después contra la sesión viva (revocation-aware).
In: header
application/json
TypeScript Definitions
Use the request body type in TypeScript.
1 <= lengthapplication/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X POST "https://example.com/scan" \ -H "Content-Type: application/json" \ -d '{ "path": "string" }'{ "asset": { "container": "string", "createdAt": 0, "editionId": "string", "fastHash": "string", "id": "string", "identification": "identified", "kind": "logical-composition", "layout": "file", "path": "string", "sizeBytes": 0, "updatedAt": 0 }, "index": { "assetId": "string", "bitrateBps": 0, "capabilities": [ "string" ], "container": "string", "createdAt": 0, "durationMs": 0, "id": "string", "indexVersion": 0, "keyframesMs": [ 0 ], "streams": [ { "bitRateBps": 0, "channels": 0, "codec": "string", "defaultFlag": true, "frameRate": 0, "height": 0, "index": 0, "language": "string", "sampleRate": 0, "type": "video", "width": 0 } ] }, "indexed": true}curl -X GET "https://example.com/version"{ "commit": "string", "component": "string", "train": "string", "version": "string"}Works del catálogo federado, paginados (page desde 1, pageSize por defecto 50, máximo 200), con el total. Lectura pública de laboratorio: aún no hay bibliotecas privadas.
1 <= value1 <= value <= 200application/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X GET "https://example.com/works"{ "total": 0, "works": [ { "createdAt": 0, "id": "string", "kind": "string", "originalTitle": "string", "title": "string", "updatedAt": 0, "year": 0 } ]}Un work del catálogo. 404 CATALOG_WORK_NOT_FOUND si no existe.
1 <= length <= 128application/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X GET "https://example.com/works/string"{ "work": { "createdAt": 0, "id": "string", "kind": "string", "originalTitle": "string", "title": "string", "updatedAt": 0, "year": 0 }}Assets de las editions del work, indexados primero y luego el más reciente. indexed=false significa que el catálogo no tiene su MediaIndex: POST /sessions de playback-svc respondería PLAYBACK_NO_CAPABILITIES.
1 <= length <= 128application/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X GET "https://example.com/works/string/assets"{ "assets": [ { "assetId": "string", "container": "string", "durationMs": 0, "editionId": "string", "facets": [ "string" ], "identification": "identified", "indexed": true, "layout": "file", "sizeBytes": 0 } ]}Relaciones padre → hijo del work ordenadas por ordinal (ruta numérica: [1, 3] = temporada 1, episodio 3). 404 CATALOG_WORK_NOT_FOUND si el work no existe.
1 <= length <= 128application/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X GET "https://example.com/works/string/relations"{ "relations": [ { "childWorkId": "string", "createdAt": 0, "ordinal": [ 0 ], "parentWorkId": "string", "rel": "string" } ]}