mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 20:15:10 +00:00
4990 lines
206 KiB
HTML
4990 lines
206 KiB
HTML
|
|
<!doctype html>
|
|
<html lang="en" class="no-js">
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
|
|
<meta name="description" content="Movie, TV, and Music archival software — user guide and REST API reference">
|
|
|
|
|
|
|
|
<link rel="canonical" href="https://docs.unshackle.dev/dev/rest-api/endpoints/">
|
|
|
|
|
|
<link rel="prev" href="../authentication/">
|
|
|
|
|
|
<link rel="next" href="../job-lifecycle/">
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="icon" href="../../../assets/favicon.svg">
|
|
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
|
|
|
|
|
|
|
|
<title>Endpoints - unshackle</title>
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../../../assets/stylesheets/main.ec1eaa64.min.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../../../assets/stylesheets/palette.ab4e12ef.min.css">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
|
|
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../../../assets/_mkdocstrings.css">
|
|
|
|
<script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
|
|
|
|
|
|
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="indigo">
|
|
|
|
|
|
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
|
|
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
|
|
<label class="md-overlay" for="__drawer"></label>
|
|
<div data-md-component="skip">
|
|
|
|
|
|
<a href="#rest-api-endpoints" class="md-skip">
|
|
Skip to content
|
|
</a>
|
|
|
|
</div>
|
|
<div data-md-component="announce">
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<header class="md-header" data-md-component="header">
|
|
<nav class="md-header__inner md-grid" aria-label="Header">
|
|
<a href="../../.." title="unshackle" class="md-header__button md-logo" aria-label="unshackle" data-md-component="logo">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m800-274-80-80v-206H514l-80-80h166v-80q0-50-34.5-85T481-840q-50 0-84 34.5T363-720v9l-73-73q22-61 75-98.5T481-920q83 0 141 58.5T680-720v80h40q33 0 56.5 23.5T800-560v286Zm20 246-62-62q-11 5-20 7.5T720-80H240q-33 0-56.5-23.5T160-160v-400q0-25 14.5-46t37.5-30L28-820l56-56L876-84l-56 56ZM686-160 539-309q-11 11-25.5 17t-31.5 6q-33 0-56.5-23.5T402-366q0-17 6-31.5t17-25.5L286-560h-46v400h446ZM486-360Zm131-97Z"/></svg>
|
|
|
|
</a>
|
|
<label class="md-header__button md-icon" for="__drawer">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
|
|
</label>
|
|
<div class="md-header__title" data-md-component="header-title">
|
|
<div class="md-header__ellipsis">
|
|
<div class="md-header__topic">
|
|
<span class="md-ellipsis">
|
|
unshackle
|
|
</span>
|
|
</div>
|
|
<div class="md-header__topic" data-md-component="header-topic">
|
|
<span class="md-ellipsis">
|
|
|
|
Endpoints
|
|
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<form class="md-header__option" data-md-component="palette">
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="(prefers-color-scheme)" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
|
|
|
|
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1M8 13h8v-2H8zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 5-5 5 5 0 0 0-5-5"/></svg>
|
|
</label>
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
|
|
|
|
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3"/></svg>
|
|
</label>
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to system preference" type="radio" name="__palette" id="__palette_2">
|
|
|
|
<label class="md-header__button md-icon" title="Switch to system preference" for="__palette_0" hidden>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5M7 15a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3"/></svg>
|
|
</label>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-header__button md-icon" for="__search">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
|
</label>
|
|
<div class="md-search" data-md-component="search" role="dialog">
|
|
<label class="md-search__overlay" for="__search"></label>
|
|
<div class="md-search__inner" role="search">
|
|
<form class="md-search__form" name="search">
|
|
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
|
|
<label class="md-search__icon md-icon" for="__search">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
|
</label>
|
|
<nav class="md-search__options" aria-label="Search">
|
|
|
|
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
|
|
</a>
|
|
|
|
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
</button>
|
|
</nav>
|
|
|
|
<div class="md-search__suggest" data-md-component="search-suggest"></div>
|
|
|
|
</form>
|
|
<div class="md-search__output">
|
|
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
|
|
<div class="md-search-result" data-md-component="search-result">
|
|
<div class="md-search-result__meta">
|
|
Initializing search
|
|
</div>
|
|
<ol class="md-search-result__list" role="presentation"></ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="md-header__source">
|
|
<a href="https://github.com/unshackle-dl/unshackle" title="Go to repository" class="md-source" data-md-component="source">
|
|
<div class="md-source__icon md-icon">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
|
</div>
|
|
<div class="md-source__repository">
|
|
unshackle-dl/unshackle
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
</header>
|
|
|
|
<div class="md-container" data-md-component="container">
|
|
|
|
|
|
|
|
|
|
|
|
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
|
|
<div class="md-grid">
|
|
<ul class="md-tabs__list">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../../.." class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Home
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../../../getting-started/installation/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Getting Started
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../../../guide/downloading/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
User Guide
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../../../reference/configuration/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Configuration
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item md-tabs__item--active">
|
|
<a href="../../creating-a-service/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Developer
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../../../reference/api/service/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
API Reference
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
|
|
|
|
|
|
<main class="md-main" data-md-component="main">
|
|
<div class="md-main__inner md-grid">
|
|
|
|
|
|
|
|
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
|
|
<div class="md-sidebar__scrollwrap">
|
|
<div class="md-sidebar__inner">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
|
|
<label class="md-nav__title" for="__drawer">
|
|
<a href="../../.." title="unshackle" class="md-nav__button md-logo" aria-label="unshackle" data-md-component="logo">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m800-274-80-80v-206H514l-80-80h166v-80q0-50-34.5-85T481-840q-50 0-84 34.5T363-720v9l-73-73q22-61 75-98.5T481-920q83 0 141 58.5T680-720v80h40q33 0 56.5 23.5T800-560v286Zm20 246-62-62q-11 5-20 7.5T720-80H240q-33 0-56.5-23.5T160-160v-400q0-25 14.5-46t37.5-30L28-820l56-56L876-84l-56 56ZM686-160 539-309q-11 11-25.5 17t-31.5 6q-33 0-56.5-23.5T402-366q0-17 6-31.5t17-25.5L286-560h-46v400h446ZM486-360Zm131-97Z"/></svg>
|
|
|
|
</a>
|
|
unshackle
|
|
</label>
|
|
|
|
<div class="md-nav__source">
|
|
<a href="https://github.com/unshackle-dl/unshackle" title="Go to repository" class="md-source" data-md-component="source">
|
|
<div class="md-source__icon md-icon">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
|
</div>
|
|
<div class="md-source__repository">
|
|
unshackle-dl/unshackle
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../.." class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Home
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Getting Started
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
|
|
<label class="md-nav__title" for="__nav_2">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
Getting Started
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../getting-started/installation/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Installation
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../getting-started/quickstart/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Quick Start
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../getting-started/configuration-file/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
The Configuration File
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
User Guide
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
|
|
<label class="md-nav__title" for="__nav_3">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
User Guide
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../guide/downloading/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Downloading
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../guide/cli-reference/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
CLI Reference
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../guide/drm-and-cdm/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
DRM & CDM Setup
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../guide/proxies-and-vpn/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Proxies & VPN
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../guide/vaults/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Key Vaults
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../guide/output-and-naming/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Output & Naming
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../guide/subtitles/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Subtitles
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../guide/troubleshooting/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Troubleshooting
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
|
|
|
|
|
|
<div class="md-nav__link md-nav__container">
|
|
<a href="../../../reference/configuration/" class="md-nav__link ">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Configuration
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<label class="md-nav__link " for="__nav_4" id="__nav_4_label" tabindex="0">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
</div>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
|
|
<label class="md-nav__title" for="__nav_4">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
Configuration
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/directories/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Directories
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/services/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Services & Authentication
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/download/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Download & Processing
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/output/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Output & Naming
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/drm/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
DRM & CDM
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/network/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Network & Proxy
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/vaults/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Key Vaults
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/post-scripts/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Post-Download Scripts
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/misc/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Other Settings
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/configuration/example/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Annotated Example
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" checked>
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Developer
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="true">
|
|
<label class="md-nav__title" for="__nav_5">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
Developer
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../creating-a-service/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Creating a Service
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../service-architecture/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Service Architecture
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_3" checked>
|
|
|
|
|
|
<div class="md-nav__link md-nav__container">
|
|
<a href="../" class="md-nav__link ">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
REST API
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<label class="md-nav__link " for="__nav_5_3" id="__nav_5_3_label" tabindex="">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
</div>
|
|
|
|
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_3_label" aria-expanded="true">
|
|
<label class="md-nav__title" for="__nav_5_3">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
REST API
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../quickstart/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Quick Start
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../authentication/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Authentication
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--active">
|
|
|
|
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__link md-nav__link--active" for="__toc">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Endpoints
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<a href="./" class="md-nav__link md-nav__link--active">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Endpoints
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__title" for="__toc">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
Table of contents
|
|
</label>
|
|
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#conventions" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Conventions
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#general-endpoints" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
General endpoints
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="General endpoints">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apihealth" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/health
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apiservices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/services
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisearch" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/search
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apilist-titles" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/list-titles
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apilist-tracks" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/list-tracks
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#download-jobs" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Download jobs
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Download jobs">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apidownload" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/download
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apidownloadjobs" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/download/jobs
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apidownloadjobsjob_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/download/jobs/{job_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apidownloadjobsjob_idevents" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/download/jobs/{job_id}/events
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#delete-apidownloadjobsjob_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
DELETE /api/download/jobs/{job_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apidownloadjobsclear-finished" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/download/jobs/clear-finished
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apidownloadjobsjob_idretry" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/download/jobs/{job_id}/retry
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apidownloadjobsjob_idpriority" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/download/jobs/{job_id}/priority
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#server-management" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Server management
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Server management">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apiprofiles" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/profiles
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apiconfig" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/config
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apihistory" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/history
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#delete-apihistoryjob_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
DELETE /api/history/{job_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apimaintenanceclear-cache-and-post-apimaintenanceclear-temp" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/maintenance/clear-cache and POST /api/maintenance/clear-temp
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apimaintenancerefresh-services" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/maintenance/refresh-services
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apienvcheck" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/env/check
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#remote-dl-sessions" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Remote-dl sessions
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Remote-dl sessions">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#session-lifecycle-overview" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Session lifecycle overview
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessioncreate" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/create
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apisessionsession_idprompt" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/session/{session_id}/prompt
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessionsession_idprompt" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/{session_id}/prompt
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apisessionsession_idtitles" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/session/{session_id}/titles
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessionsession_idtracks" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/{session_id}/tracks
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessionsession_idsegments" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/{session_id}/segments
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessionsession_idlicense" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/{session_id}/license
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apisessionsession_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/session/{session_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#delete-apisessionsession_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
DELETE /api/session/{session_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#error-responses" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Error responses
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Error responses">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#error-codes-and-default-status" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Error codes and default status
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#see-also" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
See also
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../job-lifecycle/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Job Lifecycle
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../remote-sessions/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Remote Sessions
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../errors/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Error Responses
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
API Reference
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
|
|
<label class="md-nav__title" for="__nav_6">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
API Reference
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/api/service/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Service
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/api/config/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Config
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/api/tracks/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Tracks
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/api/titles/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Titles
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../../../reference/api/drm/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
DRM
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
|
|
<div class="md-sidebar__scrollwrap">
|
|
<div class="md-sidebar__inner">
|
|
|
|
|
|
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__title" for="__toc">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
Table of contents
|
|
</label>
|
|
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#conventions" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Conventions
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#general-endpoints" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
General endpoints
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="General endpoints">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apihealth" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/health
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apiservices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/services
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisearch" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/search
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apilist-titles" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/list-titles
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apilist-tracks" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/list-tracks
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#download-jobs" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Download jobs
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Download jobs">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apidownload" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/download
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apidownloadjobs" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/download/jobs
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apidownloadjobsjob_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/download/jobs/{job_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apidownloadjobsjob_idevents" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/download/jobs/{job_id}/events
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#delete-apidownloadjobsjob_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
DELETE /api/download/jobs/{job_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apidownloadjobsclear-finished" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/download/jobs/clear-finished
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apidownloadjobsjob_idretry" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/download/jobs/{job_id}/retry
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apidownloadjobsjob_idpriority" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/download/jobs/{job_id}/priority
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#server-management" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Server management
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Server management">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apiprofiles" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/profiles
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apiconfig" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/config
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apihistory" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/history
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#delete-apihistoryjob_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
DELETE /api/history/{job_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apimaintenanceclear-cache-and-post-apimaintenanceclear-temp" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/maintenance/clear-cache and POST /api/maintenance/clear-temp
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apimaintenancerefresh-services" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/maintenance/refresh-services
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apienvcheck" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/env/check
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#remote-dl-sessions" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Remote-dl sessions
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Remote-dl sessions">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#session-lifecycle-overview" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Session lifecycle overview
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessioncreate" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/create
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apisessionsession_idprompt" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/session/{session_id}/prompt
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessionsession_idprompt" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/{session_id}/prompt
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apisessionsession_idtitles" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/session/{session_id}/titles
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessionsession_idtracks" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/{session_id}/tracks
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessionsession_idsegments" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/{session_id}/segments
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#post-apisessionsession_idlicense" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
POST /api/session/{session_id}/license
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#get-apisessionsession_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
GET /api/session/{session_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#delete-apisessionsession_id" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
DELETE /api/session/{session_id}
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#error-responses" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Error responses
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Error responses">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#error-codes-and-default-status" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Error codes and default status
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#see-also" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
See also
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="md-content" data-md-component="content">
|
|
|
|
<article class="md-content__inner md-typeset">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h1 id="rest-api-endpoints">REST API Endpoints<a class="headerlink" href="#rest-api-endpoints" title="Permanent link">¶</a></h1>
|
|
<p>This is the full endpoint reference for the unshackle REST API. It covers every route: its method and path, the request body it accepts, the response shape it returns, and the status codes it can produce. Routes are grouped into general, download jobs, server management, and remote-dl sessions.</p>
|
|
<p>Start the server with <a href="../../../guide/cli-reference/"><code>unshackle serve</code></a>. By default it binds to <code>127.0.0.1:8786</code>, and every route lives under the <code>/api/</code> prefix. Authentication, server modes, and the <code>X-Secret-Key</code> header are covered in detail on the <a href="../authentication/">Authentication</a> page. Read that first if you have not already. For an end-to-end walkthrough, see the <a href="../quickstart/">Quickstart</a>.</p>
|
|
<div class="admonition note">
|
|
<p class="admonition-title">Base URL</p>
|
|
<p>All examples below assume a base URL of <code>http://127.0.0.1:8786</code>. Replace the host and port to match your own <code>unshackle serve -h <host> -p <port></code> invocation.</p>
|
|
</div>
|
|
<div class="admonition tip">
|
|
<p class="admonition-title">Interactive docs</p>
|
|
<p>A live Swagger UI is mounted at <strong><code>/api/docs/</code></strong> whenever the server is not running in <code>--remote-only</code> mode. Its title is "Unshackle REST API" and its version tracks the installed package version. In API-only mode with a key configured, the Swagger UI itself sits behind <code>X-Secret-Key</code>; only <code>/api/health</code> is exempt.</p>
|
|
</div>
|
|
<h2 id="conventions">Conventions<a class="headerlink" href="#conventions" title="Permanent link">¶</a></h2>
|
|
<ul>
|
|
<li><strong>Authentication.</strong> Every request except <code>GET /api/health</code> requires the <code>X-Secret-Key</code> header when a key is configured. Starting the server with <code>--no-key</code> disables the check entirely. See <a href="../authentication/">Authentication</a>.</li>
|
|
<li><strong>Content type.</strong> Request bodies are JSON (<code>Content-Type: application/json</code>); all success responses are JSON unless a <code>204 No Content</code> is documented.</li>
|
|
<li><strong>CORS.</strong> Every response carries permissive CORS headers, and <code>OPTIONS</code> preflight requests are answered automatically.</li>
|
|
<li><strong>Compression.</strong> JSON responses of 256 bytes or more are gzip-compressed when the client sends <code>Accept-Encoding: gzip</code>.</li>
|
|
<li><strong>Service allowlist.</strong> Service-facing endpoints are filtered by the effective allowlist for your API key (the intersection of the global <code>serve.services</code> list and your per-key list). Services you are not allowed to use are treated as unknown.</li>
|
|
</ul>
|
|
<div class="admonition warning">
|
|
<p class="admonition-title">Error responses have two shapes</p>
|
|
<p>Structured application errors (raised inside a handler) return <code>{"status": "error", "error_code": "...", "message": "...", "timestamp": "..."}</code>. The authentication middleware, however, returns a <strong>different</strong> shape: <code>{"status": 401, "message": "..."}</code> with an integer <code>status</code> and no <code>error_code</code>. Clients must handle both. The full error model is documented in the <a href="#error-responses">Error responses</a> section at the bottom of this page.</p>
|
|
</div>
|
|
<hr />
|
|
<h2 id="general-endpoints">General endpoints<a class="headerlink" href="#general-endpoints" title="Permanent link">¶</a></h2>
|
|
<p>These endpoints report server state and enumerate what is available. <code>GET /api/health</code>, <code>GET /api/services</code>, and <code>POST /api/search</code> are also exposed in <code>--remote-only</code> mode.</p>
|
|
<h3 id="get-apihealth"><code>GET /api/health</code><a class="headerlink" href="#get-apihealth" title="Permanent link">¶</a></h3>
|
|
<p>Health check. <strong>This is the only route exempt from authentication</strong>: you can call it without an <code>X-Secret-Key</code> header. It reports the running version and a best-effort update check.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="1:2"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Request</label><label for="__tabbed_1_2">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-bash highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>curl<span class="w"> </span>http://127.0.0.1:8786/api/health
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="p">{</span>
|
|
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ok"</span><span class="p">,</span>
|
|
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5.3.0"</span><span class="p">,</span>
|
|
</span><span id="__span-1-4"><a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="w"> </span><span class="nt">"code_hash"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1d22a1e"</span><span class="p">,</span>
|
|
</span><span id="__span-1-5"><a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a><span class="w"> </span><span class="nt">"update_check"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-1-6"><a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="w"> </span><span class="nt">"update_available"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
|
|
</span><span id="__span-1-7"><a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="w"> </span><span class="nt">"current_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5.3.0"</span><span class="p">,</span>
|
|
</span><span id="__span-1-8"><a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a><span class="w"> </span><span class="nt">"latest_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5.3.0"</span>
|
|
</span><span id="__span-1-9"><a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-1-10"><a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p><code>code_hash</code> fingerprints the framework source the server is running, so it identifies the code itself rather than the release. It is the same value for a git checkout and for an installed package built from that checkout, and it changes if anything under <code>unshackle/core</code>, <code>unshackle/commands</code>, <code>unshackle/utils</code>, or <code>unshackle/vaults</code> is edited. Service modules are not included. The value is <code>null</code> only when the source files cannot be read.</p>
|
|
<p>If the update check fails (for example, no network), <code>update_available</code> and <code>latest_version</code> are <code>null</code> while <code>current_version</code> still reports the installed version.</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>Server is healthy.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="get-apiservices"><code>GET /api/services</code><a class="headerlink" href="#get-apiservices" title="Permanent link">¶</a></h3>
|
|
<p>List the streaming services available on this server, filtered by your allowlist. Each entry describes the service's tag, matching rules, capability flags, and its CLI parameters (useful for building a UI that accepts service-specific options).</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="2:2"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Request</label><label for="__tabbed_2_2">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-bash highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>curl<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-Secret-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span>http://127.0.0.1:8786/api/services
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="p">{</span>
|
|
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="w"> </span><span class="nt">"services"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="w"> </span><span class="nt">"tag"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EXAMPLE"</span><span class="p">,</span>
|
|
</span><span id="__span-3-5"><a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a><span class="w"> </span><span class="nt">"aliases"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"EX"</span><span class="p">],</span>
|
|
</span><span id="__span-3-6"><a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="w"> </span><span class="nt">"geofence"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"US"</span><span class="p">],</span>
|
|
</span><span id="__span-3-7"><a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a><span class="w"> </span><span class="nt">"title_regex"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^https?://example\\.com/.+"</span><span class="p">,</span>
|
|
</span><span id="__span-3-8"><a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a><span class="w"> </span><span class="nt">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://example.com"</span><span class="p">,</span>
|
|
</span><span id="__span-3-9"><a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a><span class="w"> </span><span class="nt">"help"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EXAMPLE\nAuthorization: Cookies\nSecurity: FHD@L3"</span><span class="p">,</span>
|
|
</span><span id="__span-3-10"><a id="__codelineno-3-10" name="__codelineno-3-10" href="#__codelineno-3-10"></a><span class="w"> </span><span class="nt">"cli_params"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-3-11"><a id="__codelineno-3-11" name="__codelineno-3-11" href="#__codelineno-3-11"></a><span class="w"> </span><span class="p">{</span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"title"</span><span class="p">,</span><span class="w"> </span><span class="nt">"kind"</span><span class="p">:</span><span class="w"> </span><span class="s2">"argument"</span><span class="p">,</span><span class="w"> </span><span class="nt">"required"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">},</span>
|
|
</span><span id="__span-3-12"><a id="__codelineno-3-12" name="__codelineno-3-12" href="#__codelineno-3-12"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-3-13"><a id="__codelineno-3-13" name="__codelineno-3-13" href="#__codelineno-3-13"></a><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"movie"</span><span class="p">,</span>
|
|
</span><span id="__span-3-14"><a id="__codelineno-3-14" name="__codelineno-3-14" href="#__codelineno-3-14"></a><span class="w"> </span><span class="nt">"kind"</span><span class="p">:</span><span class="w"> </span><span class="s2">"option"</span><span class="p">,</span>
|
|
</span><span id="__span-3-15"><a id="__codelineno-3-15" name="__codelineno-3-15" href="#__codelineno-3-15"></a><span class="w"> </span><span class="nt">"opts"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"-m"</span><span class="p">,</span><span class="w"> </span><span class="s2">"--movie"</span><span class="p">],</span>
|
|
</span><span id="__span-3-16"><a id="__codelineno-3-16" name="__codelineno-3-16" href="#__codelineno-3-16"></a><span class="w"> </span><span class="nt">"is_flag"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
</span><span id="__span-3-17"><a id="__codelineno-3-17" name="__codelineno-3-17" href="#__codelineno-3-17"></a><span class="w"> </span><span class="nt">"default"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
|
|
</span><span id="__span-3-18"><a id="__codelineno-3-18" name="__codelineno-3-18" href="#__codelineno-3-18"></a><span class="w"> </span><span class="nt">"help"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Title is a movie."</span><span class="p">,</span>
|
|
</span><span id="__span-3-19"><a id="__codelineno-3-19" name="__codelineno-3-19" href="#__codelineno-3-19"></a><span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"boolean"</span><span class="p">,</span>
|
|
</span><span id="__span-3-20"><a id="__codelineno-3-20" name="__codelineno-3-20" href="#__codelineno-3-20"></a><span class="w"> </span><span class="nt">"multiple"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span>
|
|
</span><span id="__span-3-21"><a id="__codelineno-3-21" name="__codelineno-3-21" href="#__codelineno-3-21"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-3-22"><a id="__codelineno-3-22" name="__codelineno-3-22" href="#__codelineno-3-22"></a><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-3-23"><a id="__codelineno-3-23" name="__codelineno-3-23" href="#__codelineno-3-23"></a><span class="w"> </span><span class="nt">"needs_auth"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
</span><span id="__span-3-24"><a id="__codelineno-3-24" name="__codelineno-3-24" href="#__codelineno-3-24"></a><span class="w"> </span><span class="nt">"has_search"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
</span><span id="__span-3-25"><a id="__codelineno-3-25" name="__codelineno-3-25" href="#__codelineno-3-25"></a><span class="w"> </span><span class="nt">"has_drm"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
</span><span id="__span-3-26"><a id="__codelineno-3-26" name="__codelineno-3-26" href="#__codelineno-3-26"></a><span class="w"> </span><span class="nt">"auth_methods"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"cookies"</span><span class="p">]</span>
|
|
</span><span id="__span-3-27"><a id="__codelineno-3-27" name="__codelineno-3-27" href="#__codelineno-3-27"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-3-28"><a id="__codelineno-3-28" name="__codelineno-3-28" href="#__codelineno-3-28"></a><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-3-29"><a id="__codelineno-3-29" name="__codelineno-3-29" href="#__codelineno-3-29"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p>Field notes:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Field</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>tag</code></td>
|
|
<td>Canonical service tag; use this as the <code>service</code> value on other endpoints.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>aliases</code></td>
|
|
<td>Alternate tags the service also answers to.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>geofence</code></td>
|
|
<td>Region codes the service is geofenced to (may be empty).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>title_regex</code></td>
|
|
<td>URL/ID pattern the service matches, as a string or list of strings (or <code>null</code>).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>url</code></td>
|
|
<td>Service URL, taken from the service's CLI short help.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>help</code></td>
|
|
<td>The service module's docstring.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>cli_params</code></td>
|
|
<td>Array of parameter descriptors. Arguments have <code>{name, kind: "argument", required}</code>; options have <code>{name, kind: "option", opts, is_flag, default, help, type, multiple}</code> and, for choice options, a <code>choices</code> list.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>needs_auth</code></td>
|
|
<td>Whether the service overrides <code>authenticate()</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>has_search</code></td>
|
|
<td>Whether the service supports <code>POST /api/search</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>has_drm</code></td>
|
|
<td>Whether the service overrides a Widevine or PlayReady license hook.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>auth_methods</code></td>
|
|
<td>Declared or inferred auth methods, e.g. <code>["cookies"]</code>, <code>["credentials"]</code>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>Service list returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>500</code></td>
|
|
<td>Unexpected server error (<code>INTERNAL_ERROR</code>).</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apisearch"><code>POST /api/search</code><a class="headerlink" href="#post-apisearch" title="Permanent link">¶</a></h3>
|
|
<p>Search a service for titles by query string. The service must implement <code>search()</code> (see <code>has_search</code> above).</p>
|
|
<p><strong>Request body</strong></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Field</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Default</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>service</code></td>
|
|
<td>string</td>
|
|
<td>yes</td>
|
|
<td>-</td>
|
|
<td>Service tag.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>query</code></td>
|
|
<td>string</td>
|
|
<td>yes</td>
|
|
<td>-</td>
|
|
<td>Search query.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>profile</code></td>
|
|
<td>string</td>
|
|
<td>no</td>
|
|
<td><code>null</code></td>
|
|
<td>Credential/cookie profile to use.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>proxy</code></td>
|
|
<td>string</td>
|
|
<td>no</td>
|
|
<td><code>null</code></td>
|
|
<td>Proxy URI or country code.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>no_proxy</code></td>
|
|
<td>boolean</td>
|
|
<td>no</td>
|
|
<td><code>false</code></td>
|
|
<td>Force-disable all proxy use.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="3:2"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Request</label><label for="__tabbed_3_2">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-bash highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:8786/api/search<span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-Secret-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"service": "EXAMPLE", "query": "planet earth"}'</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="p">{</span>
|
|
</span><span id="__span-5-2"><a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="w"> </span><span class="nt">"results"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-5-3"><a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-5-4"><a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"12345"</span><span class="p">,</span>
|
|
</span><span id="__span-5-5"><a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a><span class="w"> </span><span class="nt">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Planet Earth"</span><span class="p">,</span>
|
|
</span><span id="__span-5-6"><a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a><span class="w"> </span><span class="nt">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A nature documentary series."</span><span class="p">,</span>
|
|
</span><span id="__span-5-7"><a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a><span class="w"> </span><span class="nt">"label"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Available"</span><span class="p">,</span>
|
|
</span><span id="__span-5-8"><a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a><span class="w"> </span><span class="nt">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://example.com/title/12345"</span>
|
|
</span><span id="__span-5-9"><a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-5-10"><a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-5-11"><a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a><span class="w"> </span><span class="nt">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
|
|
</span><span id="__span-5-12"><a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Search completed.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_PARAMETERS</code></td>
|
|
<td>Missing <code>query</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_SERVICE</code></td>
|
|
<td>Unknown or disallowed service.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_PROXY</code></td>
|
|
<td>Proxy could not be resolved.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>502</code></td>
|
|
<td><code>SERVICE_ERROR</code></td>
|
|
<td>Service failed to initialize, or does not support search.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apilist-titles"><code>POST /api/list-titles</code><a class="headerlink" href="#post-apilist-titles" title="Permanent link">¶</a></h3>
|
|
<p>Resolve a title ID into its list of titles (episodes, movie, etc.) without downloading anything.</p>
|
|
<p><strong>Request body</strong></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Field</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>service</code></td>
|
|
<td>string</td>
|
|
<td>yes</td>
|
|
<td>Service tag.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>title_id</code></td>
|
|
<td>string</td>
|
|
<td>yes</td>
|
|
<td>Title identifier.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>profile</code></td>
|
|
<td>string</td>
|
|
<td>no</td>
|
|
<td>Credential/cookie profile.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>proxy</code></td>
|
|
<td>string</td>
|
|
<td>no</td>
|
|
<td>Proxy URI or country code.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>no_proxy</code></td>
|
|
<td>boolean</td>
|
|
<td>no</td>
|
|
<td>Force-disable proxy.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>cdm_type</code></td>
|
|
<td>string</td>
|
|
<td>no</td>
|
|
<td>Preferred CDM type.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Service-specific CLI options may also be passed as additional keys.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="4:2"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">Request</label><label for="__tabbed_4_2">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-bash highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:8786/api/list-titles<span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-Secret-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-6-4"><a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"service": "EXAMPLE", "title_id": "12345"}'</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="p">{</span>
|
|
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="w"> </span><span class="nt">"titles"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"episode"</span><span class="p">,</span>
|
|
</span><span id="__span-7-5"><a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Pilot"</span><span class="p">,</span>
|
|
</span><span id="__span-7-6"><a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ep-1"</span><span class="p">,</span>
|
|
</span><span id="__span-7-7"><a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a><span class="w"> </span><span class="nt">"language"</span><span class="p">:</span><span class="w"> </span><span class="s2">"en"</span><span class="p">,</span>
|
|
</span><span id="__span-7-8"><a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a><span class="w"> </span><span class="nt">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"The first episode."</span><span class="p">,</span>
|
|
</span><span id="__span-7-9"><a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a><span class="w"> </span><span class="nt">"date"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-01"</span><span class="p">,</span>
|
|
</span><span id="__span-7-10"><a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a><span class="w"> </span><span class="nt">"cover_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://example.com/cover.jpg"</span><span class="p">,</span>
|
|
</span><span id="__span-7-11"><a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a><span class="w"> </span><span class="nt">"year"</span><span class="p">:</span><span class="w"> </span><span class="mi">2020</span><span class="p">,</span>
|
|
</span><span id="__span-7-12"><a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a><span class="w"> </span><span class="nt">"series_title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example Show"</span><span class="p">,</span>
|
|
</span><span id="__span-7-13"><a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a><span class="w"> </span><span class="nt">"season"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
|
|
</span><span id="__span-7-14"><a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a><span class="w"> </span><span class="nt">"number"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
|
|
</span><span id="__span-7-15"><a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-7-16"><a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-7-17"><a id="__codelineno-7-17" name="__codelineno-7-17" href="#__codelineno-7-17"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p>Each serialized title carries <code>type</code> (<code>"episode"</code>, <code>"movie"</code>, or <code>"other"</code>), <code>name</code>, <code>id</code>, <code>language</code>, <code>description</code>, <code>date</code>, and <code>cover_url</code>. Episodes and movies add <code>year</code>; episodes additionally add <code>series_title</code>, <code>season</code>, and <code>number</code>.</p>
|
|
<p>These keys are sent only when the title carries them, so a title without them serializes exactly as before:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Key</th>
|
|
<th>Type</th>
|
|
<th>On</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>part</code></td>
|
|
<td>integer</td>
|
|
<td>episode</td>
|
|
<td>Part index of a <a href="../../creating-a-service/#split-episodes">split episode</a>, counting from 1.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>air_date</code></td>
|
|
<td>string</td>
|
|
<td>episode</td>
|
|
<td>ISO air date of <a href="../../../guide/downloading/#daily-and-date-based-content">dated content</a>. unshackle names the episode by date instead of <code>SxxExx</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>absolute</code></td>
|
|
<td>integer</td>
|
|
<td>episode</td>
|
|
<td>Absolute episode number across all seasons.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>daily</code></td>
|
|
<td>boolean</td>
|
|
<td>episode</td>
|
|
<td>The episode is daily/date-based. Set from the title, or from the service's <code>DAILY</code> class attribute.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>anime</code></td>
|
|
<td>boolean</td>
|
|
<td>episode, movie</td>
|
|
<td>The title is anime, so metadata lookups prefer AniList. Set from the title, or from the service's <code>ANIME</code> class attribute.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="admonition info">
|
|
<p class="admonition-title"><code>part</code> on a split episode</p>
|
|
<p>A service that splits one episode into several separately playable videos reports each
|
|
one as its own episode. Those titles share a <code>season</code> and <code>number</code> and add a <code>part</code>
|
|
integer counting from 1. No other title carries the key, so a client that ignores it
|
|
is unaffected. See <a href="../../creating-a-service/#split-episodes">Split episodes</a>.</p>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Titles returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>Missing <code>service</code> or <code>title_id</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_SERVICE</code></td>
|
|
<td>Unknown or disallowed service.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>401</code></td>
|
|
<td><code>AUTH_FAILED</code></td>
|
|
<td>Authentication with the service failed.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>NOT_FOUND</code></td>
|
|
<td>Title not found.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>500</code></td>
|
|
<td><code>INTERNAL_ERROR</code></td>
|
|
<td>Unexpected error.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apilist-tracks"><code>POST /api/list-tracks</code><a class="headerlink" href="#post-apilist-tracks" title="Permanent link">¶</a></h3>
|
|
<p>List the video, audio, and subtitle tracks for a title. For series, you can scope to specific episodes.</p>
|
|
<div class="admonition tip">
|
|
<p class="admonition-title">Spotting the original-language audio</p>
|
|
<p>Each audio track carries <code>is_original</code>, which marks the track the default <code>lang</code> of <code>orig</code> selects. Unshackle resolves it with the same language matcher the downloader uses, so it stays correct for regional variants a client cannot separate from tag text alone (<code>pt</code> marks <code>pt-BR</code> rather than <code>pt-PT</code>). Services need not report a title's language, so every track can legitimately come back <code>false</code>.</p>
|
|
</div>
|
|
<p><strong>Request body</strong></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Field</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>service</code></td>
|
|
<td>string</td>
|
|
<td>yes</td>
|
|
<td>Service tag.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>title_id</code></td>
|
|
<td>string</td>
|
|
<td>yes</td>
|
|
<td>Title identifier.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>wanted</code></td>
|
|
<td>string</td>
|
|
<td>no</td>
|
|
<td>Episode/season range (e.g. <code>"S01E01-S01E03"</code>).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>season</code></td>
|
|
<td>int/string</td>
|
|
<td>no</td>
|
|
<td>Season number (combined with <code>episode</code>).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>episode</code></td>
|
|
<td>int/string</td>
|
|
<td>no</td>
|
|
<td>Episode number (combined with <code>season</code>).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>part</code></td>
|
|
<td>int/string</td>
|
|
<td>no</td>
|
|
<td>Part index of a split episode (combined with <code>season</code> and <code>episode</code>).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>profile</code>, <code>proxy</code>, <code>no_proxy</code>, <code>cdm_type</code></td>
|
|
<td>-</td>
|
|
<td>no</td>
|
|
<td>As on <code>list-titles</code>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>When both <code>season</code> and <code>episode</code> are given, they are combined into a <code>"{season}x{episode}"</code> selector. Adding <code>part</code> narrows that to <code>"{season}x{episode}.{part}"</code>, one part of a <a href="../../creating-a-service/#split-episodes">split episode</a>; without it you get every part of the episode. <code>part</code> is read only when <code>season</code> and <code>episode</code> are both given, and <code>wanted</code> takes precedence over all three. To scope a part by range, put it in <code>wanted</code> instead (<code>"S01E01.2"</code>).</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="5:2"><input checked="checked" id="__tabbed_5_1" name="__tabbed_5" type="radio" /><input id="__tabbed_5_2" name="__tabbed_5" type="radio" /><div class="tabbed-labels"><label for="__tabbed_5_1">Single title / movie: Response <code>200</code></label><label for="__tabbed_5_2">Multiple episodes: Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="p">{</span>
|
|
</span><span id="__span-8-2"><a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="w"> </span><span class="nt">"title"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"movie"</span><span class="p">,</span><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example Movie"</span><span class="p">,</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"12345"</span><span class="p">,</span><span class="w"> </span><span class="nt">"year"</span><span class="p">:</span><span class="w"> </span><span class="mi">2021</span><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-8-3"><a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="nt">"video"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-8-4"><a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-8-5"><a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"v-1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"codec"</span><span class="p">:</span><span class="w"> </span><span class="s2">"H265"</span><span class="p">,</span><span class="w"> </span><span class="nt">"codec_display"</span><span class="p">:</span><span class="w"> </span><span class="s2">"HEVC"</span><span class="p">,</span>
|
|
</span><span id="__span-8-6"><a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a><span class="w"> </span><span class="nt">"bitrate"</span><span class="p">:</span><span class="w"> </span><span class="mi">8000</span><span class="p">,</span><span class="w"> </span><span class="nt">"width"</span><span class="p">:</span><span class="w"> </span><span class="mi">3840</span><span class="p">,</span><span class="w"> </span><span class="nt">"height"</span><span class="p">:</span><span class="w"> </span><span class="mi">2160</span><span class="p">,</span>
|
|
</span><span id="__span-8-7"><a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a><span class="w"> </span><span class="nt">"resolution"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2160p"</span><span class="p">,</span><span class="w"> </span><span class="nt">"fps"</span><span class="p">:</span><span class="w"> </span><span class="s2">"24"</span><span class="p">,</span><span class="w"> </span><span class="nt">"range"</span><span class="p">:</span><span class="w"> </span><span class="s2">"HDR10"</span><span class="p">,</span>
|
|
</span><span id="__span-8-8"><a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a><span class="w"> </span><span class="nt">"range_display"</span><span class="p">:</span><span class="w"> </span><span class="s2">"HDR10"</span><span class="p">,</span><span class="w"> </span><span class="nt">"language"</span><span class="p">:</span><span class="w"> </span><span class="s2">"en"</span><span class="p">,</span><span class="w"> </span><span class="nt">"drm"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w"> </span><span class="nt">"descriptor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DASH"</span>
|
|
</span><span id="__span-8-9"><a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-8-10"><a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-8-11"><a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a><span class="w"> </span><span class="nt">"audio"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-8-12"><a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-8-13"><a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"a-1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"codec"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EC3"</span><span class="p">,</span><span class="w"> </span><span class="nt">"codec_display"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DD+"</span><span class="p">,</span>
|
|
</span><span id="__span-8-14"><a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a><span class="w"> </span><span class="nt">"bitrate"</span><span class="p">:</span><span class="w"> </span><span class="mi">640</span><span class="p">,</span><span class="w"> </span><span class="nt">"channels"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5.1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"language"</span><span class="p">:</span><span class="w"> </span><span class="s2">"en"</span><span class="p">,</span><span class="w"> </span><span class="nt">"is_original"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
</span><span id="__span-8-15"><a id="__codelineno-8-15" name="__codelineno-8-15" href="#__codelineno-8-15"></a><span class="w"> </span><span class="nt">"atmos"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nt">"descriptive"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nt">"drm"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w"> </span><span class="nt">"descriptor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DASH"</span>
|
|
</span><span id="__span-8-16"><a id="__codelineno-8-16" name="__codelineno-8-16" href="#__codelineno-8-16"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-8-17"><a id="__codelineno-8-17" name="__codelineno-8-17" href="#__codelineno-8-17"></a><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-8-18"><a id="__codelineno-8-18" name="__codelineno-8-18" href="#__codelineno-8-18"></a><span class="w"> </span><span class="nt">"subtitles"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-8-19"><a id="__codelineno-8-19" name="__codelineno-8-19" href="#__codelineno-8-19"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"s-1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"codec"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vtt"</span><span class="p">,</span><span class="w"> </span><span class="nt">"language"</span><span class="p">:</span><span class="w"> </span><span class="s2">"en"</span><span class="p">,</span>
|
|
</span><span id="__span-8-20"><a id="__codelineno-8-20" name="__codelineno-8-20" href="#__codelineno-8-20"></a><span class="w"> </span><span class="nt">"forced"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nt">"sdh"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nt">"cc"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nt">"descriptor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DASH"</span><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-8-21"><a id="__codelineno-8-21" name="__codelineno-8-21" href="#__codelineno-8-21"></a><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-8-22"><a id="__codelineno-8-22" name="__codelineno-8-22" href="#__codelineno-8-22"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="p">{</span>
|
|
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="w"> </span><span class="nt">"episodes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-9-4"><a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a><span class="w"> </span><span class="nt">"title"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"episode"</span><span class="p">,</span><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Pilot"</span><span class="p">,</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ep-1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"season"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nt">"number"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-9-5"><a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a><span class="w"> </span><span class="nt">"video"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-9-6"><a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a><span class="w"> </span><span class="nt">"audio"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-9-7"><a id="__codelineno-9-7" name="__codelineno-9-7" href="#__codelineno-9-7"></a><span class="w"> </span><span class="nt">"subtitles"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-9-8"><a id="__codelineno-9-8" name="__codelineno-9-8" href="#__codelineno-9-8"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-9-9"><a id="__codelineno-9-9" name="__codelineno-9-9" href="#__codelineno-9-9"></a><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-9-10"><a id="__codelineno-9-10" name="__codelineno-9-10" href="#__codelineno-9-10"></a><span class="w"> </span><span class="nt">"unavailable_episodes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-9-11"><a id="__codelineno-9-11" name="__codelineno-9-11" href="#__codelineno-9-11"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"title"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ep-2"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nt">"error"</span><span class="p">:</span><span class="w"> </span><span class="s2">"..."</span><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-9-12"><a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-9-13"><a id="__codelineno-9-13" name="__codelineno-9-13" href="#__codelineno-9-13"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p>Tracks are sorted by bitrate, descending. Episodes that fail to resolve are collected into <code>unavailable_episodes</code> rather than failing the whole request. Track objects here do <strong>not</strong> include a download <code>url</code>; segment URLs are only exposed through the remote-dl session endpoints.</p>
|
|
<p>The <code>drm</code> array on a track is a list of <code>{type, pssh?, kids?, content_keys?, license_url?}</code> objects.</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Tracks returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>Missing <code>service</code> or <code>title_id</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_PARAMETERS</code></td>
|
|
<td>Invalid <code>wanted</code> range.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_SERVICE</code></td>
|
|
<td>Unknown or disallowed service.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>NO_CONTENT</code></td>
|
|
<td>No matching episodes, or all matches failed.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<hr />
|
|
<h2 id="download-jobs">Download jobs<a class="headerlink" href="#download-jobs" title="Permanent link">¶</a></h2>
|
|
<p>Downloads are asynchronous. <code>POST /api/download</code> enqueues a job and returns immediately with a <code>job_id</code>; the server runs each job in a background worker subprocess. You then poll the job endpoints for progress and results.</p>
|
|
<div class="admonition info">
|
|
<p class="admonition-title">Job states</p>
|
|
<p>A job moves through <code>queued</code> → <code>downloading</code> → one of the terminal states <code>completed</code>, <code>failed</code>, or <code>cancelled</code>. Only queued jobs can be prioritized; only terminal jobs can be retried or removed.</p>
|
|
</div>
|
|
<h3 id="post-apidownload"><code>POST /api/download</code><a class="headerlink" href="#post-apidownload" title="Permanent link">¶</a></h3>
|
|
<p>Create a download job. Requires <code>service</code> and <code>title_id</code>; every other field is an optional download parameter with a server-side default. On success this returns <strong><code>202 Accepted</code></strong>, not <code>200</code>.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="6:2"><input checked="checked" id="__tabbed_6_1" name="__tabbed_6" type="radio" /><input id="__tabbed_6_2" name="__tabbed_6" type="radio" /><div class="tabbed-labels"><label for="__tabbed_6_1">Request</label><label for="__tabbed_6_2">Response <code>202</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-bash highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:8786/api/download<span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-Secret-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-10-4"><a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{</span>
|
|
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a><span class="s1"> "service": "EXAMPLE",</span>
|
|
</span><span id="__span-10-6"><a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a><span class="s1"> "title_id": "12345",</span>
|
|
</span><span id="__span-10-7"><a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a><span class="s1"> "quality": [2160],</span>
|
|
</span><span id="__span-10-8"><a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a><span class="s1"> "vcodec": "H265",</span>
|
|
</span><span id="__span-10-9"><a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a><span class="s1"> "range": ["HDR10"],</span>
|
|
</span><span id="__span-10-10"><a id="__codelineno-10-10" name="__codelineno-10-10" href="#__codelineno-10-10"></a><span class="s1"> "wanted": ["S01E01"]</span>
|
|
</span><span id="__span-10-11"><a id="__codelineno-10-11" name="__codelineno-10-11" href="#__codelineno-10-11"></a><span class="s1"> }'</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="p">{</span>
|
|
</span><span id="__span-11-2"><a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a><span class="w"> </span><span class="nt">"job_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"b0f7c8e2-4a1d-4e9c-9b7e-2f3a1c0d5e6f"</span><span class="p">,</span>
|
|
</span><span id="__span-11-3"><a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"queued"</span><span class="p">,</span>
|
|
</span><span id="__span-11-4"><a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-4"></a><span class="w"> </span><span class="nt">"created_time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2026-07-03T12:00:00+00:00"</span>
|
|
</span><span id="__span-11-5"><a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p><strong>Common parameters</strong> (all optional). These mirror the <a href="../../../guide/downloading/"><code>dl</code> command</a> flags:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Field</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th>Notes</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>profile</code></td>
|
|
<td>string</td>
|
|
<td><code>null</code></td>
|
|
<td>Credential/cookie profile.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>quality</code></td>
|
|
<td>int[]</td>
|
|
<td><code>[]</code></td>
|
|
<td>Target resolution(s); best available if empty.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>vcodec</code></td>
|
|
<td>string/string[]</td>
|
|
<td><code>null</code></td>
|
|
<td>Video codec filter.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>acodec</code></td>
|
|
<td>string/string[]</td>
|
|
<td><code>null</code></td>
|
|
<td>Audio codec filter.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>vbitrate</code> / <code>abitrate</code></td>
|
|
<td>int</td>
|
|
<td><code>null</code></td>
|
|
<td>Video / audio bitrate in kbps (positive).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>vbitrate_range</code> / <code>abitrate_range</code></td>
|
|
<td>string</td>
|
|
<td><code>null</code></td>
|
|
<td><code>"MIN-MAX"</code> bitrate window.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>range</code></td>
|
|
<td>string[]</td>
|
|
<td><code>["SDR"]</code></td>
|
|
<td>Dynamic range(s).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>channels</code></td>
|
|
<td>number</td>
|
|
<td><code>null</code></td>
|
|
<td>Audio channel count.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>no_atmos</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Exclude Atmos tracks.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>wanted</code></td>
|
|
<td>string[]</td>
|
|
<td><code>[]</code></td>
|
|
<td>Episode/season selectors. Accepts the part form, <code>"S01E01.2"</code>, and the air-date form, <code>"2026-08-11"</code> or <code>"2026-08-01:2026-08-31"</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>latest_episode</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Only the newest episode.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>lang</code> / <code>v_lang</code> / <code>a_lang</code> / <code>s_lang</code></td>
|
|
<td>string[]</td>
|
|
<td><code>["orig"]</code> / <code>[]</code> / <code>[]</code> / <code>["all"]</code></td>
|
|
<td>Language filters.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>require_subs</code></td>
|
|
<td>string[]</td>
|
|
<td><code>[]</code></td>
|
|
<td>Required subtitle languages.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>forced_subs</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Include forced subtitles.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>forced_s_lang</code></td>
|
|
<td>string[]</td>
|
|
<td><code>[]</code></td>
|
|
<td>Forced subtitle language(s); implies <code>forced_subs</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>exact_lang</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Exact language matching.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>sub_format</code></td>
|
|
<td>string</td>
|
|
<td><code>null</code></td>
|
|
<td>Output subtitle format.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>video_only</code> / <code>audio_only</code> / <code>subs_only</code> / <code>chapters_only</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Track-type restriction (at most one).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>no_subs</code> / <code>no_audio</code> / <code>no_chapters</code> / <code>no_video</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Skip a track type.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>audio_description</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Download audio description.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>slow</code></td>
|
|
<td>boolean/string</td>
|
|
<td><code>null</code></td>
|
|
<td>Randomized delay between downloads.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>split_audio</code></td>
|
|
<td>boolean</td>
|
|
<td><code>null</code></td>
|
|
<td>Separate files per audio codec.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>skip_dl</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Only fetch keys, do not download.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>export</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Export manifest/keys/subs to JSON.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>cdm_only</code></td>
|
|
<td>boolean</td>
|
|
<td><code>null</code></td>
|
|
<td>Force CDM-only (<code>true</code>) or vault-only (<code>false</code>) key retrieval.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>proxy</code> / <code>no_proxy</code> / <code>no_proxy_download</code></td>
|
|
<td>string / bool / bool</td>
|
|
<td><code>null</code> / <code>false</code> / <code>false</code></td>
|
|
<td>Proxy controls.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>no_folder</code> / <code>no_source</code> / <code>no_mux</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Output/mux controls.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>workers</code></td>
|
|
<td>int</td>
|
|
<td><code>null</code></td>
|
|
<td>Threads per track.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>adaptive_workers</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Scale segment workers to measured CDN throughput, up to the <code>workers</code> cap.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>download_processes</code></td>
|
|
<td>int</td>
|
|
<td><code>1</code></td>
|
|
<td>Split a track's segments across this many processes. Only engages for large batches.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>downloads</code></td>
|
|
<td>int</td>
|
|
<td><code>1</code></td>
|
|
<td>Concurrent tracks.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>worst</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Lowest bitrate within quality.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>best_available</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Fall back to best available.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>repack</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Add REPACK tag.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>tag</code></td>
|
|
<td>string</td>
|
|
<td><code>null</code></td>
|
|
<td>Release group tag.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>tmdb_id</code> / <code>imdb_id</code> / <code>tvdb_id</code> / <code>anilist_id</code></td>
|
|
<td>-</td>
|
|
<td><code>null</code></td>
|
|
<td>External ID overrides. Each resolves its metadata directly instead of by a title search, and is used for tagging. Set <code>enrich</code> to also take the title, year and original language. Give at most one of <code>tmdb_id</code>, <code>imdb_id</code> and <code>tvdb_id</code>, since unshackle resolves the others from it. Sending two returns <code>400</code>. <code>anilist_id</code> still combines with one of them. <code>tmdb_id</code> and <code>tvdb_id</code> must be positive integers, <code>imdb_id</code> must look like <code>tt1375666</code>, and <code>anilist_id</code> must be a positive integer or a string like <code>mal:12345</code>, or the request returns <code>400</code>. An ID whose provider is unconfigured, such as <code>tmdb_id</code> with no <code>tmdb_api_key</code>, fails the job rather than returning <code>400</code>. <code>anilist_id</code> needs no key.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>tvdb_order</code></td>
|
|
<td><code>official</code>, <code>dvd</code>, <code>absolute</code>, <code>alternate</code>, <code>regional</code></td>
|
|
<td><code>null</code></td>
|
|
<td>Renumber episodes to a TVDB season order. Falls back to the <code>tvdb_order</code> config option.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>enrich</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Overwrite title, year and original language with the external source's. Needs one of <code>tmdb_id</code>, <code>imdb_id</code>, <code>tvdb_id</code> or <code>anilist_id</code>. Without one the job fails instead of returning <code>400</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>daily</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Treat the title as daily/date-based content and fill missing episode air dates from TVDB. The fill needs <code>enrich</code> and a TVDB ID. An air date the service already set is kept.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>output_dir</code></td>
|
|
<td>string</td>
|
|
<td><code>null</code></td>
|
|
<td>Override output directory.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>no_cache</code> / <code>reset_cache</code></td>
|
|
<td>boolean</td>
|
|
<td><code>false</code></td>
|
|
<td>Title cache controls.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><strong>Validation.</strong> Invalid values return <code>400 INVALID_PARAMETERS</code>. Notably: <code>vcodec</code> must be one of H264/H265/H.264/H.265/AVC/HEVC/VC1/VC-1/VP8/VP9/AV1; <code>acodec</code> one of AAC/AC3/EC3/EAC3/DD/DD+/AC4/OPUS/FLAC/ALAC/VORBIS/OGG/DTS; <code>range</code> one of SDR/HDR10/HDR10P/DV/HLG/HYBRID (<code>HDR10+</code> is accepted); bitrate/worker/download counts must be positive integers; at most one of the <code>*_only</code> flags may be set; <code>no_subs</code> cannot be combined with <code>subs_only</code>, <code>no_audio</code> with <code>audio_only</code>, or <code>s_lang</code> with <code>require_subs</code>.</p>
|
|
<div class="admonition danger">
|
|
<p class="admonition-title">Rejected parameters</p>
|
|
<p><code>postscript</code>, <code>post_script</code> and <code>post_scripts</code> are never accepted. A body containing any
|
|
of them is rejected with <code>400 INVALID_PARAMETERS</code>, because a command string arriving from
|
|
an HTTP caller would be remote code execution. Post-download hooks are configured only in
|
|
<code>unshackle.yaml</code>, where they still run for API jobs. See
|
|
<a href="../../../reference/configuration/post-scripts/">Post-download scripts</a>.</p>
|
|
</div>
|
|
<div class="admonition warning">
|
|
<p class="admonition-title">Gated parameters (developer)</p>
|
|
<p>A few keys are accepted but only permitted when the server config opts in, otherwise the request is rejected with <code>403 FORBIDDEN</code>:</p>
|
|
<ul>
|
|
<li><code>cdm</code> (per-request CDM device name): allowed only if <code>serve.cdm_overrides</code> is <code>true</code> or a list containing that device name.</li>
|
|
<li><code>credential</code> (<code>"user:pass"</code>) and <code>credentials</code> (a map): allowed only if <code>serve.allow_job_credentials</code> is truthy (off by default).</li>
|
|
</ul>
|
|
<p>Server-side, effective parameters are merged as defaults → <code>serve:</code> config overrides → service-specific defaults → your request body.</p>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>202</code></td>
|
|
<td>-</td>
|
|
<td>Job queued.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>Missing <code>service</code>/<code>title_id</code> or malformed JSON.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_PARAMETERS</code></td>
|
|
<td>A parameter failed validation.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_SERVICE</code></td>
|
|
<td>Unknown or disallowed service.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>403</code></td>
|
|
<td><code>FORBIDDEN</code></td>
|
|
<td>A gated parameter is not permitted.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="get-apidownloadjobs"><code>GET /api/download/jobs</code><a class="headerlink" href="#get-apidownloadjobs" title="Permanent link">¶</a></h3>
|
|
<p>List download jobs, with optional filtering and sorting.</p>
|
|
<p><strong>Query parameters</strong></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Param</th>
|
|
<th>Values</th>
|
|
<th>Default</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>status</code></td>
|
|
<td><code>queued</code>, <code>downloading</code>, <code>completed</code>, <code>failed</code>, <code>cancelled</code></td>
|
|
<td>-</td>
|
|
<td>Filter by status.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>service</code></td>
|
|
<td>service tag</td>
|
|
<td>-</td>
|
|
<td>Filter by service.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>sort_by</code></td>
|
|
<td><code>created_time</code>, <code>started_time</code>, <code>completed_time</code>, <code>progress</code>, <code>status</code>, <code>service</code></td>
|
|
<td><code>created_time</code></td>
|
|
<td>Sort field.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>sort_order</code></td>
|
|
<td><code>asc</code>, <code>desc</code></td>
|
|
<td><code>desc</code></td>
|
|
<td>Sort direction.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>full</code></td>
|
|
<td><code>true</code>, <code>false</code></td>
|
|
<td><code>false</code></td>
|
|
<td>Include full per-job details.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="7:2"><input checked="checked" id="__tabbed_7_1" name="__tabbed_7" type="radio" /><input id="__tabbed_7_2" name="__tabbed_7" type="radio" /><div class="tabbed-labels"><label for="__tabbed_7_1">Request</label><label for="__tabbed_7_2">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-bash highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a>curl<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-Secret-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="s2">"http://127.0.0.1:8786/api/download/jobs?status=downloading&sort_by=progress&sort_order=desc"</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="p">{</span>
|
|
</span><span id="__span-13-2"><a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a><span class="w"> </span><span class="nt">"jobs"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-13-3"><a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-13-4"><a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a><span class="w"> </span><span class="nt">"job_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"b0f7c8e2-..."</span><span class="p">,</span>
|
|
</span><span id="__span-13-5"><a id="__codelineno-13-5" name="__codelineno-13-5" href="#__codelineno-13-5"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"downloading"</span><span class="p">,</span>
|
|
</span><span id="__span-13-6"><a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a><span class="w"> </span><span class="nt">"created_time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2026-07-03T12:00:00+00:00"</span><span class="p">,</span>
|
|
</span><span id="__span-13-7"><a id="__codelineno-13-7" name="__codelineno-13-7" href="#__codelineno-13-7"></a><span class="w"> </span><span class="nt">"service"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EXAMPLE"</span><span class="p">,</span>
|
|
</span><span id="__span-13-8"><a id="__codelineno-13-8" name="__codelineno-13-8" href="#__codelineno-13-8"></a><span class="w"> </span><span class="nt">"title_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"12345"</span><span class="p">,</span>
|
|
</span><span id="__span-13-9"><a id="__codelineno-13-9" name="__codelineno-13-9" href="#__codelineno-13-9"></a><span class="w"> </span><span class="nt">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example Show S01E01"</span><span class="p">,</span>
|
|
</span><span id="__span-13-10"><a id="__codelineno-13-10" name="__codelineno-13-10" href="#__codelineno-13-10"></a><span class="w"> </span><span class="nt">"progress"</span><span class="p">:</span><span class="w"> </span><span class="mf">42.5</span><span class="p">,</span>
|
|
</span><span id="__span-13-11"><a id="__codelineno-13-11" name="__codelineno-13-11" href="#__codelineno-13-11"></a><span class="w"> </span><span class="nt">"phase"</span><span class="p">:</span><span class="w"> </span><span class="s2">"downloading"</span><span class="p">,</span>
|
|
</span><span id="__span-13-12"><a id="__codelineno-13-12" name="__codelineno-13-12" href="#__codelineno-13-12"></a><span class="w"> </span><span class="nt">"current_title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Episode 1"</span><span class="p">,</span>
|
|
</span><span id="__span-13-13"><a id="__codelineno-13-13" name="__codelineno-13-13" href="#__codelineno-13-13"></a><span class="w"> </span><span class="nt">"completed_tracks"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
|
|
</span><span id="__span-13-14"><a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a><span class="w"> </span><span class="nt">"total_tracks"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span>
|
|
</span><span id="__span-13-15"><a id="__codelineno-13-15" name="__codelineno-13-15" href="#__codelineno-13-15"></a><span class="w"> </span><span class="nt">"active_tracks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"v-1"</span><span class="p">],</span>
|
|
</span><span id="__span-13-16"><a id="__codelineno-13-16" name="__codelineno-13-16" href="#__codelineno-13-16"></a><span class="w"> </span><span class="nt">"track_progress"</span><span class="p">:</span><span class="w"> </span><span class="p">[{</span><span class="nt">"label"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Video"</span><span class="p">,</span><span class="w"> </span><span class="nt">"progress"</span><span class="p">:</span><span class="w"> </span><span class="mf">42.5</span><span class="p">,</span><span class="w"> </span><span class="nt">"speed"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5.2 MB/s"</span><span class="p">}],</span>
|
|
</span><span id="__span-13-17"><a id="__codelineno-13-17" name="__codelineno-13-17" href="#__codelineno-13-17"></a><span class="w"> </span><span class="nt">"segments_done"</span><span class="p">:</span><span class="w"> </span><span class="mi">120</span><span class="p">,</span>
|
|
</span><span id="__span-13-18"><a id="__codelineno-13-18" name="__codelineno-13-18" href="#__codelineno-13-18"></a><span class="w"> </span><span class="nt">"segments_total"</span><span class="p">:</span><span class="w"> </span><span class="mi">300</span><span class="p">,</span>
|
|
</span><span id="__span-13-19"><a id="__codelineno-13-19" name="__codelineno-13-19" href="#__codelineno-13-19"></a><span class="w"> </span><span class="nt">"speed"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5.2 MB/s"</span><span class="p">,</span>
|
|
</span><span id="__span-13-20"><a id="__codelineno-13-20" name="__codelineno-13-20" href="#__codelineno-13-20"></a><span class="w"> </span><span class="nt">"skipped_subtitles"</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span>
|
|
</span><span id="__span-13-21"><a id="__codelineno-13-21" name="__codelineno-13-21" href="#__codelineno-13-21"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-13-22"><a id="__codelineno-13-22" name="__codelineno-13-22" href="#__codelineno-13-22"></a><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-13-23"><a id="__codelineno-13-23" name="__codelineno-13-23" href="#__codelineno-13-23"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p>With <code>full=true</code>, each job additionally includes <code>parameters</code> (with secrets redacted), <code>started_time</code>, <code>completed_time</code>, <code>output_files</code>, <code>error_message</code>, <code>error_details</code>, <code>error_code</code>, <code>error_traceback</code>, and <code>worker_stderr</code>.</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Jobs returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_PARAMETERS</code></td>
|
|
<td>Invalid <code>sort_by</code> or <code>sort_order</code>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="get-apidownloadjobsjob_id"><code>GET /api/download/jobs/{job_id}</code><a class="headerlink" href="#get-apidownloadjobsjob_id" title="Permanent link">¶</a></h3>
|
|
<p>Fetch a single job with full details (equivalent to a <code>full=true</code> list entry).</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Job returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>JOB_NOT_FOUND</code></td>
|
|
<td>No such job.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="get-apidownloadjobsjob_idevents"><code>GET /api/download/jobs/{job_id}/events</code><a class="headerlink" href="#get-apidownloadjobsjob_idevents" title="Permanent link">¶</a></h3>
|
|
<p>Stream the job's progress as <a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events">Server-Sent Events</a>. Use this instead of polling <code>GET /api/download/jobs/{job_id}</code>.</p>
|
|
<p>The response has the content type <code>text/event-stream</code>. Each event has this format:</p>
|
|
<div class="language-text highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a>event: <name>
|
|
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a>data: <job JSON>
|
|
</span></code></pre></div>
|
|
<p>The <code>data</code> field of every event is the same job object that <code>GET /api/download/jobs/{job_id}</code> returns.</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Event</th>
|
|
<th>When it is sent</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>snapshot</code></td>
|
|
<td>Immediately, as the first event. Gives the job's current state.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>status</code></td>
|
|
<td>The job leaves the queue and starts to download.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>progress</code></td>
|
|
<td>The worker's progress record changed. The server reads that record every 0.5 seconds, so you get at most two of these events each second, and none while the record stays the same.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>completed</code></td>
|
|
<td>The job finished. The server then closes the stream.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>failed</code></td>
|
|
<td>The job failed. The server then closes the stream.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>cancelled</code></td>
|
|
<td>The job was cancelled. The server then closes the stream.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The server sends a <code>: keep-alive</code> comment each 15 seconds while the job is quiet, to keep proxies from closing an idle connection. Ignore these lines.</p>
|
|
<p>If the job is already in a terminal state, the server sends the <code>snapshot</code> event, then the terminal event, and closes the stream immediately.</p>
|
|
<div class="admonition tip">
|
|
<p class="admonition-title">Authentication from a browser</p>
|
|
<p><code>EventSource</code> cannot set headers. For this endpoint only, the server also accepts the key in the <code>secret_key</code> query parameter. This works in both server modes, the default integrated server and <code>--api-only</code>:</p>
|
|
<div class="language-javascript highlight"><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">events</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">EventSource</span><span class="p">(</span>
|
|
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a><span class="w"> </span><span class="sb">`http://127.0.0.1:8786/api/download/jobs/</span><span class="si">${</span><span class="nx">jobId</span><span class="si">}</span><span class="sb">/events?secret_key=</span><span class="si">${</span><span class="nx">key</span><span class="si">}</span><span class="sb">`</span>
|
|
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a><span class="p">);</span>
|
|
</span><span id="__span-15-4"><a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="nx">events</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">"progress"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nx">e</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nb">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">data</span><span class="p">).</span><span class="nx">progress</span><span class="p">));</span>
|
|
</span><span id="__span-15-5"><a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a><span class="nx">events</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">"completed"</span><span class="p">,</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">events</span><span class="p">.</span><span class="nx">close</span><span class="p">());</span>
|
|
</span></code></pre></div>
|
|
<p>The header always wins. Send the key in the query parameter <em>or</em> in the header, not both: if an <code>X-Secret-Key</code> header is present, the server checks that header and ignores the query parameter. See <a href="../authentication/#how-clients-present-credentials">Authentication</a>.</p>
|
|
</div>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="8:2"><input checked="checked" id="__tabbed_8_1" name="__tabbed_8" type="radio" /><input id="__tabbed_8_2" name="__tabbed_8" type="radio" /><div class="tabbed-labels"><label for="__tabbed_8_1">Request</label><label for="__tabbed_8_2">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-bash highlight"><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a>curl<span class="w"> </span>-N<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-Secret-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
|
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a><span class="w"> </span><span class="s2">"http://127.0.0.1:8786/api/download/jobs/b0f7c8e2-.../events"</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-text highlight"><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a>event: snapshot
|
|
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a>data: {"job_id":"b0f7c8e2-...","status":"downloading","progress":42.5,...}
|
|
</span><span id="__span-17-3"><a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a>
|
|
</span><span id="__span-17-4"><a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a>event: progress
|
|
</span><span id="__span-17-5"><a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a>data: {"job_id":"b0f7c8e2-...","status":"downloading","progress":48.0,...}
|
|
</span><span id="__span-17-6"><a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a>
|
|
</span><span id="__span-17-7"><a id="__codelineno-17-7" name="__codelineno-17-7" href="#__codelineno-17-7"></a>: keep-alive
|
|
</span><span id="__span-17-8"><a id="__codelineno-17-8" name="__codelineno-17-8" href="#__codelineno-17-8"></a>
|
|
</span><span id="__span-17-9"><a id="__codelineno-17-9" name="__codelineno-17-9" href="#__codelineno-17-9"></a>event: completed
|
|
</span><span id="__span-17-10"><a id="__codelineno-17-10" name="__codelineno-17-10" href="#__codelineno-17-10"></a>data: {"job_id":"b0f7c8e2-...","status":"completed","progress":100.0,...}
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Event stream started.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>JOB_NOT_FOUND</code></td>
|
|
<td>No such job.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="delete-apidownloadjobsjob_id"><code>DELETE /api/download/jobs/{job_id}</code><a class="headerlink" href="#delete-apidownloadjobsjob_id" title="Permanent link">¶</a></h3>
|
|
<p>Cancel or remove a job. The behaviour depends on the job's current state:</p>
|
|
<ul>
|
|
<li><strong>Terminal job</strong> (completed/failed/cancelled): removed from the manager, returning <strong><code>204 No Content</code></strong> with an empty body.</li>
|
|
<li><strong>Queued or downloading job</strong>: cancelled, returning <code>200</code> <code>{"status": "success", "message": "Job cancelled"}</code>.</li>
|
|
</ul>
|
|
<div class="admonition warning">
|
|
<p class="admonition-title">Warning</p>
|
|
<p>A <code>204</code> response has no body. Do not attempt to parse JSON from it.</p>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Job cancelled.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>204</code></td>
|
|
<td>-</td>
|
|
<td>Terminal job removed (empty body).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_PARAMETERS</code></td>
|
|
<td>Job is in a state that cannot be cancelled.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>JOB_NOT_FOUND</code></td>
|
|
<td>No such job.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apidownloadjobsclear-finished"><code>POST /api/download/jobs/clear-finished</code><a class="headerlink" href="#post-apidownloadjobsclear-finished" title="Permanent link">¶</a></h3>
|
|
<p>Remove every terminal (completed/failed/cancelled) job from the manager. No request body.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="9:1"><input checked="checked" id="__tabbed_9_1" name="__tabbed_9" type="radio" /><div class="tabbed-labels"><label for="__tabbed_9_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"removed"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<h3 id="post-apidownloadjobsjob_idretry"><code>POST /api/download/jobs/{job_id}/retry</code><a class="headerlink" href="#post-apidownloadjobsjob_idretry" title="Permanent link">¶</a></h3>
|
|
<p>Enqueue a <strong>new</strong> job that reuses a terminal job's service, title, and parameters. The service allowlist and parameter gates are re-checked. Returns <code>202</code> with the new job's ID.</p>
|
|
<div class="admonition warning">
|
|
<p class="admonition-title">Retry reuses the original, unredacted parameters</p>
|
|
<p>Retry replays the finished job's stored parameters exactly as they were submitted, including any secrets such as <code>credential</code>/<code>credentials</code>, not the redacted <code>parameters</code> view that <code>GET /api/download/jobs</code> and <code>GET /api/history</code> expose. This is deliberate: it lets a retried job reproduce a credentialed download that the redacted job record alone never could. It also means anyone who can retry a job can re-run it with its original credentials, even though those credentials are masked everywhere else in the API.</p>
|
|
</div>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="10:1"><input checked="checked" id="__tabbed_10_1" name="__tabbed_10" type="radio" /><div class="tabbed-labels"><label for="__tabbed_10_1">Response <code>202</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="p">{</span>
|
|
</span><span id="__span-19-2"><a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="w"> </span><span class="nt">"job_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"9c1e2f3a-..."</span><span class="p">,</span>
|
|
</span><span id="__span-19-3"><a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"queued"</span><span class="p">,</span>
|
|
</span><span id="__span-19-4"><a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="w"> </span><span class="nt">"created_time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2026-07-03T12:05:00+00:00"</span>
|
|
</span><span id="__span-19-5"><a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>202</code></td>
|
|
<td>-</td>
|
|
<td>New job queued.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>JOB_NOT_FOUND</code></td>
|
|
<td>No such job.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>409</code></td>
|
|
<td><code>CONFLICT</code></td>
|
|
<td>Job is not in a terminal state.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_SERVICE</code></td>
|
|
<td>Service is no longer allowed.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>403</code></td>
|
|
<td><code>FORBIDDEN</code></td>
|
|
<td>A gated parameter is no longer permitted.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apidownloadjobsjob_idpriority"><code>POST /api/download/jobs/{job_id}/priority</code><a class="headerlink" href="#post-apidownloadjobsjob_idpriority" title="Permanent link">¶</a></h3>
|
|
<p>Move a queued job to the front of the download queue.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="11:1"><input checked="checked" id="__tabbed_11_1" name="__tabbed_11" type="radio" /><div class="tabbed-labels"><label for="__tabbed_11_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"job_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"b0f7c8e2-..."</span><span class="p">,</span><span class="w"> </span><span class="nt">"position"</span><span class="p">:</span><span class="w"> </span><span class="s2">"front"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Job moved to front.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>JOB_NOT_FOUND</code></td>
|
|
<td>No such job.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>409</code></td>
|
|
<td><code>CONFLICT</code></td>
|
|
<td>Job is not queued.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<hr />
|
|
<h2 id="server-management">Server management<a class="headerlink" href="#server-management" title="Permanent link">¶</a></h2>
|
|
<p>Endpoints for profiles, effective configuration, download history, environment checks, and maintenance actions.</p>
|
|
<h3 id="get-apiprofiles"><code>GET /api/profiles</code><a class="headerlink" href="#get-apiprofiles" title="Permanent link">¶</a></h3>
|
|
<p>List the named credential profiles configured per service (usable as the <code>profile</code> parameter elsewhere). Only services whose credentials are a mapping of profile name to credential are listed; services with a single unnamed credential are omitted. Filtered by your allowlist.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="12:1"><input checked="checked" id="__tabbed_12_1" name="__tabbed_12" type="radio" /><div class="tabbed-labels"><label for="__tabbed_12_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="p">{</span>
|
|
</span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a><span class="w"> </span><span class="nt">"profiles"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a><span class="w"> </span><span class="nt">"EXAMPLE"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"default"</span><span class="p">,</span><span class="w"> </span><span class="s2">"premium"</span><span class="p">],</span>
|
|
</span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="w"> </span><span class="nt">"OTHER"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"us-account"</span><span class="p">]</span>
|
|
</span><span id="__span-21-5"><a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-21-6"><a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<h3 id="get-apiconfig"><code>GET /api/config</code><a class="headerlink" href="#get-apiconfig" title="Permanent link">¶</a></h3>
|
|
<p>Return a read-only, redacted view of the effective server configuration, suitable for a settings page in a UI. Secrets are never emitted: keys matching <code>secret</code>, <code>password</code>, <code>token</code>, <code>api_key</code>, or <code>credential</code>, and any userinfo in proxy URLs, are masked.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="13:1"><input checked="checked" id="__tabbed_13_1" name="__tabbed_13" type="radio" /><div class="tabbed-labels"><label for="__tabbed_13_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="p">{</span>
|
|
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a><span class="w"> </span><span class="nt">"config"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-22-3"><a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="w"> </span><span class="nt">"dl"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"..."</span><span class="p">:</span><span class="w"> </span><span class="s2">"redacted default dl parameters"</span><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-22-4"><a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="w"> </span><span class="nt">"serve"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-22-5"><a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a><span class="w"> </span><span class="nt">"max_concurrent_downloads"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
|
|
</span><span id="__span-22-6"><a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a><span class="w"> </span><span class="nt">"job_retention_hours"</span><span class="p">:</span><span class="w"> </span><span class="mi">24</span><span class="p">,</span>
|
|
</span><span id="__span-22-7"><a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a><span class="w"> </span><span class="nt">"history_limit"</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span>
|
|
</span><span id="__span-22-8"><a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-8"></a><span class="w"> </span><span class="nt">"services"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
|
</span><span id="__span-22-9"><a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-9"></a><span class="w"> </span><span class="nt">"remote_only"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
|
|
</span><span id="__span-22-10"><a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-10"></a><span class="w"> </span><span class="nt">"cdm_overrides"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
|
</span><span id="__span-22-11"><a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a><span class="w"> </span><span class="nt">"allow_job_credentials"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span>
|
|
</span><span id="__span-22-12"><a id="__codelineno-22-12" name="__codelineno-22-12" href="#__codelineno-22-12"></a><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-22-13"><a id="__codelineno-22-13" name="__codelineno-22-13" href="#__codelineno-22-13"></a><span class="w"> </span><span class="nt">"directories"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-22-14"><a id="__codelineno-22-14" name="__codelineno-22-14" href="#__codelineno-22-14"></a><span class="w"> </span><span class="nt">"downloads"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/home/user/Downloads/unshackle"</span><span class="p">,</span>
|
|
</span><span id="__span-22-15"><a id="__codelineno-22-15" name="__codelineno-22-15" href="#__codelineno-22-15"></a><span class="w"> </span><span class="nt">"temp"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/home/user/.unshackle/temp"</span><span class="p">,</span>
|
|
</span><span id="__span-22-16"><a id="__codelineno-22-16" name="__codelineno-22-16" href="#__codelineno-22-16"></a><span class="w"> </span><span class="nt">"cache"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/home/user/.unshackle/cache"</span>
|
|
</span><span id="__span-22-17"><a id="__codelineno-22-17" name="__codelineno-22-17" href="#__codelineno-22-17"></a><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-22-18"><a id="__codelineno-22-18" name="__codelineno-22-18" href="#__codelineno-22-18"></a><span class="w"> </span><span class="nt">"services"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"EXAMPLE"</span><span class="p">,</span><span class="w"> </span><span class="s2">"OTHER"</span><span class="p">]</span>
|
|
</span><span id="__span-22-19"><a id="__codelineno-22-19" name="__codelineno-22-19" href="#__codelineno-22-19"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-22-20"><a id="__codelineno-22-20" name="__codelineno-22-20" href="#__codelineno-22-20"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<h3 id="get-apihistory"><code>GET /api/history</code><a class="headerlink" href="#get-apihistory" title="Permanent link">¶</a></h3>
|
|
<p>Read the persisted history of jobs that reached a terminal state, newest first. History is stored in <code>api_history.jsonl</code> in the cache directory; corrupt lines are skipped and a missing file yields an empty list.</p>
|
|
<p><strong>Query parameters</strong></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Param</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>limit</code></td>
|
|
<td>int (≥ 1)</td>
|
|
<td><code>100</code></td>
|
|
<td>Maximum entries to return.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>service</code></td>
|
|
<td>string</td>
|
|
<td>-</td>
|
|
<td>Case-insensitive service filter.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="14:1"><input checked="checked" id="__tabbed_14_1" name="__tabbed_14" type="radio" /><div class="tabbed-labels"><label for="__tabbed_14_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="p">{</span>
|
|
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="w"> </span><span class="nt">"history"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-23-4"><a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="w"> </span><span class="nt">"job_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"b0f7c8e2-..."</span><span class="p">,</span>
|
|
</span><span id="__span-23-5"><a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a><span class="w"> </span><span class="nt">"service"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EXAMPLE"</span><span class="p">,</span>
|
|
</span><span id="__span-23-6"><a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a><span class="w"> </span><span class="nt">"title_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"12345"</span><span class="p">,</span>
|
|
</span><span id="__span-23-7"><a id="__codelineno-23-7" name="__codelineno-23-7" href="#__codelineno-23-7"></a><span class="w"> </span><span class="nt">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example Show S01E01"</span><span class="p">,</span>
|
|
</span><span id="__span-23-8"><a id="__codelineno-23-8" name="__codelineno-23-8" href="#__codelineno-23-8"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"completed"</span><span class="p">,</span>
|
|
</span><span id="__span-23-9"><a id="__codelineno-23-9" name="__codelineno-23-9" href="#__codelineno-23-9"></a><span class="w"> </span><span class="nt">"created_time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2026-07-03T12:00:00+00:00"</span><span class="p">,</span>
|
|
</span><span id="__span-23-10"><a id="__codelineno-23-10" name="__codelineno-23-10" href="#__codelineno-23-10"></a><span class="w"> </span><span class="nt">"completed_time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2026-07-03T12:08:00+00:00"</span><span class="p">,</span>
|
|
</span><span id="__span-23-11"><a id="__codelineno-23-11" name="__codelineno-23-11" href="#__codelineno-23-11"></a><span class="w"> </span><span class="nt">"output_files"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"/downloads/Example.S01E01.mkv"</span><span class="p">],</span>
|
|
</span><span id="__span-23-12"><a id="__codelineno-23-12" name="__codelineno-23-12" href="#__codelineno-23-12"></a><span class="w"> </span><span class="nt">"error_message"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
|
</span><span id="__span-23-13"><a id="__codelineno-23-13" name="__codelineno-23-13" href="#__codelineno-23-13"></a><span class="w"> </span><span class="nt">"parameters"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"..."</span><span class="p">:</span><span class="w"> </span><span class="s2">"redacted"</span><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-23-14"><a id="__codelineno-23-14" name="__codelineno-23-14" href="#__codelineno-23-14"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-23-15"><a id="__codelineno-23-15" name="__codelineno-23-15" href="#__codelineno-23-15"></a><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-23-16"><a id="__codelineno-23-16" name="__codelineno-23-16" href="#__codelineno-23-16"></a><span class="w"> </span><span class="nt">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
|
|
</span><span id="__span-23-17"><a id="__codelineno-23-17" name="__codelineno-23-17" href="#__codelineno-23-17"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>History returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_PARAMETERS</code></td>
|
|
<td>Invalid <code>limit</code>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="delete-apihistoryjob_id"><code>DELETE /api/history/{job_id}</code><a class="headerlink" href="#delete-apihistoryjob_id" title="Permanent link">¶</a></h3>
|
|
<p>Remove a single persisted history entry. Returns <strong><code>204 No Content</code></strong> (empty body) on success.</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>204</code></td>
|
|
<td>-</td>
|
|
<td>Entry removed (empty body).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>NOT_FOUND</code></td>
|
|
<td>No such entry (or outside your allowlist).</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apimaintenanceclear-cache-and-post-apimaintenanceclear-temp"><code>POST /api/maintenance/clear-cache</code> and <code>POST /api/maintenance/clear-temp</code><a class="headerlink" href="#post-apimaintenanceclear-cache-and-post-apimaintenanceclear-temp" title="Permanent link">¶</a></h3>
|
|
<p>Delete and recreate the cache or temp directory. Neither takes a request body. Both are blocked with <code>409 CONFLICT</code> if any job is currently <code>downloading</code> (the <code>details</code> include the offending <code>active_jobs</code>).</p>
|
|
<p>The <code>409</code> guard is about active file I/O, not an arbitrary lock: an in-flight job may still be <em>reading</em> cached title data under the cache directory, and active download workers are <em>writing</em> segment files under temp. Removing either directory mid-download would corrupt those running jobs, so the endpoints refuse until nothing is downloading.</p>
|
|
<div class="admonition warning">
|
|
<p class="admonition-title">clear-cache also wipes download history</p>
|
|
<p>The persistent history read by <a href="#get-apihistory"><code>GET /api/history</code></a> lives in <code>api_history.jsonl</code> <strong>inside the cache directory</strong>. Because clear-cache deletes and recreates that whole directory, calling it also erases your entire download history, not just cached title data. If you want to keep history, do not clear the cache; remove individual entries with <a href="#delete-apihistoryjob_id"><code>DELETE /api/history/{job_id}</code></a> instead.</p>
|
|
</div>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="15:1"><input checked="checked" id="__tabbed_15_1" name="__tabbed_15" type="radio" /><div class="tabbed-labels"><label for="__tabbed_15_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"cleared"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="nt">"freed_bytes"</span><span class="p">:</span><span class="w"> </span><span class="mi">1048576</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Directory cleared.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>409</code></td>
|
|
<td><code>CONFLICT</code></td>
|
|
<td>A download is currently active.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apimaintenancerefresh-services"><code>POST /api/maintenance/refresh-services</code><a class="headerlink" href="#post-apimaintenancerefresh-services" title="Permanent link">¶</a></h3>
|
|
<p>git-pull every service repository configured under <code>directories.services</code>. <code>refreshed</code> is <code>true</code> when all repos updated successfully (or none are configured).</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="16:1"><input checked="checked" id="__tabbed_16_1" name="__tabbed_16" type="radio" /><div class="tabbed-labels"><label for="__tabbed_16_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="p">{</span>
|
|
</span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a><span class="w"> </span><span class="nt">"refreshed"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
</span><span id="__span-25-3"><a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="w"> </span><span class="nt">"repos"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-25-4"><a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"spec"</span><span class="p">:</span><span class="w"> </span><span class="s2">"github.com/example/services"</span><span class="p">,</span><span class="w"> </span><span class="nt">"updated"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="nt">"changes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"a1b2c3d Update EXAMPLE"</span><span class="p">]</span><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-25-5"><a id="__codelineno-25-5" name="__codelineno-25-5" href="#__codelineno-25-5"></a><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-25-6"><a id="__codelineno-25-6" name="__codelineno-25-6" href="#__codelineno-25-6"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<h3 id="get-apienvcheck"><code>GET /api/env/check</code><a class="headerlink" href="#get-apienvcheck" title="Permanent link">¶</a></h3>
|
|
<p>Report the install status of the external binaries unshackle depends on (the same set <code>unshackle env check</code> inspects), with best-effort version detection.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="17:1"><input checked="checked" id="__tabbed_17_1" name="__tabbed_17" type="radio" /><div class="tabbed-labels"><label for="__tabbed_17_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="p">{</span>
|
|
</span><span id="__span-26-2"><a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a><span class="w"> </span><span class="nt">"checks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
|
</span><span id="__span-26-3"><a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ffmpeg"</span><span class="p">,</span><span class="w"> </span><span class="nt">"installed"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"6.1.1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"required"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-26-4"><a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ccextractor"</span><span class="p">,</span><span class="w"> </span><span class="nt">"installed"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="nt">"required"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-26-5"><a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-26-6"><a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<h2 id="remote-dl-sessions">Remote-dl sessions<a class="headerlink" href="#remote-dl-sessions" title="Permanent link">¶</a></h2>
|
|
<div class="admonition note">
|
|
<p class="admonition-title">Developer feature</p>
|
|
<p>The <code>/api/session/*</code> endpoints power unshackle's <strong>remote download</strong> mode, where a thin local client authenticates once against a remote server, then fetches titles, tracks, and segments and proxies DRM licensing back through it. These endpoints are exposed in <code>--remote-only</code> mode, and they are what the built-in <code>RemoteService</code> client drives. Most end users never call them directly.</p>
|
|
</div>
|
|
<p>Sessions are held in memory. They expire after <code>serve.session_ttl</code> (default 300s), except while awaiting interactive authentication input, which uses a 600s window. A session is bound to the IP that created it, so a request from a different IP is rejected with <code>403 FORBIDDEN</code>.</p>
|
|
<h3 id="session-lifecycle-overview">Session lifecycle overview<a class="headerlink" href="#session-lifecycle-overview" title="Permanent link">¶</a></h3>
|
|
<div class="language-text highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a>POST /api/session/create → returns session_id, status "authenticating"
|
|
</span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a>GET /api/session/{id}/prompt → poll until authenticated (submit answers via POST)
|
|
</span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a>GET /api/session/{id}/titles → list titles
|
|
</span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a>POST /api/session/{id}/tracks → tracks + chapters (with URLs) for one title
|
|
</span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a>POST /api/session/{id}/segments → resolve segment URLs / DRM / headers per track
|
|
</span><span id="__span-27-6"><a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a>POST /api/session/{id}/license → proxy or server-CDM DRM licensing
|
|
</span><span id="__span-27-7"><a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a>DELETE /api/session/{id} → tear down, harvest updated cache
|
|
</span></code></pre></div>
|
|
<h3 id="post-apisessioncreate"><code>POST /api/session/create</code><a class="headerlink" href="#post-apisessioncreate" title="Permanent link">¶</a></h3>
|
|
<p>Create a session for a service and title. Authentication runs asynchronously in the background. This call returns immediately with <code>status: "authenticating"</code>, and you then poll the prompt endpoint. The body accepts <code>service</code> and <code>title_id</code> (both required) plus a broad set of optional keys (<code>additionalProperties</code> is allowed): <code>credentials</code> (<code>{username, password, extra?}</code>), <code>cookies</code> (base64 of zlib-compressed Netscape cookie file), <code>proxy</code>, <code>no_proxy</code>, <code>profile</code>, <code>cache</code> (map of forwarded cache files), <code>client_region</code>, <code>cdm_type</code>, <code>range_</code>, <code>vcodec</code>, <code>quality</code>, <code>best_available</code>, and any service CLI options.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="18:1"><input checked="checked" id="__tabbed_18_1" name="__tabbed_18" type="radio" /><div class="tabbed-labels"><label for="__tabbed_18_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="p">{</span>
|
|
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a><span class="w"> </span><span class="nt">"session_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d4e5f6a7-..."</span><span class="p">,</span>
|
|
</span><span id="__span-28-3"><a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a><span class="w"> </span><span class="nt">"service"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EXAMPLE"</span><span class="p">,</span>
|
|
</span><span id="__span-28-4"><a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"authenticating"</span>
|
|
</span><span id="__span-28-5"><a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-5"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Session created; authentication in progress.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>Missing <code>service</code> or <code>title_id</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_SERVICE</code></td>
|
|
<td>Unknown or disallowed service.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="get-apisessionsession_idprompt"><code>GET /api/session/{session_id}/prompt</code><a class="headerlink" href="#get-apisessionsession_idprompt" title="Permanent link">¶</a></h3>
|
|
<p>Poll for the authentication status and any pending interactive prompt (OTP, PIN, device code). Response variants:</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="19:4"><input checked="checked" id="__tabbed_19_1" name="__tabbed_19" type="radio" /><input id="__tabbed_19_2" name="__tabbed_19" type="radio" /><input id="__tabbed_19_3" name="__tabbed_19" type="radio" /><input id="__tabbed_19_4" name="__tabbed_19" type="radio" /><div class="tabbed-labels"><label for="__tabbed_19_1">Authenticating</label><label for="__tabbed_19_2">Pending input</label><label for="__tabbed_19_3">Authenticated</label><label for="__tabbed_19_4">Failed</label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"authenticating"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"pending_input"</span><span class="p">,</span><span class="w"> </span><span class="nt">"prompt"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Enter the code sent to your email:"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"authenticated"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"failed"</span><span class="p">,</span><span class="w"> </span><span class="nt">"error"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Invalid credentials"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Status returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>403</code></td>
|
|
<td><code>FORBIDDEN</code></td>
|
|
<td>Request IP differs from the session creator.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>SESSION_NOT_FOUND</code></td>
|
|
<td>No such session.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apisessionsession_idprompt"><code>POST /api/session/{session_id}/prompt</code><a class="headerlink" href="#post-apisessionsession_idprompt" title="Permanent link">¶</a></h3>
|
|
<p>Submit a response to a pending prompt. Body: <code>{ "response": "..." }</code> (required).</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="20:1"><input checked="checked" id="__tabbed_20_1" name="__tabbed_20" type="radio" /><div class="tabbed-labels"><label for="__tabbed_20_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"accepted"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Response accepted.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>Missing <code>response</code>, or no prompt is pending.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>SESSION_NOT_FOUND</code></td>
|
|
<td>No such session.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="get-apisessionsession_idtitles"><code>GET /api/session/{session_id}/titles</code><a class="headerlink" href="#get-apisessionsession_idtitles" title="Permanent link">¶</a></h3>
|
|
<p>Fetch the titles for an authenticated session.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="21:1"><input checked="checked" id="__tabbed_21_1" name="__tabbed_21" type="radio" /><div class="tabbed-labels"><label for="__tabbed_21_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="p">{</span>
|
|
</span><span id="__span-34-2"><a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a><span class="w"> </span><span class="nt">"session_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d4e5f6a7-..."</span><span class="p">,</span>
|
|
</span><span id="__span-34-3"><a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a><span class="w"> </span><span class="nt">"titles"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"episode"</span><span class="p">,</span><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Pilot"</span><span class="p">,</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ep-1"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span>
|
|
</span><span id="__span-34-4"><a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p>Requires an authenticated session; <code>404 SESSION_NOT_FOUND</code> otherwise.</p>
|
|
<h3 id="post-apisessionsession_idtracks"><code>POST /api/session/{session_id}/tracks</code><a class="headerlink" href="#post-apisessionsession_idtracks" title="Permanent link">¶</a></h3>
|
|
<p>Get tracks and chapters for a specific title within the session. Body: <code>{ "title_id": "..." }</code> (required). Unlike <code>list-tracks</code>, track objects here <strong>include</strong> download URLs, along with session headers/cookies and manifest data the client needs to download directly.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="22:1"><input checked="checked" id="__tabbed_22_1" name="__tabbed_22" type="radio" /><div class="tabbed-labels"><label for="__tabbed_22_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-35-1"><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a><span class="p">{</span>
|
|
</span><span id="__span-35-2"><a id="__codelineno-35-2" name="__codelineno-35-2" href="#__codelineno-35-2"></a><span class="w"> </span><span class="nt">"title"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"episode"</span><span class="p">,</span><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Pilot"</span><span class="p">,</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ep-1"</span><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-35-3"><a id="__codelineno-35-3" name="__codelineno-35-3" href="#__codelineno-35-3"></a><span class="w"> </span><span class="nt">"video"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"v-1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://..."</span><span class="p">,</span><span class="w"> </span><span class="nt">"drm"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-35-4"><a id="__codelineno-35-4" name="__codelineno-35-4" href="#__codelineno-35-4"></a><span class="w"> </span><span class="nt">"audio"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"a-1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://..."</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-35-5"><a id="__codelineno-35-5" name="__codelineno-35-5" href="#__codelineno-35-5"></a><span class="w"> </span><span class="nt">"subtitles"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"s-1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://..."</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-35-6"><a id="__codelineno-35-6" name="__codelineno-35-6" href="#__codelineno-35-6"></a><span class="w"> </span><span class="nt">"chapters"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"timestamp"</span><span class="p">:</span><span class="w"> </span><span class="s2">"00:00:00.000"</span><span class="p">,</span><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Intro"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-35-7"><a id="__codelineno-35-7" name="__codelineno-35-7" href="#__codelineno-35-7"></a><span class="w"> </span><span class="nt">"attachments"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://..."</span><span class="p">,</span><span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"font.ttf"</span><span class="p">,</span><span class="w"> </span><span class="nt">"mime_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"font/ttf"</span><span class="p">,</span><span class="w"> </span><span class="nt">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-35-8"><a id="__codelineno-35-8" name="__codelineno-35-8" href="#__codelineno-35-8"></a><span class="w"> </span><span class="nt">"manifests"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dash"</span><span class="p">,</span><span class="w"> </span><span class="nt">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://..."</span><span class="p">,</span><span class="w"> </span><span class="nt">"data"</span><span class="p">:</span><span class="w"> </span><span class="s2">"<base64 zlib xml>"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span>
|
|
</span><span id="__span-35-9"><a id="__codelineno-35-9" name="__codelineno-35-9" href="#__codelineno-35-9"></a><span class="w"> </span><span class="nt">"session_headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"User-Agent"</span><span class="p">:</span><span class="w"> </span><span class="s2">"..."</span><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-35-10"><a id="__codelineno-35-10" name="__codelineno-35-10" href="#__codelineno-35-10"></a><span class="w"> </span><span class="nt">"session_cookies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"sid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"..."</span><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-35-11"><a id="__codelineno-35-11" name="__codelineno-35-11" href="#__codelineno-35-11"></a><span class="w"> </span><span class="nt">"server_cdm_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"widevine"</span>
|
|
</span><span id="__span-35-12"><a id="__codelineno-35-12" name="__codelineno-35-12" href="#__codelineno-35-12"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Tracks returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>Missing or unknown <code>title_id</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>SESSION_NOT_FOUND</code></td>
|
|
<td>No such session.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apisessionsession_idsegments"><code>POST /api/session/{session_id}/segments</code><a class="headerlink" href="#post-apisessionsession_idsegments" title="Permanent link">¶</a></h3>
|
|
<p>Resolve the download URL, DRM info, headers, cookies, and raw track data for selected tracks. Body: <code>{ "track_ids": ["v-1", "a-1"] }</code> (required).</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="23:1"><input checked="checked" id="__tabbed_23_1" name="__tabbed_23" type="radio" /><div class="tabbed-labels"><label for="__tabbed_23_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-36-1"><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a><span class="p">{</span>
|
|
</span><span id="__span-36-2"><a id="__codelineno-36-2" name="__codelineno-36-2" href="#__codelineno-36-2"></a><span class="w"> </span><span class="nt">"tracks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
|
</span><span id="__span-36-3"><a id="__codelineno-36-3" name="__codelineno-36-3" href="#__codelineno-36-3"></a><span class="w"> </span><span class="nt">"v-1"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"descriptor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DASH"</span><span class="p">,</span><span class="w"> </span><span class="nt">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://..."</span><span class="p">,</span><span class="w"> </span><span class="nt">"drm"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="nt">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nt">"cookies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nt">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-36-4"><a id="__codelineno-36-4" name="__codelineno-36-4" href="#__codelineno-36-4"></a><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-36-5"><a id="__codelineno-36-5" name="__codelineno-36-5" href="#__codelineno-36-5"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>Segment info returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>Missing <code>track_ids</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>TRACK_NOT_FOUND</code></td>
|
|
<td>An unknown track ID was requested.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="post-apisessionsession_idlicense"><code>POST /api/session/{session_id}/license</code><a class="headerlink" href="#post-apisessionsession_idlicense" title="Permanent link">¶</a></h3>
|
|
<p>Acquire DRM keys. Two modes are supported via the <code>mode</code> field.</p>
|
|
<p><strong>Proxy mode</strong> (<code>mode: "proxy"</code>, the default) forwards the client's CDM <code>challenge</code> to the service's license endpoint and returns the raw license bytes:</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="24:2"><input checked="checked" id="__tabbed_24_1" name="__tabbed_24" type="radio" /><input id="__tabbed_24_2" name="__tabbed_24" type="radio" /><div class="tabbed-labels"><label for="__tabbed_24_1">Request</label><label for="__tabbed_24_2">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-37-1"><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"track_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"v-1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"challenge"</span><span class="p">:</span><span class="w"> </span><span class="s2">"<base64 CDM challenge>"</span><span class="p">,</span><span class="w"> </span><span class="nt">"drm_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"widevine"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-38-1"><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"license"</span><span class="p">:</span><span class="w"> </span><span class="s2">"<base64 license bytes>"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p><strong>Server-CDM mode</strong> (<code>mode: "server_cdm"</code>) runs the full CDM flow on the server using the device configured for your API key, returning content keys directly. Use <code>track_id</code> for a single track or <code>track_ids</code> for a batch:</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="25:2"><input checked="checked" id="__tabbed_25_1" name="__tabbed_25" type="radio" /><input id="__tabbed_25_2" name="__tabbed_25" type="radio" /><div class="tabbed-labels"><label for="__tabbed_25_1">Single: Response <code>200</code></label><label for="__tabbed_25_2">Batch: Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-39-1"><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"keys"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"<kid_hex>"</span><span class="p">:</span><span class="w"> </span><span class="s2">"<key_hex>"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-40-1"><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a><span class="p">{</span><span class="w"> </span><span class="nt">"keys"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"v-1"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"<kid_hex>"</span><span class="p">:</span><span class="w"> </span><span class="s2">"<key_hex>"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nt">"drm_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"widevine"</span><span class="w"> </span><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Field</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>track_id</code> / <code>track_ids</code></td>
|
|
<td>Single track, or a batch of tracks.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>challenge</code></td>
|
|
<td>Base64 CDM challenge (proxy mode).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>pssh</code></td>
|
|
<td>Base64 PSSH (server-CDM mode).</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>drm_type</code></td>
|
|
<td><code>widevine</code> (default) or <code>playready</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>mode</code></td>
|
|
<td><code>proxy</code> (default) or <code>server_cdm</code>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Error code</th>
|
|
<th>Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>200</code></td>
|
|
<td>-</td>
|
|
<td>License/keys returned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>Missing challenge/PSSH, or no CDM device configured for the key.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>400</code></td>
|
|
<td><code>INVALID_PARAMETERS</code></td>
|
|
<td>Unsupported <code>drm_type</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>TRACK_NOT_FOUND</code></td>
|
|
<td>Unknown track ID.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>404</code></td>
|
|
<td><code>NO_CONTENT</code></td>
|
|
<td>Server CDM produced no keys.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>502</code></td>
|
|
<td><code>SERVICE_ERROR</code></td>
|
|
<td>The service aborted during licensing.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3 id="get-apisessionsession_id"><code>GET /api/session/{session_id}</code><a class="headerlink" href="#get-apisessionsession_id" title="Permanent link">¶</a></h3>
|
|
<p>Return session metadata and validity.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="26:1"><input checked="checked" id="__tabbed_26_1" name="__tabbed_26" type="radio" /><div class="tabbed-labels"><label for="__tabbed_26_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-41-1"><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a><span class="p">{</span>
|
|
</span><span id="__span-41-2"><a id="__codelineno-41-2" name="__codelineno-41-2" href="#__codelineno-41-2"></a><span class="w"> </span><span class="nt">"session_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d4e5f6a7-..."</span><span class="p">,</span>
|
|
</span><span id="__span-41-3"><a id="__codelineno-41-3" name="__codelineno-41-3" href="#__codelineno-41-3"></a><span class="w"> </span><span class="nt">"service"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EXAMPLE"</span><span class="p">,</span>
|
|
</span><span id="__span-41-4"><a id="__codelineno-41-4" name="__codelineno-41-4" href="#__codelineno-41-4"></a><span class="w"> </span><span class="nt">"valid"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
</span><span id="__span-41-5"><a id="__codelineno-41-5" name="__codelineno-41-5" href="#__codelineno-41-5"></a><span class="w"> </span><span class="nt">"expires_in"</span><span class="p">:</span><span class="w"> </span><span class="mi">300</span><span class="p">,</span>
|
|
</span><span id="__span-41-6"><a id="__codelineno-41-6" name="__codelineno-41-6" href="#__codelineno-41-6"></a><span class="w"> </span><span class="nt">"track_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span>
|
|
</span><span id="__span-41-7"><a id="__codelineno-41-7" name="__codelineno-41-7" href="#__codelineno-41-7"></a><span class="w"> </span><span class="nt">"title_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span>
|
|
</span><span id="__span-41-8"><a id="__codelineno-41-8" name="__codelineno-41-8" href="#__codelineno-41-8"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p><code>404 SESSION_NOT_FOUND</code> if the session does not exist or has expired.</p>
|
|
<h3 id="delete-apisessionsession_id"><code>DELETE /api/session/{session_id}</code><a class="headerlink" href="#delete-apisessionsession_id" title="Permanent link">¶</a></h3>
|
|
<p>Tear down a session. Its input bridge is cancelled, any updated cache files are harvested, and the session plus its cache directory are deleted.</p>
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="27:1"><input checked="checked" id="__tabbed_27_1" name="__tabbed_27" type="radio" /><div class="tabbed-labels"><label for="__tabbed_27_1">Response <code>200</code></label></div>
|
|
<div class="tabbed-content">
|
|
<div class="tabbed-block">
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-42-1"><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a><span class="p">{</span>
|
|
</span><span id="__span-42-2"><a id="__codelineno-42-2" name="__codelineno-42-2" href="#__codelineno-42-2"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ok"</span><span class="p">,</span>
|
|
</span><span id="__span-42-3"><a id="__codelineno-42-3" name="__codelineno-42-3" href="#__codelineno-42-3"></a><span class="w"> </span><span class="nt">"cache"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"tokens.json"</span><span class="p">:</span><span class="w"> </span><span class="s2">"<base64 zlib bytes>"</span><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-42-4"><a id="__codelineno-42-4" name="__codelineno-42-4" href="#__codelineno-42-4"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p>The <code>cache</code> field is present only if the session produced cache files. <code>404 SESSION_NOT_FOUND</code> if the session does not exist.</p>
|
|
<hr />
|
|
<h2 id="error-responses">Error responses<a class="headerlink" href="#error-responses" title="Permanent link">¶</a></h2>
|
|
<p>Every structured error raised inside a handler is serialized to the same JSON envelope:</p>
|
|
<div class="language-json highlight"><pre><span></span><code><span id="__span-43-1"><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a><span class="p">{</span>
|
|
</span><span id="__span-43-2"><a id="__codelineno-43-2" name="__codelineno-43-2" href="#__codelineno-43-2"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"error"</span><span class="p">,</span>
|
|
</span><span id="__span-43-3"><a id="__codelineno-43-3" name="__codelineno-43-3" href="#__codelineno-43-3"></a><span class="w"> </span><span class="nt">"error_code"</span><span class="p">:</span><span class="w"> </span><span class="s2">"INVALID_PARAMETERS"</span><span class="p">,</span>
|
|
</span><span id="__span-43-4"><a id="__codelineno-43-4" name="__codelineno-43-4" href="#__codelineno-43-4"></a><span class="w"> </span><span class="nt">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Invalid video codec: XYZ"</span><span class="p">,</span>
|
|
</span><span id="__span-43-5"><a id="__codelineno-43-5" name="__codelineno-43-5" href="#__codelineno-43-5"></a><span class="w"> </span><span class="nt">"timestamp"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2026-07-03T12:00:00+00:00"</span><span class="p">,</span>
|
|
</span><span id="__span-43-6"><a id="__codelineno-43-6" name="__codelineno-43-6" href="#__codelineno-43-6"></a><span class="w"> </span><span class="nt">"details"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vcodec"</span><span class="w"> </span><span class="p">},</span>
|
|
</span><span id="__span-43-7"><a id="__codelineno-43-7" name="__codelineno-43-7" href="#__codelineno-43-7"></a><span class="w"> </span><span class="nt">"retryable"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
|
</span><span id="__span-43-8"><a id="__codelineno-43-8" name="__codelineno-43-8" href="#__codelineno-43-8"></a><span class="w"> </span><span class="nt">"debug_info"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">"exception_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"APIError"</span><span class="p">,</span><span class="w"> </span><span class="nt">"traceback"</span><span class="p">:</span><span class="w"> </span><span class="s2">"..."</span><span class="w"> </span><span class="p">}</span>
|
|
</span><span id="__span-43-9"><a id="__codelineno-43-9" name="__codelineno-43-9" href="#__codelineno-43-9"></a><span class="p">}</span>
|
|
</span></code></pre></div>
|
|
<ul>
|
|
<li><code>details</code> appears only when non-empty.</li>
|
|
<li><code>retryable</code> appears only when the error is retryable (e.g. network errors, rate limiting).</li>
|
|
<li><code>debug_info</code> appears only when the server was started with <code>--debug-api</code>.</li>
|
|
</ul>
|
|
<div class="admonition warning">
|
|
<p class="admonition-title">Authentication errors differ</p>
|
|
<p>Errors raised by the API-key middleware use a distinct shape (<code>{"status": 401, "message": "Secret Key is Empty."}</code> or <code>{"status": 401, "message": "Secret Key is Invalid."}</code>) with an integer <code>status</code> and no <code>error_code</code>, <code>timestamp</code>, or <code>details</code>. A malformed JSON body on any POST, by contrast, returns the standard envelope with <code>error_code: "INVALID_INPUT"</code>.</p>
|
|
</div>
|
|
<h3 id="error-codes-and-default-status">Error codes and default status<a class="headerlink" href="#error-codes-and-default-status" title="Permanent link">¶</a></h3>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Error code</th>
|
|
<th>HTTP status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>INVALID_INPUT</code></td>
|
|
<td>400</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>INVALID_SERVICE</code></td>
|
|
<td>400</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>INVALID_PROXY</code></td>
|
|
<td>400</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>INVALID_PARAMETERS</code></td>
|
|
<td>400</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>AUTH_FAILED</code></td>
|
|
<td>401</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>FORBIDDEN</code></td>
|
|
<td>403</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>GEOFENCE</code></td>
|
|
<td>403</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>NOT_FOUND</code></td>
|
|
<td>404</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>NO_CONTENT</code></td>
|
|
<td>404</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>JOB_NOT_FOUND</code></td>
|
|
<td>404</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>SESSION_NOT_FOUND</code></td>
|
|
<td>404</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>TRACK_NOT_FOUND</code></td>
|
|
<td>404</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>CONFLICT</code></td>
|
|
<td>409</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>RATE_LIMITED</code></td>
|
|
<td>429</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>INTERNAL_ERROR</code></td>
|
|
<td>500</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>DOWNLOAD_ERROR</code></td>
|
|
<td>500</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>WORKER_ERROR</code></td>
|
|
<td>500</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>SERVICE_ERROR</code></td>
|
|
<td>502</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>DRM_ERROR</code></td>
|
|
<td>502</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>NETWORK_ERROR</code></td>
|
|
<td>503</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>SERVICE_UNAVAILABLE</code></td>
|
|
<td>503</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>When a generic (uncategorized) exception reaches a handler, unshackle inspects its message and type to pick a code. For example, messages mentioning "connection" or "timeout" become <code>NETWORK_ERROR</code> (503, retryable), "rate limit" or "429" become <code>RATE_LIMITED</code> (429, retryable), and anything unrecognized collapses to <code>INTERNAL_ERROR</code> (500).</p>
|
|
<hr />
|
|
<h2 id="see-also">See also<a class="headerlink" href="#see-also" title="Permanent link">¶</a></h2>
|
|
<ul>
|
|
<li><a href="../">REST API overview</a>. What the server is and when to use it.</li>
|
|
<li><a href="../authentication/">Authentication</a>. Keys, server modes, and the <code>X-Secret-Key</code> header.</li>
|
|
<li><a href="../quickstart/">Quickstart</a>. A first end-to-end request walkthrough.</li>
|
|
<li><a href="../../../guide/downloading/">Downloading</a>. The <code>dl</code> flags mirrored by <code>POST /api/download</code>.</li>
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</article>
|
|
</div>
|
|
|
|
|
|
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
|
|
|
|
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
|
</div>
|
|
|
|
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
|
|
Back to top
|
|
</button>
|
|
|
|
</main>
|
|
|
|
<footer class="md-footer">
|
|
|
|
|
|
|
|
<nav class="md-footer__inner md-grid" aria-label="Footer" >
|
|
|
|
|
|
<a href="../authentication/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Authentication">
|
|
<div class="md-footer__button md-icon">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
|
</div>
|
|
<div class="md-footer__title">
|
|
<span class="md-footer__direction">
|
|
Previous
|
|
</span>
|
|
<div class="md-ellipsis">
|
|
Authentication
|
|
</div>
|
|
</div>
|
|
</a>
|
|
|
|
|
|
|
|
<a href="../job-lifecycle/" class="md-footer__link md-footer__link--next" aria-label="Next: Job Lifecycle">
|
|
<div class="md-footer__title">
|
|
<span class="md-footer__direction">
|
|
Next
|
|
</span>
|
|
<div class="md-ellipsis">
|
|
Job Lifecycle
|
|
</div>
|
|
</div>
|
|
<div class="md-footer__button md-icon">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
|
|
</div>
|
|
</a>
|
|
|
|
</nav>
|
|
|
|
|
|
<div class="md-footer-meta md-typeset">
|
|
<div class="md-footer-meta__inner md-grid">
|
|
<div class="md-copyright">
|
|
|
|
|
|
Made with
|
|
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
|
|
Material for MkDocs
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
</div>
|
|
<div class="md-dialog" data-md-component="dialog">
|
|
<div class="md-dialog__inner md-typeset"></div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script id="__config" type="application/json">{"annotate": null, "base": "../../..", "features": ["content.code.annotate", "content.code.copy", "content.tabs.link", "content.tooltips", "navigation.footer", "navigation.indexes", "navigation.sections", "navigation.tabs", "navigation.top", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
|
|
|
|
|
|
<script src="../../../assets/javascripts/bundle.d7400e89.min.js"></script>
|
|
|
|
|
|
</body>
|
|
</html> |