Files
unshackle/reference/configuration/index.html
T
2026-07-11 15:43:47 +00:00

4266 lines
145 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/reference/configuration/">
<link rel="prev" href="../../guide/troubleshooting/">
<link rel="next" href="../../dev/creating-a-service/">
<link rel="icon" href="../../assets/favicon.svg">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<title>Reference - unshackle</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.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="#configuration-reference" 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">
Reference
</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 md-tabs__item--active">
<a href="./" class="md-tabs__link">
Configuration
</a>
</li>
<li class="md-tabs__item">
<a href="../../dev/creating-a-service/" class="md-tabs__link">
Developer
</a>
</li>
<li class="md-tabs__item">
<a href="../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--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" checked>
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="">
<span class="md-ellipsis">
Configuration
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="true">
<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 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">
Reference
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Reference
</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="#quick-index" class="md-nav__link">
<span class="md-ellipsis">
Quick index
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#directories" class="md-nav__link">
<span class="md-ellipsis">
Directories
</span>
</a>
<nav class="md-nav" aria-label="Directories">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#filenames" class="md-nav__link">
<span class="md-ellipsis">
Filenames
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#services-auth" class="md-nav__link">
<span class="md-ellipsis">
Services &amp; authentication
</span>
</a>
<nav class="md-nav" aria-label="Services &amp; authentication">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#services" class="md-nav__link">
<span class="md-ellipsis">
services
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#credentials" class="md-nav__link">
<span class="md-ellipsis">
credentials
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#firefox_cookies" class="md-nav__link">
<span class="md-ellipsis">
firefox_cookies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#remote_services" class="md-nav__link">
<span class="md-ellipsis">
remote_services
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#serve" class="md-nav__link">
<span class="md-ellipsis">
serve
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#download-processing" class="md-nav__link">
<span class="md-ellipsis">
Download &amp; processing
</span>
</a>
<nav class="md-nav" aria-label="Download &amp; processing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#dl" class="md-nav__link">
<span class="md-ellipsis">
dl
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#subtitle" class="md-nav__link">
<span class="md-ellipsis">
subtitle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#audio" class="md-nav__link">
<span class="md-ellipsis">
audio
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#muxing" class="md-nav__link">
<span class="md-ellipsis">
muxing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#language_tags" class="md-nav__link">
<span class="md-ellipsis">
language_tags
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#output-naming" class="md-nav__link">
<span class="md-ellipsis">
Output &amp; naming
</span>
</a>
<nav class="md-nav" aria-label="Output &amp; naming">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#output_template" class="md-nav__link">
<span class="md-ellipsis">
output_template
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#tagging-naming-keys" class="md-nav__link">
<span class="md-ellipsis">
Tagging &amp; naming keys
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#drm-cdm" class="md-nav__link">
<span class="md-ellipsis">
DRM &amp; CDM
</span>
</a>
<nav class="md-nav" aria-label="DRM &amp; CDM">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#cdm" class="md-nav__link">
<span class="md-ellipsis">
cdm
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#remote_cdm" class="md-nav__link">
<span class="md-ellipsis">
remote_cdm
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#decryption" class="md-nav__link">
<span class="md-ellipsis">
decryption
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#network-proxy" class="md-nav__link">
<span class="md-ellipsis">
Network &amp; proxy
</span>
</a>
<nav class="md-nav" aria-label="Network &amp; proxy">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#network" class="md-nav__link">
<span class="md-ellipsis">
network
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#headers" class="md-nav__link">
<span class="md-ellipsis">
headers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#proxy_providers" class="md-nav__link">
<span class="md-ellipsis">
proxy_providers
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#key-vaults" class="md-nav__link">
<span class="md-ellipsis">
Key vaults
</span>
</a>
<nav class="md-nav" aria-label="Key vaults">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#key_vaults" class="md-nav__link">
<span class="md-ellipsis">
key_vaults
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#vault_timeout" class="md-nav__link">
<span class="md-ellipsis">
vault_timeout
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#external-api-keys" class="md-nav__link">
<span class="md-ellipsis">
External API keys
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#caching-updates" class="md-nav__link">
<span class="md-ellipsis">
Caching &amp; updates
</span>
</a>
<nav class="md-nav" aria-label="Caching &amp; updates">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#title-cache" class="md-nav__link">
<span class="md-ellipsis">
Title cache
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#update-checks" class="md-nav__link">
<span class="md-ellipsis">
Update checks
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#logging-privacy-debug" class="md-nav__link">
<span class="md-ellipsis">
Logging, privacy &amp; debug
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#deprecated-removed-keys" class="md-nav__link">
<span class="md-ellipsis">
Deprecated &amp; removed keys
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#a-complete-annotated-example" class="md-nav__link">
<span class="md-ellipsis">
A complete annotated example
</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_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<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="false">
<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="../../dev/creating-a-service/" class="md-nav__link">
<span class="md-ellipsis">
Creating a Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/service-architecture/" class="md-nav__link">
<span class="md-ellipsis">
Service Architecture
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_3" >
<div class="md-nav__link md-nav__container">
<a href="../../dev/rest-api/" 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="0">
<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="false">
<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="../../dev/rest-api/quickstart/" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/authentication/" class="md-nav__link">
<span class="md-ellipsis">
Authentication
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/endpoints/" class="md-nav__link">
<span class="md-ellipsis">
Endpoints
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/job-lifecycle/" class="md-nav__link">
<span class="md-ellipsis">
Job Lifecycle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/remote-sessions/" class="md-nav__link">
<span class="md-ellipsis">
Remote Sessions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/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="../api/service/" class="md-nav__link">
<span class="md-ellipsis">
Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../api/config/" class="md-nav__link">
<span class="md-ellipsis">
Config
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../api/tracks/" class="md-nav__link">
<span class="md-ellipsis">
Tracks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../api/titles/" class="md-nav__link">
<span class="md-ellipsis">
Titles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../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="#quick-index" class="md-nav__link">
<span class="md-ellipsis">
Quick index
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#directories" class="md-nav__link">
<span class="md-ellipsis">
Directories
</span>
</a>
<nav class="md-nav" aria-label="Directories">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#filenames" class="md-nav__link">
<span class="md-ellipsis">
Filenames
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#services-auth" class="md-nav__link">
<span class="md-ellipsis">
Services &amp; authentication
</span>
</a>
<nav class="md-nav" aria-label="Services &amp; authentication">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#services" class="md-nav__link">
<span class="md-ellipsis">
services
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#credentials" class="md-nav__link">
<span class="md-ellipsis">
credentials
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#firefox_cookies" class="md-nav__link">
<span class="md-ellipsis">
firefox_cookies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#remote_services" class="md-nav__link">
<span class="md-ellipsis">
remote_services
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#serve" class="md-nav__link">
<span class="md-ellipsis">
serve
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#download-processing" class="md-nav__link">
<span class="md-ellipsis">
Download &amp; processing
</span>
</a>
<nav class="md-nav" aria-label="Download &amp; processing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#dl" class="md-nav__link">
<span class="md-ellipsis">
dl
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#subtitle" class="md-nav__link">
<span class="md-ellipsis">
subtitle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#audio" class="md-nav__link">
<span class="md-ellipsis">
audio
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#muxing" class="md-nav__link">
<span class="md-ellipsis">
muxing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#language_tags" class="md-nav__link">
<span class="md-ellipsis">
language_tags
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#output-naming" class="md-nav__link">
<span class="md-ellipsis">
Output &amp; naming
</span>
</a>
<nav class="md-nav" aria-label="Output &amp; naming">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#output_template" class="md-nav__link">
<span class="md-ellipsis">
output_template
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#tagging-naming-keys" class="md-nav__link">
<span class="md-ellipsis">
Tagging &amp; naming keys
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#drm-cdm" class="md-nav__link">
<span class="md-ellipsis">
DRM &amp; CDM
</span>
</a>
<nav class="md-nav" aria-label="DRM &amp; CDM">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#cdm" class="md-nav__link">
<span class="md-ellipsis">
cdm
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#remote_cdm" class="md-nav__link">
<span class="md-ellipsis">
remote_cdm
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#decryption" class="md-nav__link">
<span class="md-ellipsis">
decryption
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#network-proxy" class="md-nav__link">
<span class="md-ellipsis">
Network &amp; proxy
</span>
</a>
<nav class="md-nav" aria-label="Network &amp; proxy">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#network" class="md-nav__link">
<span class="md-ellipsis">
network
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#headers" class="md-nav__link">
<span class="md-ellipsis">
headers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#proxy_providers" class="md-nav__link">
<span class="md-ellipsis">
proxy_providers
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#key-vaults" class="md-nav__link">
<span class="md-ellipsis">
Key vaults
</span>
</a>
<nav class="md-nav" aria-label="Key vaults">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#key_vaults" class="md-nav__link">
<span class="md-ellipsis">
key_vaults
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#vault_timeout" class="md-nav__link">
<span class="md-ellipsis">
vault_timeout
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#external-api-keys" class="md-nav__link">
<span class="md-ellipsis">
External API keys
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#caching-updates" class="md-nav__link">
<span class="md-ellipsis">
Caching &amp; updates
</span>
</a>
<nav class="md-nav" aria-label="Caching &amp; updates">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#title-cache" class="md-nav__link">
<span class="md-ellipsis">
Title cache
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#update-checks" class="md-nav__link">
<span class="md-ellipsis">
Update checks
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#logging-privacy-debug" class="md-nav__link">
<span class="md-ellipsis">
Logging, privacy &amp; debug
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#deprecated-removed-keys" class="md-nav__link">
<span class="md-ellipsis">
Deprecated &amp; removed keys
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#a-complete-annotated-example" class="md-nav__link">
<span class="md-ellipsis">
A complete annotated example
</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="configuration-reference">Configuration Reference<a class="headerlink" href="#configuration-reference" title="Permanent link">&para;</a></h1>
<p>This page is the exhaustive, authoritative reference for <strong>every</strong> key you can set in
<code>unshackle.yaml</code>. For each key you will find its name, expected type, default value, and
what it does. Keys are grouped by area so you can jump straight to the part of unshackle
you are configuring.</p>
<p>If you are new to the config file (where it lives, how unshackle discovers it, and how to
edit it), start with <a href="../../getting-started/configuration-file/">The Configuration File</a>.
This page assumes you already know the basics and want precise details.</p>
<div class="admonition info">
<p class="admonition-title">How defaults work</p>
<p>Every key is optional. If you omit a key, unshackle uses the built-in default listed
here. There is <strong>no schema validation</strong>: unknown keys are silently ignored (they never
become settings), and the file is parsed with <code>yaml.safe_load</code>. An empty or missing
file means <em>all</em> defaults apply.</p>
</div>
<div class="admonition warning">
<p class="admonition-title">Two keys behave specially on load</p>
<ul>
<li><code>curl_impersonate</code> is a <strong>deprecated</strong> alias of <a href="#network-proxy"><code>network</code></a> and emits a
<code>DeprecationWarning</code>.</li>
<li><code>scene_naming</code> has been <strong>removed</strong>. If it is present at all, unshackle exits
immediately with an error telling you to use <a href="#output-naming"><code>output_template</code></a>
instead.</li>
</ul>
<p>See <a href="#deprecated-removed-keys">Deprecated &amp; removed keys</a> at the end of this page.</p>
</div>
<hr />
<h2 id="quick-index">Quick index<a class="headerlink" href="#quick-index" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Area</th>
<th>Keys</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#directories">Directories</a></td>
<td><code>directories</code>, <code>filenames</code></td>
</tr>
<tr>
<td><a href="#services-auth">Services &amp; authentication</a></td>
<td><code>services</code>, <code>credentials</code>, <code>firefox_cookies</code>, <code>remote_services</code>, <code>serve</code></td>
</tr>
<tr>
<td><a href="#download-processing">Download &amp; processing</a></td>
<td><code>dl</code>, <code>subtitle</code>, <code>audio</code>, <code>muxing</code>, <code>language_tags</code></td>
</tr>
<tr>
<td><a href="#output-naming">Output &amp; naming</a></td>
<td><code>output_template</code>, <code>tag</code>, <code>tag_group_name</code>, <code>tag_imdb_tmdb</code>, <code>chapter_fallback_name</code>, <code>unicode_filenames</code></td>
</tr>
<tr>
<td><a href="#drm-cdm">DRM &amp; CDM</a></td>
<td><code>cdm</code>, <code>remote_cdm</code>, <code>decryption</code></td>
</tr>
<tr>
<td><a href="#network-proxy">Network &amp; proxy</a></td>
<td><code>network</code>, <code>headers</code>, <code>proxy_providers</code></td>
</tr>
<tr>
<td><a href="#key-vaults">Key vaults</a></td>
<td><code>key_vaults</code>, <code>vault_timeout</code></td>
</tr>
<tr>
<td><a href="#external-api-keys">External API keys</a></td>
<td><code>imdb_api_enabled</code>, <code>tmdb_api_key</code>, <code>simkl_client_id</code>, <code>decrypt_labs_api_key</code>, <code>ipinfo_api_key</code></td>
</tr>
<tr>
<td><a href="#caching-updates">Caching &amp; updates</a></td>
<td><code>title_cache_enabled</code>, <code>title_cache_time</code>, <code>title_cache_max_retention</code>, <code>update_checks</code>, <code>update_check_interval</code></td>
</tr>
<tr>
<td><a href="#logging-privacy-debug">Logging, privacy &amp; debug</a></td>
<td><code>redact_paths</code>, <code>debug</code>, <code>debug_keys</code>, <code>debug_requests</code>, <code>set_terminal_bg</code></td>
</tr>
<tr>
<td><a href="#deprecated-removed-keys">Deprecated &amp; removed</a></td>
<td><code>curl_impersonate</code>, <code>downloader</code>, <code>scene_naming</code></td>
</tr>
</tbody>
</table>
<hr />
<h2 id="directories">Directories<a class="headerlink" href="#directories" title="Permanent link">&para;</a></h2>
<p>The <code>directories</code> key is a <strong>dict</strong> mapping directory names to filesystem paths. Only the
names listed below are honoured; a handful are <strong>protected</strong> and cannot be moved (attempts
to override them are silently skipped). All defaults are computed relative to the installed
package, and every user-settable path is passed through <code>Path(...).expanduser()</code>, so <code>~</code>
works.</p>
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nt">directories</span><span class="p">:</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="w"> </span><span class="nt">downloads</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/Media/unshackle</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="w"> </span><span class="nt">temp</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/mnt/fast-scratch/unshackle-temp</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="w"> </span><span class="nt">wvds</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/.unshackle/WVDs</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a><span class="w"> </span><span class="nt">prds</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/.unshackle/PRDs</span>
</span></code></pre></div>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th style="text-align: center;">Overridable</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>downloads</code></td>
<td>path</td>
<td><code>&lt;repo&gt;/downloads</code></td>
<td style="text-align: center;">✅</td>
<td>Default output directory for finished files.</td>
</tr>
<tr>
<td><code>temp</code></td>
<td>path</td>
<td><code>&lt;repo&gt;/temp</code></td>
<td style="text-align: center;">✅</td>
<td>Temporary working files during download/decrypt/mux.</td>
</tr>
<tr>
<td><code>cache</code></td>
<td>path</td>
<td><code>&lt;data&gt;/cache</code></td>
<td style="text-align: center;">✅</td>
<td>Generic cache, title cache, and the update-check store.</td>
</tr>
<tr>
<td><code>cookies</code></td>
<td>path</td>
<td><code>&lt;data&gt;/cookies</code></td>
<td style="text-align: center;">✅</td>
<td>Per-service cookie files (and VPN cookie/token files).</td>
</tr>
<tr>
<td><code>logs</code></td>
<td>path</td>
<td><code>&lt;data&gt;/logs</code></td>
<td style="text-align: center;">✅</td>
<td>Log files.</td>
</tr>
<tr>
<td><code>exports</code></td>
<td>path</td>
<td><code>&lt;data&gt;/exports</code></td>
<td style="text-align: center;">✅</td>
<td>Export JSON files.</td>
</tr>
<tr>
<td><code>wvds</code></td>
<td>path</td>
<td><code>&lt;data&gt;/WVDs</code></td>
<td style="text-align: center;">✅</td>
<td>Widevine device files (<code>.wvd</code>).</td>
</tr>
<tr>
<td><code>prds</code></td>
<td>path</td>
<td><code>&lt;data&gt;/PRDs</code></td>
<td style="text-align: center;">✅</td>
<td>PlayReady device files (<code>.prd</code>).</td>
</tr>
<tr>
<td><code>dcsl</code></td>
<td>path</td>
<td><code>&lt;data&gt;/DCSL</code></td>
<td style="text-align: center;">✅</td>
<td>DCSL data.</td>
</tr>
<tr>
<td><code>commands</code></td>
<td>path</td>
<td><code>unshackle/commands</code></td>
<td style="text-align: center;">✅</td>
<td>CLI command modules.</td>
</tr>
<tr>
<td><code>services</code></td>
<td>list | path</td>
<td><code>[unshackle/services]</code></td>
<td style="text-align: center;">✅</td>
<td>Service search paths and/or remote repo specs (see below).</td>
</tr>
<tr>
<td><code>vaults</code></td>
<td>path</td>
<td><code>unshackle/vaults</code></td>
<td style="text-align: center;">✅</td>
<td>Vault backend modules.</td>
</tr>
<tr>
<td><code>fonts</code></td>
<td>path</td>
<td><code>unshackle/fonts</code></td>
<td style="text-align: center;">✅</td>
<td>Bundled fonts.</td>
</tr>
<tr>
<td><code>user_configs</code></td>
<td>path</td>
<td><code>unshackle/</code></td>
<td style="text-align: center;">❌ protected</td>
<td>Where <code>unshackle.yaml</code> lives.</td>
</tr>
<tr>
<td><code>data</code></td>
<td>path</td>
<td><code>unshackle/</code></td>
<td style="text-align: center;">❌ protected</td>
<td>Base for the data subdirectories above.</td>
</tr>
<tr>
<td><code>core_dir</code></td>
<td>path</td>
<td><code>unshackle/core</code></td>
<td style="text-align: center;">❌ protected</td>
<td>Package core.</td>
</tr>
<tr>
<td><code>namespace_dir</code></td>
<td>path</td>
<td><code>unshackle/</code></td>
<td style="text-align: center;">❌ protected</td>
<td>Package root.</td>
</tr>
<tr>
<td><code>app_dirs</code></td>
<td>-</td>
<td><code>AppDirs("unshackle", False)</code></td>
<td style="text-align: center;">❌ protected</td>
<td>Internal AppDirs instance.</td>
</tr>
</tbody>
</table>
<div class="admonition note">
<p class="admonition-title">The <code>services</code> directory is special</p>
<p><code>services</code> may be a <strong>list</strong>, and each entry can be either a local directory or a
<strong>repository spec</strong>: a git URL (<code>https://...</code>, <code>ssh://...</code>, <code>git@...</code>, or anything ending in
<code>.git</code>) or <code>owner/repo</code> shorthand. Repo specs are cloned and updated automatically; plain
paths are used as-is. <strong>List order is priority</strong>: the first source to define a service
tag wins, so put your own local service directories <strong>last</strong> to make them fallbacks.</p>
<div class="language-yaml 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="nt">directories</span><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">services</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="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">unshackle-dl/community-services</span><span class="w"> </span><span class="c1"># cloned from GitHub</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="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://example.com/private.git@stable</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="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/my-services</span><span class="w"> </span><span class="c1"># local, lowest priority</span>
</span></code></pre></div>
</div>
<div class="admonition info">
<p class="admonition-title">How git-backed service repos are handled</p>
<p>unshackle's use of git is <strong>read-only on the remote</strong>: it only ever performs a shallow
<code>clone</code>, <code>fetch</code>, <code>pull</code>, and a local <code>reset</code>; <strong>nothing is ever pushed</strong>. Private repos
are authenticated through your existing git credential helper, and unshackle stores no
tokens of its own. Clones live under <code>&lt;first-local-services-dir&gt;/_repos/&lt;repo-name&gt;/</code> (or
the bundled <code>unshackle/services</code>), and <strong>nothing is written to the cache directory</strong>. After
the first clone unshackle re-pulls <strong>at most once every 24 h</strong>, so it does not touch the
network on every run.</p>
</div>
<div class="admonition warning">
<p class="admonition-title">The two refresh paths diverge on purpose</p>
<p>The <strong>automatic</strong> 24 h-TTL refresh that happens during a normal <code>dl</code>/<code>search</code> run will
deliberately <strong>refuse to refresh and exit</strong> (naming the offending clone) if that clone
has uncommitted changes to tracked files or unpushed local commits, so a background pull can
never clobber work in progress. Untracked files (new service folders, <code>__pycache__</code>) never
block it. The <strong>manual</strong> <code>unshackle util refresh-services</code> command does the opposite: it
<strong>hard-resets</strong> the clone to upstream, discarding any local edits. Reach for the manual
command only when you actually want to throw local changes away.</p>
</div>
<div class="admonition warning">
<p class="admonition-title">Read-only installs and reinstalls</p>
<p>If the services directory lives inside the installed package, a reinstall can delete the
<code>_repos</code> clones. They are simply re-cloned on next use. On <strong>read-only installs</strong> you must
point <code>services</code> at a writable path, or cloning will fail.</p>
</div>
<h3 id="filenames">Filenames<a class="headerlink" href="#filenames" title="Permanent link">&para;</a></h3>
<p>The <code>filenames</code> key is a <strong>dict</strong> of templated file/name patterns. Each value is used
verbatim (no path processing). Braced fields like <code>{time}</code> and <code>{service}</code> are filled in at
runtime.</p>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>log</code></td>
<td>str</td>
<td><code>"unshackle_{name}_{time}.log"</code></td>
<td>Written under <code>directories.logs</code>.</td>
</tr>
<tr>
<td><code>debug_log</code></td>
<td>str</td>
<td><code>"unshackle_debug_{service}_{time}.jsonl"</code></td>
<td>Structured debug log, under <code>directories.logs</code>.</td>
</tr>
<tr>
<td><code>config</code></td>
<td>str</td>
<td><code>"config.yaml"</code></td>
<td>Per-service config file, under that service's directory.</td>
</tr>
<tr>
<td><code>root_config</code></td>
<td>str</td>
<td><code>"unshackle.yaml"</code></td>
<td>The main config filename itself.</td>
</tr>
<tr>
<td><code>chapters</code></td>
<td>str</td>
<td><code>"Chapters_{title}_{random}.txt"</code></td>
<td>Under <code>directories.temp</code>.</td>
</tr>
<tr>
<td><code>subtitle</code></td>
<td>str</td>
<td><code>"Subtitle_{id}_{language}.srt"</code></td>
<td>Under <code>directories.temp</code>.</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="services-auth">Services &amp; authentication<a class="headerlink" href="#services-auth" title="Permanent link">&para;</a></h2>
<h3 id="services"><code>services</code><a class="headerlink" href="#services" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> keyed by service tag &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Per-service configuration, keyed by the canonical service tag (for example <code>EXAMPLE1</code>, <code>EXAMPLE2</code>,
<code>EXAMPLE3</code>). unshackle reads several well-known sub-keys out of each service's block:</p>
<ul>
<li><strong><code>proxy_map</code></strong>: a dict mapping <code>"provider:query"</code> or <code>"query"</code> to a proxy value, used to
auto-select a proxy for that service.</li>
<li><strong><code>title_map</code></strong>: an exact-match rename map applied to fetched titles (source name →
desired name), so a service that names a title differently from your library still matches.</li>
</ul>
<p>Individual services may read any additional keys they define. The whole block is handed to
the service as <code>self.config</code>.</p>
<div class="admonition tip">
<p class="admonition-title">Why put secrets here and not in the service's own <code>config.yaml</code>?</p>
<p>A service ships a per-service <code>config.yaml</code> inside its own folder, and that file is
typically shared/committed and <strong>not</strong> meant to be edited by you. So anything user- or
device-specific (API keys, account IDs, device attributes) belongs in this <code>services</code>
block of <code>unshackle.yaml</code> instead, where it is <strong>merged over</strong> the service's <code>config.yaml</code>
at load time. That is why the two config locations exist: one for shared service defaults,
one for your private overrides.</p>
</div>
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="nt">services</span><span class="p">:</span>
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="w"> </span><span class="nt">EXAMPLE1</span><span class="p">:</span>
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="w"> </span><span class="nt">proxy_map</span><span class="p">:</span>
</span><span id="__span-2-4"><a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="w"> </span><span class="nt">default</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">us</span>
</span><span id="__span-2-5"><a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a><span class="w"> </span><span class="nt">title_map</span><span class="p">:</span>
</span><span id="__span-2-6"><a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a><span class="w"> </span><span class="s">&quot;My</span><span class="nv"> </span><span class="s">Show:</span><span class="nv"> </span><span class="s">The</span><span class="nv"> </span><span class="s">Movie&quot;</span><span class="p p-Indicator">:</span><span class="w"> </span><span class="s">&quot;My</span><span class="nv"> </span><span class="s">Show</span><span class="nv"> </span><span class="s">Presents</span><span class="nv"> </span><span class="s">The</span><span class="nv"> </span><span class="s">Movie&quot;</span>
</span></code></pre></div>
<h3 id="credentials"><code>credentials</code><a class="headerlink" href="#credentials" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> keyed by service tag &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Per-service login credentials. Each value is a <code>username:password[:extra]</code> string (a list or
dict form is also accepted where a service supports it). These are parsed into <code>Credential</code>
objects; the credential's SHA-1 is also used as an account hash for cache keys.</p>
<div class="language-yaml 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="nt">credentials</span><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">EXAMPLE2</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">user@example.com:hunter2</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="nt">EXAMPLE1</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="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">primary@example.com:pw1</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="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">secondary@example.com:pw2</span>
</span></code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Cookies vs credentials</p>
<p>Cookies are stored as files under <a href="#directories"><code>directories.cookies</code></a>, not in this key.
A service's <code>authenticate()</code> accepts cookies, credentials, or both.</p>
</div>
<h3 id="firefox_cookies"><code>firefox_cookies</code><a class="headerlink" href="#firefox_cookies" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Settings for extracting cookies directly from a local Firefox profile. A service block is
expected to provide <code>hosts</code> (a list of cookie hostnames; entries shorter than 3 characters
are ignored to prevent dumping the whole cookie store) and an optional <code>local_storage</code>
boolean to also pull matching local-storage entries. Extraction is read-only.</p>
<div class="admonition note">
<p class="admonition-title">Firefox does not need to be closed</p>
<p>The extractor copies <strong>both</strong> <code>cookies.sqlite</code> <strong>and</strong> its WAL file into a <code>0700</code> temp
directory; the WAL copy exists to capture writes Firefox has not yet flushed to the main
DB, so the copy is current even against a running browser. The only real constraint is that
Firefox must not hold an exclusive write lock at the exact instant of the copy. The live
profile is otherwise left untouched.</p>
</div>
<div class="admonition tip">
<p class="admonition-title">When you actually need <code>local_storage: true</code></p>
<p>Enable it only for services that keep their auth tokens in the browser's <strong>localStorage</strong>
(<code>webappsstore.sqlite</code>) rather than in HTTP cookies. If a service authenticates with plain
cookies, leaving it off is correct.</p>
</div>
<div class="admonition warning">
<p class="admonition-title">Extraction fails silently to file cookies</p>
<p>If extraction yields no cookies or fails for <strong>any</strong> reason, unshackle silently falls back
to the normal file-based cookie path (<code>cookies/&lt;SERVICE&gt;.txt</code> or
<code>cookies/&lt;SERVICE&gt;/&lt;profile&gt;.txt</code>). This is a safety net, but it also means that if you
expected Firefox cookies and file cookies are being used instead, extraction quietly failed.
Check that first when troubleshooting.</p>
</div>
<h3 id="remote_services"><code>remote_services</code><a class="headerlink" href="#remote_services" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Definitions of remote unshackle service servers, used by the <code>--remote</code> mode. Each entry
carries a <code>services</code> sub-dict of remote service tags, which unshackle turns into synthetic
CLI commands that run against the remote server.</p>
<h3 id="serve"><code>serve</code><a class="headerlink" href="#serve" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Configuration for the <code>serve</code> command (the built-in REST API server). The full server guide
is the <a href="../../dev/rest-api/">REST API</a> section; these are the config keys.</p>
<table>
<thead>
<tr>
<th>Sub-key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>api_secret</code></td>
<td>str</td>
<td><em>(unset)</em></td>
<td>Master secret accepted in the <code>X-Secret-Key</code> header.</td>
</tr>
<tr>
<td><code>users</code></td>
<td>dict</td>
<td><code>{}</code></td>
<td>Per-user API keys and their allowlists (see below).</td>
</tr>
<tr>
<td><code>services</code></td>
<td>list</td>
<td><em>(unset)</em></td>
<td>Global service allowlist. Omit to allow all.</td>
</tr>
<tr>
<td><code>remote_only</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Run without a local <code>output_template</code> (CORS/Cloudflare-friendly).</td>
</tr>
<tr>
<td><code>session_ttl</code></td>
<td>int (s)</td>
<td><code>300</code></td>
<td>Lifetime of an interactive auth session.</td>
</tr>
<tr>
<td><code>max_sessions</code></td>
<td>int</td>
<td><code>100</code></td>
<td>Maximum concurrent sessions.</td>
</tr>
<tr>
<td><code>history_limit</code></td>
<td>int</td>
<td><code>100</code></td>
<td>How many finished jobs to retain in history.</td>
</tr>
<tr>
<td><code>compression_level</code></td>
<td>int</td>
<td><code>1</code></td>
<td>gzip level for responses.</td>
</tr>
<tr>
<td><code>cdm_overrides</code></td>
<td>dict</td>
<td><em>(unset)</em></td>
<td>Allowed per-request CDM overrides.</td>
</tr>
<tr>
<td><code>allow_job_credentials</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Permit clients to supply credentials per job.</td>
</tr>
<tr>
<td><code>devices</code></td>
<td>list</td>
<td><em>(auto)</em></td>
<td>Widevine devices offered; auto-filled from <code>directories.wvds</code>.</td>
</tr>
<tr>
<td><code>playready_devices</code></td>
<td>list</td>
<td><em>(auto)</em></td>
<td>PlayReady devices; auto-filled from <code>directories.prds</code>.</td>
</tr>
<tr>
<td><code>country</code> / <code>locations</code></td>
<td>str / dict</td>
<td><em>(unset)</em></td>
<td>Advertised region metadata.</td>
</tr>
</tbody>
</table>
<p>Each entry under <code>users</code> is keyed by that user's API key and may set its own <code>services</code>,
<code>devices</code>, and <code>playready_devices</code> allowlists, narrowing the global ones.</p>
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="nt">serve</span><span class="p">:</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><span class="nt">api_secret</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">change-me</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><span class="nt">remote_only</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</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><span class="nt">services</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">EXAMPLE1</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">EXAMPLE2</span><span class="p p-Indicator">]</span>
</span><span id="__span-4-5"><a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="w"> </span><span class="c1"># server-wide download defaults (same keys as the `dl:` block)</span>
</span><span id="__span-4-6"><a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a><span class="w"> </span><span class="nt">downloads</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3</span>
</span><span id="__span-4-7"><a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a><span class="w"> </span><span class="nt">best_available</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
</span><span id="__span-4-8"><a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a><span class="w"> </span><span class="nt">users</span><span class="p">:</span>
</span><span id="__span-4-9"><a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="w"> </span><span class="nt">a1b2c3d4</span><span class="p">:</span><span class="w"> </span><span class="c1"># this user&#39;s API key</span>
</span><span id="__span-4-10"><a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a><span class="w"> </span><span class="nt">services</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">EXAMPLE1</span><span class="p p-Indicator">]</span><span class="w"> </span><span class="c1"># may only use EXAMPLE1</span>
</span></code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Declaring <code>dl</code> defaults under <code>serve</code></p>
<p>You can set any <a href="#dl"><code>dl</code></a> flag key (<code>downloads</code>, <code>workers</code>, <code>best_available</code>, and so on)
directly inside <code>serve</code>. The point is to raise concurrency and behaviour defaults
<strong>server-wide</strong> (every request the server handles picks them up) without having to change
each client call individually.</p>
</div>
<hr />
<h2 id="download-processing">Download &amp; processing<a class="headerlink" href="#download-processing" title="Permanent link">&para;</a></h2>
<h3 id="dl"><code>dl</code><a class="headerlink" href="#dl" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Persistent defaults for the <code>dl</code> command. This block is used as Click's <code>default_map</code>, so
<strong>any</strong> <code>dl</code> flag can be given a default here and it applies to every download without you
typing it. See <a href="../../guide/downloading/">Downloading</a> and the
<a href="../../guide/cli-reference/">CLI Reference</a> for what each flag does.</p>
<p><strong>Key naming.</strong> A key is the flag's long name with dashes replaced by underscores
(<code>--best-available</code> → <code>best_available</code>, <code>--sub-format</code> → <code>sub_format</code>). A few keys are named
after the flag's internal destination rather than its visible name; set these exact keys:</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Config key</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>-r</code> / <code>--range</code></td>
<td><code>range</code></td>
</tr>
<tr>
<td><code>--list</code></td>
<td><code>list</code></td>
</tr>
<tr>
<td><code>--tmdb</code></td>
<td><code>tmdb_id</code></td>
</tr>
<tr>
<td><code>--imdb</code></td>
<td><code>imdb_id</code></td>
</tr>
<tr>
<td><code>--animeapi</code></td>
<td><code>animeapi_id</code></td>
</tr>
<tr>
<td><code>-naa</code> / <code>--noatmos</code></td>
<td><code>no_atmos</code></td>
</tr>
<tr>
<td><code>-o</code> / <code>--output</code></td>
<td><code>output_dir</code></td>
</tr>
<tr>
<td><code>--cdm-only</code> / <code>--vaults-only</code></td>
<td><code>cdm_only</code></td>
</tr>
</tbody>
</table>
<p><strong>Precedence</strong> (highest first): an explicit CLI flag or environment variable → a per-service
<a href="#services-auth"><code>services.&lt;TAG&gt;.dl</code></a> override → this global <code>dl:</code> block → the built-in
default. In other words, config only fills in options you did not set on the command line.</p>
<p>Common keys (a useful subset; every <code>dl</code> flag works):</p>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Sets</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>lang</code></td>
<td>list</td>
<td><code>["orig"]</code></td>
<td>Video/audio language(s); <code>orig</code> = original language.</td>
</tr>
<tr>
<td><code>a_lang</code> / <code>v_lang</code></td>
<td>list</td>
<td><code>[]</code></td>
<td>Audio- / video-only language override.</td>
</tr>
<tr>
<td><code>s_lang</code></td>
<td>list</td>
<td><code>["all"]</code></td>
<td>Subtitle language(s).</td>
</tr>
<tr>
<td><code>quality</code></td>
<td>list</td>
<td><code>[]</code> (best)</td>
<td>Resolution(s), e.g. <code>[1080]</code>.</td>
</tr>
<tr>
<td><code>vcodec</code></td>
<td>list</td>
<td><code>[]</code> (any)</td>
<td>Video codec(s), e.g. <code>[H265]</code>.</td>
</tr>
<tr>
<td><code>acodec</code></td>
<td>list</td>
<td><code>[]</code> (any)</td>
<td>Audio codec(s), e.g. <code>[EC3]</code>.</td>
</tr>
<tr>
<td><code>range</code></td>
<td>list</td>
<td><code>["SDR"]</code></td>
<td>Colour range(s): <code>SDR</code>, <code>HDR10</code>, <code>HDR10+</code>, <code>DV</code>.</td>
</tr>
<tr>
<td><code>channels</code></td>
<td>float</td>
<td><em>(unset)</em></td>
<td>Audio channels, e.g. <code>6</code> for 5.1.</td>
</tr>
<tr>
<td><code>sub_format</code></td>
<td>str</td>
<td><em>(unset)</em></td>
<td>Convert subtitles to this format (<code>srt</code>, <code>vtt</code>, <code>original</code>, ...).</td>
</tr>
<tr>
<td><code>forced_subs</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Include forced subtitle tracks.</td>
</tr>
<tr>
<td><code>no_subs</code> / <code>no_audio</code> / <code>no_chapters</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Skip that track type.</td>
</tr>
<tr>
<td><code>downloads</code></td>
<td>int</td>
<td><code>1</code></td>
<td>Tracks downloaded concurrently.</td>
</tr>
<tr>
<td><code>workers</code></td>
<td>int</td>
<td><em>(downloader default)</em></td>
<td>Threads per track.</td>
</tr>
<tr>
<td><code>slow</code></td>
<td>str</td>
<td><em>(unset)</em></td>
<td>Inter-title delay, e.g. <code>"20-40"</code>.</td>
</tr>
<tr>
<td><code>best_available</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Fall back to best quality if the request is unavailable.</td>
</tr>
<tr>
<td><code>proxy</code></td>
<td>str</td>
<td><em>(unset)</em></td>
<td>Default proxy URI or 2-letter country.</td>
</tr>
<tr>
<td><code>no_folder</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Do not create a per-title folder.</td>
</tr>
</tbody>
</table>
<div class="language-yaml highlight"><span class="filename">Global download defaults</span><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="nt">dl</span><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">lang</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">]</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="nt">quality</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">1080</span><span class="p p-Indicator">]</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">range</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">HDR10</span><span class="p p-Indicator">]</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">vcodec</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">H265</span><span class="p p-Indicator">]</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">sub_format</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">srt</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">downloads</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">2</span>
</span></code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Per-service overrides</p>
<p>Nest a <code>dl</code> block under a service in <a href="#services-auth"><code>services</code></a> to override these defaults
for just that service. It uses the same keys and wins over the global <code>dl:</code> block (but still
loses to an explicit CLI flag).</p>
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="nt">dl</span><span class="p">:</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><span class="nt">lang</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">]</span><span class="w"> </span><span class="c1"># global default</span>
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="nt">services</span><span class="p">:</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><span class="nt">EXAMPLE1</span><span class="p">:</span>
</span><span id="__span-6-5"><a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a><span class="w"> </span><span class="nt">dl</span><span class="p">:</span>
</span><span id="__span-6-6"><a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a><span class="w"> </span><span class="nt">lang</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">ja</span><span class="p p-Indicator">]</span><span class="w"> </span><span class="c1"># EXAMPLE1 downloads both; everything else stays English</span>
</span><span id="__span-6-7"><a id="__codelineno-6-7" name="__codelineno-6-7" href="#__codelineno-6-7"></a><span class="w"> </span><span class="nt">range</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">DV</span><span class="p p-Indicator">]</span>
</span></code></pre></div>
</div>
<div class="admonition note">
<p class="admonition-title"><code>serve</code> uses these same keys</p>
<p>The <a href="#serve"><code>serve</code></a> block accepts the same <code>dl</code> option keys at its top level to set
server-wide download defaults for every request it handles.</p>
</div>
<h3 id="subtitle"><code>subtitle</code><a class="headerlink" href="#subtitle" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Subtitle handling: SDH stripping, format conversion, and whether subtitles are muxed in or
written as sidecar files. See <a href="../../guide/subtitles/">Subtitles</a> for the full guide.</p>
<table>
<thead>
<tr>
<th>Sub-key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>strip_sdh</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Strip SDH/CC cues (hearing-impaired annotations) into a clean track.</td>
</tr>
<tr>
<td><code>sdh_method</code></td>
<td>str</td>
<td><code>"auto"</code></td>
<td>SDH-stripping backend to use.</td>
</tr>
<tr>
<td><code>preserve_formatting</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Keep styling/positioning when converting or stripping.</td>
</tr>
<tr>
<td><code>convert_before_strip</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Convert to the working format before stripping SDH.</td>
</tr>
<tr>
<td><code>conversion_method</code></td>
<td>str</td>
<td><code>"auto"</code></td>
<td>Subtitle conversion backend.</td>
</tr>
<tr>
<td><code>preferred_conversion_method</code></td>
<td>str</td>
<td><em>(unset)</em></td>
<td>Preferred converter when several are available.</td>
</tr>
<tr>
<td><code>output_mode</code></td>
<td>str</td>
<td><code>"mux"</code></td>
<td><code>mux</code> embeds subtitles in the MKV; <code>sidecar</code> writes separate files.</td>
</tr>
<tr>
<td><code>sidecar_format</code></td>
<td>str</td>
<td><code>"srt"</code></td>
<td>Format for sidecar files when <code>output_mode: sidecar</code>.</td>
</tr>
<tr>
<td><code>type_priority</code></td>
<td>list</td>
<td><em>(unset)</em></td>
<td>Ordered ranking of subtitle types (<code>forced</code>, <code>normal</code>, <code>sdh</code>; CC counts as SDH) that sorts the variants within each language. Types you leave out fall to the end.</td>
</tr>
</tbody>
</table>
<div class="language-yaml 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="nt">subtitle</span><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">strip_sdh</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</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="nt">output_mode</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">sidecar</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">sidecar_format</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">srt</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title"><code>type_priority</code> also picks the default subtitle</p>
<p><code>type_priority</code> sorts the tracks within each language, and at mux time the first track
in the default subtitle language gets the <code>default</code> flag. The built-in order is <code>forced</code>,
<code>normal</code>, <code>sdh</code>, which means a forced track becomes default whenever one exists. If you
want the full dialogue track as default instead, set:</p>
<div class="language-yaml 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="nt">subtitle</span><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">type_priority</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">normal</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">sdh</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">forced</span><span class="p p-Indicator">]</span>
</span></code></pre></div>
</div>
<h3 id="audio"><code>audio</code><a class="headerlink" href="#audio" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Audio handling options. The most notable sub-key is <strong><code>codec_priority</code></strong>, an ordered list of
audio codecs used to break ties in track selection.</p>
<div class="language-yaml 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="nt">audio</span><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">codec_priority</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 p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">EAC3</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="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">AC3</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title"><code>codec_priority</code> is a soft priority: nothing is dropped</p>
<p><code>codec_priority</code> only breaks ties <strong>among tracks that share the same bitrate and language</strong>.
Codecs not in the list keep their normal bitrate-based ordering and are simply placed after
all listed codecs, and none are ever removed. Two higher-level rules still override it: <strong>Atmos
tracks always take precedence over <code>codec_priority</code></strong>, and <strong>audio-description tracks are
always forced to the end</strong> regardless of it. When <code>codec_priority</code> is unset, tracks sort by
bitrate alone, with those same Atmos/descriptive rules still applied.</p>
</div>
<h3 id="muxing"><code>muxing</code><a class="headerlink" href="#muxing" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Matroska (MKV) muxing options.</p>
<table>
<thead>
<tr>
<th>Sub-key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>set_title</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Write a human-readable title into the MKV container.</td>
</tr>
<tr>
<td><code>default_language</code></td>
<td>dict</td>
<td><code>{}</code></td>
<td>Force which language is flagged <em>default</em> per track type, e.g. <code>{audio: en, subtitle: en}</code>.</td>
</tr>
<tr>
<td><code>merge_audio</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Merge all audio into one file. <code>--split-audio</code> on the CLI flips this off.</td>
</tr>
<tr>
<td><code>merge_video</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Merge all video tracks into one file. <code>--merge-video</code> on the CLI flips this on.</td>
</tr>
</tbody>
</table>
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="nt">muxing</span><span class="p">:</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><span class="nt">set_title</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</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><span class="nt">default_language</span><span class="p">:</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><span class="nt">audio</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">en</span>
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a><span class="w"> </span><span class="nt">subtitle</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">en</span>
</span></code></pre></div>
<h3 id="language_tags"><code>language_tags</code><a class="headerlink" href="#language_tags" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Language-tag remapping and the rule engine behind the <code>{lang_tag}</code> filename variable. When a
<code>rules</code> list is present, each rule is evaluated in order and the first match's <code>tag</code> is used.
A rule may test:</p>
<table>
<thead>
<tr>
<th>Condition</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>audio</code></td>
<td>Matches against the audio track languages.</td>
</tr>
<tr>
<td><code>subs_contain</code></td>
<td>At least one subtitle language matches.</td>
</tr>
<tr>
<td><code>subs_contain_all</code></td>
<td>Every listed language must be present (scalar or list).</td>
</tr>
</tbody>
</table>
<div class="language-yaml 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="nt">language_tags</span><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">rules</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="p p-Indicator">-</span><span class="w"> </span><span class="nt">audio</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">]</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">subs_contain_all</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">]</span>
</span><span id="__span-11-5"><a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a><span class="w"> </span><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="w"> </span><span class="c1"># native English release, no tag</span>
</span><span id="__span-11-6"><a id="__codelineno-11-6" name="__codelineno-11-6" href="#__codelineno-11-6"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">audio</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">ja</span><span class="p p-Indicator">]</span>
</span><span id="__span-11-7"><a id="__codelineno-11-7" name="__codelineno-11-7" href="#__codelineno-11-7"></a><span class="w"> </span><span class="nt">subs_contain</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">]</span>
</span><span id="__span-11-8"><a id="__codelineno-11-8" name="__codelineno-11-8" href="#__codelineno-11-8"></a><span class="w"> </span><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;SUBBED&quot;</span>
</span></code></pre></div>
<hr />
<h2 id="output-naming">Output &amp; naming<a class="headerlink" href="#output-naming" title="Permanent link">&para;</a></h2>
<p>For the full picture of how templates render, see
<a href="../../guide/output-and-naming/">Output &amp; naming</a>. The keys are summarised here.</p>
<h3 id="output_template"><code>output_template</code><a class="headerlink" href="#output_template" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Filename templates keyed by media kind, using <code>{variable}</code> placeholders. Recognised kinds are
<code>movies</code>, <code>series</code>, and <code>songs</code> (and <code>albums</code> for folder templates). A trailing <code>?</code> on a
variable (e.g. <code>{quality?}</code>) marks it optional: if empty, it and one adjacent separator are
dropped.</p>
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="nt">output_template</span><span class="p">:</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="nt">movies</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{title}.{year}.{quality?}.{source}-{tag}&quot;</span>
</span><span id="__span-12-3"><a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a><span class="w"> </span><span class="nt">series</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{title}.{season_episode}.{episode_name?}.{quality?}.{source}-{tag}&quot;</span>
</span><span id="__span-12-4"><a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a><span class="w"> </span><span class="nt">songs</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{track_number}.</span><span class="nv"> </span><span class="s">{title}&quot;</span>
</span><span id="__span-12-5"><a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a><span class="w"> </span><span class="nt">folder</span><span class="p">:</span><span class="w"> </span><span class="c1"># special nested key, see below</span>
</span><span id="__span-12-6"><a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a><span class="w"> </span><span class="nt">movies</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{title}</span><span class="nv"> </span><span class="s">({year})&quot;</span>
</span><span id="__span-12-7"><a id="__codelineno-12-7" name="__codelineno-12-7" href="#__codelineno-12-7"></a><span class="w"> </span><span class="nt">series</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{title}</span><span class="nv"> </span><span class="s">({year})&quot;</span>
</span></code></pre></div>
<p><strong>The nested <code>folder</code> sub-key</strong> controls output subfolders and is popped out of
<code>output_template</code>:</p>
<ul>
<li>A <strong>dict</strong> sets per-kind folder templates (kinds: <code>movies</code>, <code>series</code>, <code>songs</code>, <code>albums</code>).</li>
<li>A <strong>str</strong> sets a single folder template for everything.</li>
</ul>
<p>unshackle validates templates on load and emits warnings for unknown variables, non-string
values, filesystem-unsafe characters (<code>&lt; &gt; : " / \ | ? *</code>), empty templates, and unknown
folder-kind keys.</p>
<details class="example">
<summary>All valid template variables</summary>
<p><code>title</code>, <code>year</code>, <code>season</code>, <code>episode</code>, <code>season_episode</code>, <code>episode_name</code>, <code>date</code>,
<code>quality</code>, <code>resolution</code>, <code>source</code>, <code>tag</code>, <code>track_number</code>, <code>artist</code>, <code>album_artist</code>,
<code>album</code>, <code>disc</code>, <code>track_total</code>, <code>disc_total</code>, <code>release_type</code>, <code>genre</code>, <code>explicit</code>,
<code>isrc</code>, <code>upc</code>, <code>label</code>, <code>audio</code>, <code>audio_channels</code>, <code>audio_full</code>, <code>atmos</code>, <code>dual</code>,
<code>multi</code>, <code>video</code>, <code>hdr</code>, <code>hfr</code>, <code>edition</code>, <code>repack</code>, <code>lang_tag</code>.</p>
</details>
<h3 id="tagging-naming-keys">Tagging &amp; naming keys<a class="headerlink" href="#tagging-naming-keys" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>tag</code></td>
<td>str</td>
<td><code>""</code></td>
<td>Release-group tag appended to filenames and written into MKV tags.</td>
</tr>
<tr>
<td><code>tag_group_name</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Include the group name (<code>tag</code>) in the MKV <code>Group</code> tag.</td>
</tr>
<tr>
<td><code>tag_imdb_tmdb</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Write IMDb/TMDB/TVDB external-ID tags into the MKV (needs metadata providers).</td>
</tr>
<tr>
<td><code>chapter_fallback_name</code></td>
<td>str</td>
<td><code>""</code></td>
<td>Fallback chapter-name template, e.g. <code>"Chapter {i:02}"</code>.</td>
</tr>
<tr>
<td><code>unicode_filenames</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Allow Unicode in filenames; when <code>false</code>, names are ASCII-sanitised.</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="drm-cdm">DRM &amp; CDM<a class="headerlink" href="#drm-cdm" title="Permanent link">&para;</a></h2>
<p>The full conceptual guide lives at <a href="../../guide/drm-and-cdm/">DRM &amp; CDM</a>. These are the config
keys. Device files themselves live in <a href="#directories"><code>directories.wvds</code></a> (<code>.wvd</code>) and
<code>directories.prds</code> (<code>.prd</code>).</p>
<h3 id="cdm"><code>cdm</code><a class="headerlink" href="#cdm" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Maps a service tag to the CDM (Widevine/PlayReady device) to use, with a <code>default</code> fallback.
Resolution is case-insensitive: an explicit CLI override wins, then the per-service entry,
then <code>default</code>.</p>
<div class="language-yaml 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="nt">cdm</span><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">default</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">chromecdm_l3</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="nt">EXAMPLE2</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">android_l1</span>
</span></code></pre></div>
<p>A value may also be a <strong>nested dict</strong> for advanced selection by quality, DRM system, or
profile:</p>
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="nt">cdm</span><span class="p">:</span>
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="w"> </span><span class="nt">EXAMPLE1</span><span class="p">:</span>
</span><span id="__span-14-3"><a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="w"> </span><span class="s">&quot;&gt;=1080&quot;</span><span class="p p-Indicator">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">android_l1</span><span class="w"> </span><span class="c1"># by track height</span>
</span><span id="__span-14-4"><a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a><span class="w"> </span><span class="s">&quot;&lt;1080&quot;</span><span class="p p-Indicator">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">chromecdm_l3</span>
</span><span id="__span-14-5"><a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a><span class="w"> </span><span class="nt">widevine</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">android_l1</span><span class="w"> </span><span class="c1"># by DRM system</span>
</span><span id="__span-14-6"><a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a><span class="w"> </span><span class="nt">playready</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">sl3000</span>
</span><span id="__span-14-7"><a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a><span class="w"> </span><span class="nt">default</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">chromecdm_l3</span>
</span></code></pre></div>
<p>Quality keys support <code>1080</code>, <code>&gt;=1080</code>, <code>&gt;720</code>, <code>&lt;=576</code>, <code>&lt;480</code> style comparisons; DRM keys
are <code>widevine</code> / <code>playready</code>.</p>
<h3 id="remote_cdm"><code>remote_cdm</code><a class="headerlink" href="#remote_cdm" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>list[dict]</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>[]</code></li>
</ul>
<p>A list of remote CDM server definitions. Each entry is matched by its <code>name</code> (referenced from
<a href="#cdm"><code>cdm</code></a>), and its <code>type</code> selects the backend:</p>
<table>
<thead>
<tr>
<th><code>type</code></th>
<th>Backend</th>
<th>Key fields</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>decrypt_labs</code></td>
<td>Decrypt Labs KeyXtractor</td>
<td><code>host</code> (default <code>https://keyxtractor.decryptlabs.com</code>), <code>device_name</code>, <code>secret</code> (falls back to <code>decrypt_labs_api_key</code>)</td>
</tr>
<tr>
<td><code>custom_api</code></td>
<td>Fully YAML-configurable remote API</td>
<td><code>device</code>, <code>auth</code>, <code>endpoints</code>, <code>request_mapping</code>, <code>response_mapping</code>, <code>caching</code>, <code>timeout</code></td>
</tr>
<tr>
<td><em>(none)</em>, <code>Device Type: PLAYREADY</code></td>
<td>pyplayready <code>RemoteCdm</code></td>
<td><code>host</code>, <code>secret</code>, <code>device_name</code>, <code>security_level</code> (default 3000)</td>
</tr>
<tr>
<td><em>(none)</em>, otherwise</td>
<td>pywidevine <code>RemoteCdm</code></td>
<td><code>host</code>, <code>secret</code>, <code>device_name</code>, <code>device_type</code>, <code>system_id</code>, <code>security_level</code> (default 3000)</td>
</tr>
</tbody>
</table>
<div class="language-yaml 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="nt">remote_cdm</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="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">keyxtractor</span>
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">decrypt_labs</span>
</span><span id="__span-15-4"><a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="w"> </span><span class="nt">device_name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">L1</span>
</span><span id="__span-15-5"><a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my_wv_server</span>
</span><span id="__span-15-6"><a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://cdm.example.com</span>
</span><span id="__span-15-7"><a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a><span class="w"> </span><span class="nt">secret</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">s3cr3t</span>
</span><span id="__span-15-8"><a id="__codelineno-15-8" name="__codelineno-15-8" href="#__codelineno-15-8"></a><span class="w"> </span><span class="nt">device_name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">android_l1</span>
</span><span id="__span-15-9"><a id="__codelineno-15-9" name="__codelineno-15-9" href="#__codelineno-15-9"></a><span class="w"> </span><span class="nt">device_type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">ANDROID</span>
</span><span id="__span-15-10"><a id="__codelineno-15-10" name="__codelineno-15-10" href="#__codelineno-15-10"></a><span class="w"> </span><span class="nt">system_id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">26830</span>
</span><span id="__span-15-11"><a id="__codelineno-15-11" name="__codelineno-15-11" href="#__codelineno-15-11"></a><span class="w"> </span><span class="nt">security_level</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">1</span>
</span></code></pre></div>
<h3 id="decryption"><code>decryption</code><a class="headerlink" href="#decryption" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>str</code> or <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>"shaka"</code></li>
</ul>
<p>Selects the tool used to physically decrypt CENC content. The value is compared
case-insensitively; <code>"mp4decrypt"</code> selects Bento4's mp4decrypt, and <strong>anything else</strong>
(including <code>"shaka"</code>) selects shaka-packager.</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">Global</label><label for="__tabbed_1_2">Per-service</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="nt">decryption</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">shaka</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="nt">decryption</span><span class="p">:</span>
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="w"> </span><span class="nt">default</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">shaka</span>
</span><span id="__span-17-3"><a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a><span class="w"> </span><span class="nt">SOMESERVICE</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">mp4decrypt</span>
</span></code></pre></div>
</div>
</div>
</div>
<hr />
<h2 id="network-proxy">Network &amp; proxy<a class="headerlink" href="#network-proxy" title="Permanent link">&para;</a></h2>
<h3 id="network"><code>network</code><a class="headerlink" href="#network" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>TLS-fingerprinting and HTTP client settings for the rnet-based session.</p>
<table>
<thead>
<tr>
<th>Sub-key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>browser</code></td>
<td>str</td>
<td><code>"Chrome131"</code></td>
<td>Impersonation preset. Must be an exact preset name (e.g. <code>Chrome131</code>, <code>Firefox135</code>, <code>Edge101</code>, <code>Safari18</code>, <code>OkHttp4_12</code>, <code>OkHttp5</code>, <code>Opera118</code>); unknown names raise an error.</td>
</tr>
<tr>
<td><code>http1_only</code></td>
<td>bool</td>
<td><em>(unset)</em></td>
<td>Force HTTP/1.1.</td>
</tr>
<tr>
<td><code>http2_only</code></td>
<td>bool</td>
<td><em>(unset)</em></td>
<td>Force HTTP/2.</td>
</tr>
<tr>
<td><code>pool_max_idle_per_host</code></td>
<td>int</td>
<td><em>(unset)</em></td>
<td>Connection-pool tuning.</td>
</tr>
<tr>
<td><code>pool_max_size</code></td>
<td>int</td>
<td><em>(unset)</em></td>
<td>Connection-pool tuning.</td>
</tr>
<tr>
<td><code>tcp_nodelay</code></td>
<td>bool</td>
<td><em>(unset)</em></td>
<td>Disable Nagle's algorithm.</td>
</tr>
</tbody>
</table>
<div class="language-yaml 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="nt">network</span><span class="p">:</span>
</span><span id="__span-18-2"><a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="w"> </span><span class="nt">browser</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Firefox135</span>
</span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="w"> </span><span class="nt">http2_only</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">When to force <code>http1_only</code></p>
<p>HTTP/2 is the right default on large CDNs, so leave it on. Force HTTP/1.1 only for a host that
throttles per-connection, or a slow origin stuck behind HTTP/2 flow control. In benchmarks
this won 30 to 50% on such hosts but <strong>cost up to 27% on fast CDNs</strong>, so enable it only when
your own measurements justify it.</p>
</div>
<div class="admonition warning">
<p class="admonition-title">Renamed from <code>curl_impersonate</code></p>
<p>The old <code>curl_impersonate</code> section is a deprecated alias. If you still use it, unshackle
honours it (only when <code>network</code> is absent) but emits a <code>DeprecationWarning</code>. Rename it to
<code>network</code>.</p>
</div>
<h3 id="headers"><code>headers</code><a class="headerlink" href="#headers" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Default HTTP headers merged into every session unshackle creates.</p>
<div class="language-yaml 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="nt">headers</span><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">Accept-Language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">en-US,en;q=0.9</span>
</span></code></pre></div>
<div class="admonition warning">
<p class="admonition-title">Don't set <code>Accept-Encoding</code> (and similar) here</p>
<p>Keep this block to sane cross-service defaults such as <code>Accept-Language</code> and <code>User-Agent</code>.
Compatibility headers like <code>Accept-Encoding</code> are set for you by the rnet HTTP backend as
part of its browser-impersonation profile, and overriding them can break the impersonation
fingerprint. Anything useful to only some services belongs in that service's config, not
here.</p>
</div>
<h3 id="proxy_providers"><code>proxy_providers</code><a class="headerlink" href="#proxy_providers" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>dict</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>{}</code></li>
</ul>
<p>Proxy/VPN provider configuration. Each sub-key names a provider, and its block is passed
straight to that provider's constructor. See <a href="../../guide/proxies-and-vpn/">Proxies &amp; VPN</a> for
the full provider guide. Recognised providers and their exit ports:</p>
<table>
<thead>
<tr>
<th>Provider</th>
<th>Config key</th>
<th>Credentials</th>
<th>Proxy scheme/port</th>
</tr>
</thead>
<tbody>
<tr>
<td>Basic (static)</td>
<td><code>basic</code></td>
<td>country → URI(s)</td>
<td>as specified</td>
</tr>
<tr>
<td>NordVPN</td>
<td><code>nordvpn</code></td>
<td>48-char <strong>service</strong> credentials</td>
<td><code>https://...:89</code></td>
</tr>
<tr>
<td>Surfshark</td>
<td><code>surfsharkvpn</code></td>
<td>48-char <strong>service</strong> credentials</td>
<td><code>https://...:443</code></td>
</tr>
<tr>
<td>Windscribe</td>
<td><code>windscribevpn</code></td>
<td>service credentials</td>
<td><code>https://...:443</code></td>
</tr>
<tr>
<td>ExpressVPN</td>
<td><code>expressvpn</code></td>
<td>device login (<code>enable: true</code>) / token cache</td>
<td><code>https://cat:...@...:443</code></td>
</tr>
<tr>
<td>ProtonVPN</td>
<td><code>protonvpn</code></td>
<td>TV login or exported cookies</td>
<td><code>https://...:4443</code> (or <code>:443</code> Secure Core)</td>
</tr>
<tr>
<td>Gluetun</td>
<td><code>gluetun</code></td>
<td>per-VPN keys/creds</td>
<td><code>http://localhost:{port}</code> (local Docker)</td>
</tr>
<tr>
<td>Hola</td>
<td><em>(none, auto)</em></td>
<td>none</td>
<td><code>http://...:{peer}</code></td>
</tr>
</tbody>
</table>
<div class="language-yaml 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="nt">proxy_providers</span><span class="p">:</span>
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a><span class="w"> </span><span class="nt">basic</span><span class="p">:</span>
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a><span class="w"> </span><span class="nt">us</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">http://user:pass@1.2.3.4:8080</span>
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="w"> </span><span class="nt">de</span><span class="p">:</span>
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">http://a.example:8080</span>
</span><span id="__span-20-6"><a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">socks5://b.example:1080</span>
</span><span id="__span-20-7"><a id="__codelineno-20-7" name="__codelineno-20-7" href="#__codelineno-20-7"></a><span class="w"> </span><span class="nt">nordvpn</span><span class="p">:</span>
</span><span id="__span-20-8"><a id="__codelineno-20-8" name="__codelineno-20-8" href="#__codelineno-20-8"></a><span class="w"> </span><span class="nt">username</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">&lt;48-char service username&gt;</span>
</span><span id="__span-20-9"><a id="__codelineno-20-9" name="__codelineno-20-9" href="#__codelineno-20-9"></a><span class="w"> </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">&lt;48-char service password&gt;</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Provider loading differs between CLI and REST server</p>
<p>The <code>dl</code> CLI loads all providers, including <code>windscribevpn</code> and <code>gluetun</code>. The REST API /
remote-client path uses a separate resolver that does <strong>not</strong> load <code>windscribevpn</code> or
<code>gluetun</code>. ExpressVPN and ProtonVPN also auto-load when their cached session exists, and Hola
auto-loads whenever the <code>hola-proxy</code> binary is present.</p>
</div>
<hr />
<h2 id="key-vaults">Key vaults<a class="headerlink" href="#key-vaults" title="Permanent link">&para;</a></h2>
<p>The full guide is at <a href="../../guide/vaults/">Vaults</a>. Two keys configure them.</p>
<h3 id="key_vaults"><code>key_vaults</code><a class="headerlink" href="#key_vaults" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>list[dict]</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>[]</code></li>
</ul>
<p>An ordered list of key-vault backends. unshackle queries them in order and reuses content
keys instead of re-licensing. Each entry needs a <code>type</code> (the backend module name) and a
<code>name</code>, plus backend-specific keys.</p>
<table>
<thead>
<tr>
<th><code>type</code></th>
<th>Purpose</th>
<th>Required keys</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>SQLite</code></td>
<td>Local SQLite database</td>
<td><code>name</code>, <code>path</code></td>
<td>Loaded <strong>critically</strong>; a failure aborts the run.</td>
</tr>
<tr>
<td><code>MySQL</code></td>
<td>Remote MySQL database</td>
<td><code>name</code>, <code>host</code>, <code>database</code>, <code>username</code></td>
<td>Extra keys (e.g. <code>password</code>, <code>port</code>) forwarded to pymysql.</td>
</tr>
<tr>
<td><code>API</code></td>
<td>RESTful JSON API</td>
<td><code>name</code>, <code>uri</code>, <code>token</code></td>
<td>Honours <code>vault_timeout</code>.</td>
</tr>
<tr>
<td><code>HTTP</code></td>
<td>HTTP API with modes</td>
<td><code>name</code>, <code>host</code>, one of <code>password</code>/<code>api_key</code></td>
<td><code>api_mode</code>: <code>query</code> (default), <code>json</code>, <code>decrypt_labs</code>.</td>
</tr>
</tbody>
</table>
<div class="language-yaml 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="nt">key_vaults</span><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="p p-Indicator">-</span><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">SQLite</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">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Local</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">path</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/.unshackle/keys.db</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 p-Indicator">-</span><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">MySQL</span>
</span><span id="__span-21-6"><a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Team</span>
</span><span id="__span-21-7"><a id="__codelineno-21-7" name="__codelineno-21-7" href="#__codelineno-21-7"></a><span class="w"> </span><span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">db.example.com</span>
</span><span id="__span-21-8"><a id="__codelineno-21-8" name="__codelineno-21-8" href="#__codelineno-21-8"></a><span class="w"> </span><span class="nt">database</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">keys</span>
</span><span id="__span-21-9"><a id="__codelineno-21-9" name="__codelineno-21-9" href="#__codelineno-21-9"></a><span class="w"> </span><span class="nt">username</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">unshackle</span>
</span><span id="__span-21-10"><a id="__codelineno-21-10" name="__codelineno-21-10" href="#__codelineno-21-10"></a><span class="w"> </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">hunter2</span>
</span><span id="__span-21-11"><a id="__codelineno-21-11" name="__codelineno-21-11" href="#__codelineno-21-11"></a><span class="w"> </span><span class="nt">no_push</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">false</span>
</span></code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Common per-entry options</p>
<ul>
<li><code>no_push: true</code> makes a vault read-only (keys are fetched but never written to it).</li>
<li>A vault of <code>type: api</code> whose <code>name</code> contains <code>decrypt_labs</code> auto-fills its <code>token</code> from
<a href="#external-api-keys"><code>decrypt_labs_api_key</code></a> when not set inline.</li>
<li>An all-zero content key (32 zeros) is treated as "no key" everywhere and is never
stored.</li>
</ul>
</div>
<h3 id="vault_timeout"><code>vault_timeout</code><a class="headerlink" href="#vault_timeout" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Type:</strong> <code>float</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>10.0</code></li>
</ul>
<p>Timeout in seconds for vault operations. Injected automatically into any backend whose
constructor accepts a <code>timeout</code> parameter (a per-vault <code>timeout</code> still wins).</p>
<hr />
<h2 id="external-api-keys">External API keys<a class="headerlink" href="#external-api-keys" title="Permanent link">&para;</a></h2>
<p>All default to an empty string and enable optional metadata/geolocation features.</p>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>imdb_api_enabled</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Use the free imdbapi.dev metadata provider, which needs no API key. Off by default since the site has been unreliable.</td>
</tr>
<tr>
<td><code>tmdb_api_key</code></td>
<td>str</td>
<td><code>""</code></td>
<td>TMDB API key for metadata enrichment and external-ID tags.</td>
</tr>
<tr>
<td><code>simkl_client_id</code></td>
<td>str</td>
<td><code>""</code></td>
<td>SIMKL client ID for metadata lookups; an alternative/fallback source to TMDB.</td>
</tr>
<tr>
<td><code>decrypt_labs_api_key</code></td>
<td>str</td>
<td><code>""</code></td>
<td>Global Decrypt Labs API key (used by remote CDM / vault).</td>
</tr>
<tr>
<td><code>ipinfo_api_key</code></td>
<td>str</td>
<td><code>""</code></td>
<td>ipinfo.io API key for IP/region lookups.</td>
</tr>
</tbody>
</table>
<div class="admonition tip">
<p class="admonition-title">SIMKL is a fallback for TMDB</p>
<p>SIMKL is positioned as an alternative metadata source, and it is most valuable precisely
<strong>when no <code>tmdb_api_key</code> is configured</strong>. It improves title-matching and tagging
reliability in that case rather than replacing TMDB where TMDB is available.</p>
</div>
<div class="admonition note">
<p class="admonition-title"><code>ipinfo_api_key</code> never touches your service sessions</p>
<p>The token is only ever sent to <code>api.ipinfo.io</code> as a per-request <code>Authorization</code> header; it
is <strong>never</strong> attached to your service session, so it cannot leak to a streaming provider.
Lookups degrade gracefully through a fallback chain: the authenticated Lite endpoint (higher
rate limits and richer fields) → anonymous ipinfo → <code>ip-api.in</code> as a last resort.</p>
</div>
<hr />
<h2 id="caching-updates">Caching &amp; updates<a class="headerlink" href="#caching-updates" title="Permanent link">&para;</a></h2>
<h3 id="title-cache">Title cache<a class="headerlink" href="#title-cache" title="Permanent link">&para;</a></h3>
<p>unshackle caches fetched title metadata (region- and account-aware) to avoid repeat API
calls.</p>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>title_cache_enabled</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Master switch for the title cache.</td>
</tr>
<tr>
<td><code>title_cache_time</code></td>
<td>int (seconds)</td>
<td><code>1800</code> (30 min)</td>
<td>Lifetime of fresh cached titles.</td>
</tr>
<tr>
<td><code>title_cache_max_retention</code></td>
<td>int (seconds)</td>
<td><code>86400</code> (24 h)</td>
<td>How long stale cached data may still be served as a fallback when a live fetch fails.</td>
</tr>
</tbody>
</table>
<h3 id="update-checks">Update checks<a class="headerlink" href="#update-checks" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>update_checks</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Whether to check for new unshackle releases.</td>
</tr>
<tr>
<td><code>update_check_interval</code></td>
<td>int (hours)</td>
<td><code>24</code></td>
<td>Minimum hours between update checks.</td>
</tr>
</tbody>
</table>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Update checks query the GitHub releases API with a fixed 5-second timeout and cache the
result in <code>directories.cache/update_check.json</code>.</p>
</div>
<hr />
<h2 id="logging-privacy-debug">Logging, privacy &amp; debug<a class="headerlink" href="#logging-privacy-debug" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>redact_paths</code></td>
<td>bool</td>
<td><code>true</code></td>
<td>Mask install-root / venv / home prefixes in logged paths (<code>&lt;unshackle&gt;</code>, <code>&lt;venv&gt;</code>, <code>~</code>). Set <code>false</code> to show full paths.</td>
</tr>
<tr>
<td><code>debug</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Global debug mode.</td>
</tr>
<tr>
<td><code>debug_keys</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Log decryption keys.</td>
</tr>
<tr>
<td><code>debug_requests</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Log HTTP requests.</td>
</tr>
<tr>
<td><code>set_terminal_bg</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>Append the theme's background colour to output styling.</td>
</tr>
</tbody>
</table>
<div class="admonition tip">
<p class="admonition-title">When to enable <code>set_terminal_bg</code></p>
<p>When on, the theme's background colour is appended to the foreground styles so the full
colour palette renders correctly on terminals whose <em>default</em> background differs from
unshackle's theme. Turn it on if the ASCII-art banner or coloured output <strong>looks off</strong> on
your terminal. Otherwise leave it off.</p>
</div>
<div class="admonition danger">
<p class="admonition-title">Key exposure</p>
<p>Decryption content keys are written to the structured debug log at INFO level during the
DRM handshake. Treat <code>debug</code>, <code>debug_keys</code>, and the <code>unshackle_debug_*.jsonl</code> files as
sensitive, and keep <code>redact_paths</code> enabled when sharing logs.</p>
<p><code>debug_keys</code> affects <strong>only</strong> content-encryption keys (the <code>content_key</code>/<code>key</code> fields).
Passwords, tokens, cookies, and session tokens are <strong>always</strong> redacted regardless of this
setting, and KIDs, key counts, and other metadata are always logged either way.</p>
</div>
<hr />
<h2 id="deprecated-removed-keys">Deprecated &amp; removed keys<a class="headerlink" href="#deprecated-removed-keys" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Key</th>
<th>Status</th>
<th>Behaviour</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>curl_impersonate</code></td>
<td><strong>Deprecated</strong> → use <a href="#network-proxy"><code>network</code></a></td>
<td>Emits a <code>DeprecationWarning</code>; still honoured only if <code>network</code> is absent.</td>
</tr>
<tr>
<td><code>downloader</code></td>
<td><strong>Deprecated</strong></td>
<td>Any value other than <code>"requests"</code> emits a <code>DeprecationWarning</code>; the value is otherwise ignored (the unified requests downloader is always used).</td>
</tr>
<tr>
<td><code>scene_naming</code></td>
<td><strong>Removed</strong></td>
<td>If present at all, unshackle exits with an error directing you to configure <a href="#output-naming"><code>output_template</code></a> instead.</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="a-complete-annotated-example">A complete annotated example<a class="headerlink" href="#a-complete-annotated-example" title="Permanent link">&para;</a></h2>
<p>The following config sets a handful of common keys. Every key not shown keeps its default.</p>
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><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="nt">directories</span><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">downloads</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/Media/unshackle</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">temp</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/mnt/scratch/unshackle</span>
</span><span id="__span-22-4"><a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a>
</span><span id="__span-22-5"><a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a><span class="nt">network</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">browser</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Chrome131</span>
</span><span id="__span-22-7"><a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a>
</span><span id="__span-22-8"><a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-8"></a><span class="nt">headers</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">Accept-Language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">en-US,en;q=0.9</span>
</span><span id="__span-22-10"><a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-10"></a>
</span><span id="__span-22-11"><a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a><span class="nt">cdm</span><span class="p">:</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="nt">default</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">chromecdm_l3</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">EXAMPLE2</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">android_l1</span>
</span><span id="__span-22-14"><a id="__codelineno-22-14" name="__codelineno-22-14" href="#__codelineno-22-14"></a>
</span><span id="__span-22-15"><a id="__codelineno-22-15" name="__codelineno-22-15" href="#__codelineno-22-15"></a><span class="nt">decryption</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">shaka</span>
</span><span id="__span-22-16"><a id="__codelineno-22-16" name="__codelineno-22-16" href="#__codelineno-22-16"></a>
</span><span id="__span-22-17"><a id="__codelineno-22-17" name="__codelineno-22-17" href="#__codelineno-22-17"></a><span class="nt">credentials</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">EXAMPLE2</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">user@example.com:hunter2</span>
</span><span id="__span-22-19"><a id="__codelineno-22-19" name="__codelineno-22-19" href="#__codelineno-22-19"></a>
</span><span id="__span-22-20"><a id="__codelineno-22-20" name="__codelineno-22-20" href="#__codelineno-22-20"></a><span class="nt">output_template</span><span class="p">:</span>
</span><span id="__span-22-21"><a id="__codelineno-22-21" name="__codelineno-22-21" href="#__codelineno-22-21"></a><span class="w"> </span><span class="nt">movies</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{title}.{year}.{quality?}.{source}-{tag}&quot;</span>
</span><span id="__span-22-22"><a id="__codelineno-22-22" name="__codelineno-22-22" href="#__codelineno-22-22"></a><span class="w"> </span><span class="nt">series</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{title}.{season_episode}.{quality?}.{source}-{tag}&quot;</span>
</span><span id="__span-22-23"><a id="__codelineno-22-23" name="__codelineno-22-23" href="#__codelineno-22-23"></a><span class="w"> </span><span class="nt">folder</span><span class="p">:</span>
</span><span id="__span-22-24"><a id="__codelineno-22-24" name="__codelineno-22-24" href="#__codelineno-22-24"></a><span class="w"> </span><span class="nt">movies</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{title}</span><span class="nv"> </span><span class="s">({year})&quot;</span>
</span><span id="__span-22-25"><a id="__codelineno-22-25" name="__codelineno-22-25" href="#__codelineno-22-25"></a><span class="w"> </span><span class="nt">series</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;{title}</span><span class="nv"> </span><span class="s">({year})&quot;</span>
</span><span id="__span-22-26"><a id="__codelineno-22-26" name="__codelineno-22-26" href="#__codelineno-22-26"></a>
</span><span id="__span-22-27"><a id="__codelineno-22-27" name="__codelineno-22-27" href="#__codelineno-22-27"></a><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">MYGRP</span>
</span><span id="__span-22-28"><a id="__codelineno-22-28" name="__codelineno-22-28" href="#__codelineno-22-28"></a>
</span><span id="__span-22-29"><a id="__codelineno-22-29" name="__codelineno-22-29" href="#__codelineno-22-29"></a><span class="nt">key_vaults</span><span class="p">:</span>
</span><span id="__span-22-30"><a id="__codelineno-22-30" name="__codelineno-22-30" href="#__codelineno-22-30"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">SQLite</span>
</span><span id="__span-22-31"><a id="__codelineno-22-31" name="__codelineno-22-31" href="#__codelineno-22-31"></a><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Local</span>
</span><span id="__span-22-32"><a id="__codelineno-22-32" name="__codelineno-22-32" href="#__codelineno-22-32"></a><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/.unshackle/keys.db</span>
</span><span id="__span-22-33"><a id="__codelineno-22-33" name="__codelineno-22-33" href="#__codelineno-22-33"></a>
</span><span id="__span-22-34"><a id="__codelineno-22-34" name="__codelineno-22-34" href="#__codelineno-22-34"></a><span class="nt">proxy_providers</span><span class="p">:</span>
</span><span id="__span-22-35"><a id="__codelineno-22-35" name="__codelineno-22-35" href="#__codelineno-22-35"></a><span class="w"> </span><span class="nt">basic</span><span class="p">:</span>
</span><span id="__span-22-36"><a id="__codelineno-22-36" name="__codelineno-22-36" href="#__codelineno-22-36"></a><span class="w"> </span><span class="nt">us</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">http://user:pass@1.2.3.4:8080</span>
</span><span id="__span-22-37"><a id="__codelineno-22-37" name="__codelineno-22-37" href="#__codelineno-22-37"></a>
</span><span id="__span-22-38"><a id="__codelineno-22-38" name="__codelineno-22-38" href="#__codelineno-22-38"></a><span class="nt">tmdb_api_key</span><span class="p">:</span><span class="w"> </span><span class="s">&quot;your-tmdb-key&quot;</span>
</span><span id="__span-22-39"><a id="__codelineno-22-39" name="__codelineno-22-39" href="#__codelineno-22-39"></a><span class="nt">title_cache_time</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3600</span>
</span><span id="__span-22-40"><a id="__codelineno-22-40" name="__codelineno-22-40" href="#__codelineno-22-40"></a><span class="nt">redact_paths</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
</span></code></pre></div>
<p>For how these interact at runtime, continue to <a href="../../guide/downloading/">Downloading</a>,
<a href="../../guide/drm-and-cdm/">DRM &amp; CDM</a>, and <a href="../../guide/output-and-naming/">Output &amp; naming</a>.</p>
</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="../../guide/troubleshooting/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Troubleshooting">
<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">
Troubleshooting
</div>
</div>
</a>
<a href="../../dev/creating-a-service/" class="md-footer__link md-footer__link--next" aria-label="Next: Creating a Service">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Creating a Service
</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.79ae519e.min.js"></script>
</body>
</html>