hydrus/developer_api.html

5976 lines
320 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="A personal booru-style media tagger that can import files and tags from your hard drive and popular websites. Content can be shared with other users via user-run servers.">
<link rel="canonical" href="https://hydrusnetwork.github.io/hydrus/developer_api.html">
<link rel="prev" href="client_api.html">
<link rel="next" href="faq.html">
<link rel="icon" href="assets/favicon.svg">
<meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.4.6">
<title>API documentation - hydrus network</title>
<link rel="stylesheet" href="assets/stylesheets/main.35e1ed30.min.css">
<link rel="stylesheet" href="assets/stylesheets/palette.356b1318.min.css">
<link rel="stylesheet" href="assets/stylesheets/extra.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="blue-grey" data-md-color-accent="blue">
<script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
<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="#api_documentation" 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="index.html" title="hydrus network" class="md-header__button md-logo" aria-label="hydrus network" data-md-component="logo">
<img src="assets/hydrus-white.svg" alt="logo">
</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 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></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">
hydrus network
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
API documentation
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="blue-grey" data-md-color-accent="blue" 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 6H7c-3.31 0-6 2.69-6 6s2.69 6 6 6h10c3.31 0 6-2.69 6-6s-2.69-6-6-6zm0 10H7c-2.21 0-4-1.79-4-4s1.79-4 4-4h10c2.21 0 4 1.79 4 4s-1.79 4-4 4zM7 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></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="blue" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_2">
<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="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 3Z"/></svg>
</label>
</form>
<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.516 6.516 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 5Z"/></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.516 6.516 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 5Z"/></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 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<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 12 19 6.41Z"/></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" 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/hydrusnetwork/hydrus" 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 496 512"><!--! Font Awesome Free 6.4.2 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 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</div>
<div class="md-source__repository">
hydrusnetwork/hydrus
</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="index.html" class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="introduction.html" class="md-tabs__link">
Getting Started
</a>
</li>
<li class="md-tabs__item">
<a href="advanced_siblings.html" class="md-tabs__link">
Advanced
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="client_api.html" class="md-tabs__link">
API
</a>
</li>
<li class="md-tabs__item">
<a href="faq.html" class="md-tabs__link">
Misc
</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" hidden>
<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="index.html" title="hydrus network" class="md-nav__button md-logo" aria-label="hydrus network" data-md-component="logo">
<img src="assets/hydrus-white.svg" alt="logo">
</a>
hydrus network
</label>
<div class="md-nav__source">
<a href="https://github.com/hydrusnetwork/hydrus" 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 496 512"><!--! Font Awesome Free 6.4.2 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 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</div>
<div class="md-source__repository">
hydrusnetwork/hydrus
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="index.html" class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--section 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="">
<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="introduction.html" class="md-nav__link">
<span class="md-ellipsis">
Introduction and Statement of Principles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="gettingStartedOverview.html" class="md-nav__link">
<span class="md-ellipsis">
Overview For Getting Started
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_installing.html" class="md-nav__link">
<span class="md-ellipsis">
Installing and Updating
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_files.html" class="md-nav__link">
<span class="md-ellipsis">
Files
</span>
</a>
</li>
<li class="md-nav__item">
<a href="filetypes.html" class="md-nav__link">
<span class="md-ellipsis">
Supported Filetypes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_importing.html" class="md-nav__link">
<span class="md-ellipsis">
Importing and Exporting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_tags.html" class="md-nav__link">
<span class="md-ellipsis">
Tags
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_searching.html" class="md-nav__link">
<span class="md-ellipsis">
Searching and Sorting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_more_tags.html" class="md-nav__link">
<span class="md-ellipsis">
More Tags
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_downloading.html" class="md-nav__link">
<span class="md-ellipsis">
Downloading
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_ratings.html" class="md-nav__link">
<span class="md-ellipsis">
Ratings
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_12" >
<label class="md-nav__link" for="__nav_2_12" id="__nav_2_12_label" tabindex="">
<span class="md-ellipsis">
PTR
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_12_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_12">
<span class="md-nav__icon md-icon"></span>
PTR
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="access_keys.html" class="md-nav__link">
<span class="md-ellipsis">
PTR Access Keys
</span>
</a>
</li>
<li class="md-nav__item">
<a href="PTR.html" class="md-nav__link">
<span class="md-ellipsis">
PTR Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="petitionPractices.html" class="md-nav__link">
<span class="md-ellipsis">
Petition Practices
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_13" >
<label class="md-nav__link" for="__nav_2_13" id="__nav_2_13_label" tabindex="">
<span class="md-ellipsis">
Next Steps
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_13">
<span class="md-nav__icon md-icon"></span>
Next Steps
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="adding_new_downloaders.html" class="md-nav__link">
<span class="md-ellipsis">
Adding New Downloaders
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_subscriptions.html" class="md-nav__link">
<span class="md-ellipsis">
Subscriptions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="duplicates.html" class="md-nav__link">
<span class="md-ellipsis">
Filtering Duplicates
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section 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="">
<span class="md-ellipsis">
Advanced
</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>
Advanced
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="advanced_siblings.html" class="md-nav__link">
<span class="md-ellipsis">
Tag Siblings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="advanced_parents.html" class="md-nav__link">
<span class="md-ellipsis">
Tag Parents
</span>
</a>
</li>
<li class="md-nav__item">
<a href="advanced_sidecars.html" class="md-nav__link">
<span class="md-ellipsis">
Sidecars
</span>
</a>
</li>
<li class="md-nav__item">
<a href="advanced_multiple_local_file_services.html" class="md-nav__link">
<span class="md-ellipsis">
Multiple Local File Services
</span>
</a>
</li>
<li class="md-nav__item">
<a href="advanced.html" class="md-nav__link">
<span class="md-ellipsis">
General Clever Tricks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="reducing_lag.html" class="md-nav__link">
<span class="md-ellipsis">
Reducing Lag
</span>
</a>
</li>
<li class="md-nav__item">
<a href="database_migration.html" class="md-nav__link">
<span class="md-ellipsis">
Database Migration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="launch_arguments.html" class="md-nav__link">
<span class="md-ellipsis">
Launch Arguments
</span>
</a>
</li>
<li class="md-nav__item">
<a href="ipfs.html" class="md-nav__link">
<span class="md-ellipsis">
IPFS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="local_booru.html" class="md-nav__link">
<span class="md-ellipsis">
Local Booru
</span>
</a>
</li>
<li class="md-nav__item">
<a href="server.html" class="md-nav__link">
<span class="md-ellipsis">
Running Your Own Server
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_12" >
<label class="md-nav__link" for="__nav_3_12" id="__nav_3_12_label" tabindex="">
<span class="md-ellipsis">
Alternate Installations
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_12_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_12">
<span class="md-nav__icon md-icon"></span>
Alternate Installations
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="docker.html" class="md-nav__link">
<span class="md-ellipsis">
Docker
</span>
</a>
</li>
<li class="md-nav__item">
<a href="wine.html" class="md-nav__link">
<span class="md-ellipsis">
Running In Wine
</span>
</a>
</li>
<li class="md-nav__item">
<a href="running_from_source.html" class="md-nav__link">
<span class="md-ellipsis">
Running From Source
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_13" >
<label class="md-nav__link" for="__nav_3_13" id="__nav_3_13_label" tabindex="">
<span class="md-ellipsis">
Downloader Creation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_13">
<span class="md-nav__icon md-icon"></span>
Downloader Creation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="downloader_intro.html" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_gugs.html" class="md-nav__link">
<span class="md-ellipsis">
Gallery URL Generators
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_url_classes.html" class="md-nav__link">
<span class="md-ellipsis">
URL Classes
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_13_4" >
<label class="md-nav__link" for="__nav_3_13_4" id="__nav_3_13_4_label" tabindex="0">
<span class="md-ellipsis">
Parsers
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_3_13_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_13_4">
<span class="md-nav__icon md-icon"></span>
Parsers
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="downloader_parsers.html" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_13_4_2" >
<label class="md-nav__link" for="__nav_3_13_4_2" id="__nav_3_13_4_2_label" tabindex="0">
<span class="md-ellipsis">
Components
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="4" aria-labelledby="__nav_3_13_4_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_13_4_2">
<span class="md-nav__icon md-icon"></span>
Components
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="downloader_parsers_formulae.html" class="md-nav__link">
<span class="md-ellipsis">
Formulae
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_parsers_content_parsers.html" class="md-nav__link">
<span class="md-ellipsis">
Content Parsers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_parsers_page_parsers.html" class="md-nav__link">
<span class="md-ellipsis">
Page Parsers
</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_13_4_3" >
<label class="md-nav__link" for="__nav_3_13_4_3" id="__nav_3_13_4_3_label" tabindex="0">
<span class="md-ellipsis">
Walkthroughs
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="4" aria-labelledby="__nav_3_13_4_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_13_4_3">
<span class="md-nav__icon md-icon"></span>
Walkthroughs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="downloader_parsers_full_example_gallery_page.html" class="md-nav__link">
<span class="md-ellipsis">
Gallery Page Example
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_parsers_full_example_file_page.html" class="md-nav__link">
<span class="md-ellipsis">
File Page Example
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_parsers_full_example_api.html" class="md-nav__link">
<span class="md-ellipsis">
API Example
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="downloader_completion.html" class="md-nav__link">
<span class="md-ellipsis">
Putting It All Together
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_sharing.html" class="md-nav__link">
<span class="md-ellipsis">
Sharing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_login.html" class="md-nav__link">
<span class="md-ellipsis">
Login Manager
</span>
</a>
</li>
</ul>
</nav>
</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">
API
</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>
API
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="client_api.html" class="md-nav__link">
<span class="md-ellipsis">
Client API
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
API documentation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="developer_api.html" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
API documentation
</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="#library_modules_created_by_hydrus_users" class="md-nav__link">
Library modules created by hydrus users
</a>
</li>
<li class="md-nav__item">
<a href="#api" class="md-nav__link">
API
</a>
</li>
<li class="md-nav__item">
<a href="#cbor" class="md-nav__link">
CBOR
</a>
</li>
<li class="md-nav__item">
<a href="#access_and_permissions" class="md-nav__link">
Access and permissions
</a>
</li>
<li class="md-nav__item">
<a href="#common_complex_parameters" class="md-nav__link">
Common Complex Parameters
</a>
<nav class="md-nav" aria-label="Common Complex Parameters">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#parameters_files" class="md-nav__link">
files
</a>
</li>
<li class="md-nav__item">
<a href="#parameters_file_domain" class="md-nav__link">
file domain
</a>
</li>
<li class="md-nav__item">
<a href="#legacy_service_name_parameters" class="md-nav__link">
legacy service_name parameters
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#services_object" class="md-nav__link">
The Services Object
</a>
</li>
<li class="md-nav__item">
<a href="#access_management" class="md-nav__link">
Access Management
</a>
<nav class="md-nav" aria-label="Access Management">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#api_version" class="md-nav__link">
GET /api_version
</a>
</li>
<li class="md-nav__item">
<a href="#request_new_permissions" class="md-nav__link">
GET /request_new_permissions
</a>
</li>
<li class="md-nav__item">
<a href="#session_key" class="md-nav__link">
GET /session_key
</a>
</li>
<li class="md-nav__item">
<a href="#verify_access_key" class="md-nav__link">
GET /verify_access_key
</a>
</li>
<li class="md-nav__item">
<a href="#get_service" class="md-nav__link">
GET /get_service
</a>
</li>
<li class="md-nav__item">
<a href="#get_services" class="md-nav__link">
GET /get_services
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#importing_and_deleting_files" class="md-nav__link">
Importing and Deleting Files
</a>
<nav class="md-nav" aria-label="Importing and Deleting Files">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#add_files_add_file" class="md-nav__link">
POST /add_files/add_file
</a>
</li>
<li class="md-nav__item">
<a href="#add_files_delete_files" class="md-nav__link">
POST /add_files/delete_files
</a>
</li>
<li class="md-nav__item">
<a href="#add_files_undelete_files" class="md-nav__link">
POST /add_files/undelete_files
</a>
</li>
<li class="md-nav__item">
<a href="#add_files_archive_files" class="md-nav__link">
POST /add_files/archive_files
</a>
</li>
<li class="md-nav__item">
<a href="#add_files_unarchive_files" class="md-nav__link">
POST /add_files/unarchive_files
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#importing_and_editing_urls" class="md-nav__link">
Importing and Editing URLs
</a>
<nav class="md-nav" aria-label="Importing and Editing URLs">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#add_urls_get_url_files" class="md-nav__link">
GET /add_urls/get_url_files
</a>
</li>
<li class="md-nav__item">
<a href="#add_urls_get_url_info" class="md-nav__link">
GET /add_urls/get_url_info
</a>
</li>
<li class="md-nav__item">
<a href="#add_urls_add_url" class="md-nav__link">
POST /add_urls/add_url
</a>
</li>
<li class="md-nav__item">
<a href="#add_urls_associate_url" class="md-nav__link">
POST /add_urls/associate_url
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#editing_file_tags" class="md-nav__link">
Editing File Tags
</a>
<nav class="md-nav" aria-label="Editing File Tags">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#add_tags_clean_tags" class="md-nav__link">
GET /add_tags/clean_tags
</a>
</li>
<li class="md-nav__item">
<a href="#add_tags_get_siblings_and_parents" class="md-nav__link">
GET /add_tags/get_siblings_and_parents
</a>
</li>
<li class="md-nav__item">
<a href="#add_tags_search_tags" class="md-nav__link">
GET /add_tags/search_tags
</a>
</li>
<li class="md-nav__item">
<a href="#add_tags_add_tags" class="md-nav__link">
POST /add_tags/add_tags
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#editing_file_ratings" class="md-nav__link">
Editing File Ratings
</a>
<nav class="md-nav" aria-label="Editing File Ratings">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#edit_ratings_set_rating" class="md-nav__link">
POST /edit_ratings/set_rating
</a>
<nav class="md-nav" aria-label="POST /edit_ratings/set_rating">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#likedislike_ratings" class="md-nav__link">
Like/Dislike Ratings
</a>
</li>
<li class="md-nav__item">
<a href="#numerical_ratings" class="md-nav__link">
Numerical Ratings
</a>
</li>
<li class="md-nav__item">
<a href="#incdec_ratings" class="md-nav__link">
Inc/Dec Ratings
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#editing_file_notes" class="md-nav__link">
Editing File Notes
</a>
<nav class="md-nav" aria-label="Editing File Notes">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#add_notes_set_notes" class="md-nav__link">
POST /add_notes/set_notes
</a>
</li>
<li class="md-nav__item">
<a href="#add_notes_delete_notes" class="md-nav__link">
POST /add_notes/delete_notes
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#searching_and_fetching_files" class="md-nav__link">
Searching and Fetching Files
</a>
<nav class="md-nav" aria-label="Searching and Fetching Files">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#get_files_search_files" class="md-nav__link">
GET /get_files/search_files
</a>
</li>
<li class="md-nav__item">
<a href="#get_files_file_hashes" class="md-nav__link">
GET /get_files/file_hashes
</a>
</li>
<li class="md-nav__item">
<a href="#get_files_file_metadata" class="md-nav__link">
GET /get_files/file_metadata
</a>
<nav class="md-nav" aria-label="GET /get_files/file_metadata">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#basics" class="md-nav__link">
basics
</a>
</li>
<li class="md-nav__item">
<a href="#tags" class="md-nav__link">
tags
</a>
</li>
<li class="md-nav__item">
<a href="#ratings" class="md-nav__link">
ratings
</a>
</li>
<li class="md-nav__item">
<a href="#services" class="md-nav__link">
services
</a>
</li>
<li class="md-nav__item">
<a href="#parameters" class="md-nav__link">
parameters
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#get_files_file" class="md-nav__link">
GET /get_files/file
</a>
</li>
<li class="md-nav__item">
<a href="#get_files_thumbnail" class="md-nav__link">
GET /get_files/thumbnail
</a>
</li>
<li class="md-nav__item">
<a href="#get_files_render" class="md-nav__link">
GET /get_files/render
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_file_relationships" class="md-nav__link">
Managing File Relationships
</a>
<nav class="md-nav" aria-label="Managing File Relationships">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_file_relationships_get_file_relationships" class="md-nav__link">
GET /manage_file_relationships/get_file_relationships
</a>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_get_potentials_count" class="md-nav__link">
GET /manage_file_relationships/get_potentials_count
</a>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_get_potential_pairs" class="md-nav__link">
GET /manage_file_relationships/get_potential_pairs
</a>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_get_random_potentials" class="md-nav__link">
GET /manage_file_relationships/get_random_potentials
</a>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_set_file_relationships" class="md-nav__link">
POST /manage_file_relationships/set_file_relationships
</a>
<nav class="md-nav" aria-label="POST /manage_file_relationships/set_file_relationships">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#king_merge_rules" class="md-nav__link">
king merge rules
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_set_kings" class="md-nav__link">
POST /manage_file_relationships/set_kings
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_cookies" class="md-nav__link">
Managing Cookies
</a>
<nav class="md-nav" aria-label="Managing Cookies">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_cookies_get_cookies" class="md-nav__link">
GET /manage_cookies/get_cookies
</a>
</li>
<li class="md-nav__item">
<a href="#manage_cookies_set_cookies" class="md-nav__link">
POST /manage_cookies/set_cookies
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_http_headers" class="md-nav__link">
Managing HTTP Headers
</a>
<nav class="md-nav" aria-label="Managing HTTP Headers">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_headers_get_headers" class="md-nav__link">
GET /manage_headers/get_headers
</a>
</li>
<li class="md-nav__item">
<a href="#manage_headers_set_headers" class="md-nav__link">
POST /manage_headers/set_headers
</a>
</li>
<li class="md-nav__item">
<a href="#manage_headers_set_user_agent" class="md-nav__link">
POST /manage_headers/set_user_agent
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_pages" class="md-nav__link">
Managing Pages
</a>
<nav class="md-nav" aria-label="Managing Pages">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_pages_get_pages" class="md-nav__link">
GET /manage_pages/get_pages
</a>
</li>
<li class="md-nav__item">
<a href="#manage_pages_get_page_info" class="md-nav__link">
GET /manage_pages/get_page_info
</a>
</li>
<li class="md-nav__item">
<a href="#manage_pages_add_files" class="md-nav__link">
POST /manage_pages/add_files
</a>
</li>
<li class="md-nav__item">
<a href="#manage_pages_focus_page" class="md-nav__link">
POST /manage_pages/focus_page
</a>
</li>
<li class="md-nav__item">
<a href="#manage_pages_refresh_page" class="md-nav__link">
POST /manage_pages/refresh_page
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_the_database" class="md-nav__link">
Managing the Database
</a>
<nav class="md-nav" aria-label="Managing the Database">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_database_lock_on" class="md-nav__link">
POST /manage_database/lock_on
</a>
</li>
<li class="md-nav__item">
<a href="#manage_database_lock_off" class="md-nav__link">
POST /manage_database/lock_off
</a>
</li>
<li class="md-nav__item">
<a href="#manage_database_mr_bones" class="md-nav__link">
GET /manage_database/mr_bones
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section 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="">
<span class="md-ellipsis">
Misc
</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>
Misc
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="faq.html" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item">
<a href="privacy.html" class="md-nav__link">
<span class="md-ellipsis">
Privacy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="contact.html" class="md-nav__link">
<span class="md-ellipsis">
Contact and Links
</span>
</a>
</li>
<li class="md-nav__item">
<a href="support.html" class="md-nav__link">
<span class="md-ellipsis">
Financial Support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="changelog.html" class="md-nav__link">
<span class="md-ellipsis">
Changelog
</span>
</a>
</li>
<li class="md-nav__item">
<a href="about_docs.html" class="md-nav__link">
<span class="md-ellipsis">
About These Docs
</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="#library_modules_created_by_hydrus_users" class="md-nav__link">
Library modules created by hydrus users
</a>
</li>
<li class="md-nav__item">
<a href="#api" class="md-nav__link">
API
</a>
</li>
<li class="md-nav__item">
<a href="#cbor" class="md-nav__link">
CBOR
</a>
</li>
<li class="md-nav__item">
<a href="#access_and_permissions" class="md-nav__link">
Access and permissions
</a>
</li>
<li class="md-nav__item">
<a href="#common_complex_parameters" class="md-nav__link">
Common Complex Parameters
</a>
<nav class="md-nav" aria-label="Common Complex Parameters">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#parameters_files" class="md-nav__link">
files
</a>
</li>
<li class="md-nav__item">
<a href="#parameters_file_domain" class="md-nav__link">
file domain
</a>
</li>
<li class="md-nav__item">
<a href="#legacy_service_name_parameters" class="md-nav__link">
legacy service_name parameters
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#services_object" class="md-nav__link">
The Services Object
</a>
</li>
<li class="md-nav__item">
<a href="#access_management" class="md-nav__link">
Access Management
</a>
<nav class="md-nav" aria-label="Access Management">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#api_version" class="md-nav__link">
GET /api_version
</a>
</li>
<li class="md-nav__item">
<a href="#request_new_permissions" class="md-nav__link">
GET /request_new_permissions
</a>
</li>
<li class="md-nav__item">
<a href="#session_key" class="md-nav__link">
GET /session_key
</a>
</li>
<li class="md-nav__item">
<a href="#verify_access_key" class="md-nav__link">
GET /verify_access_key
</a>
</li>
<li class="md-nav__item">
<a href="#get_service" class="md-nav__link">
GET /get_service
</a>
</li>
<li class="md-nav__item">
<a href="#get_services" class="md-nav__link">
GET /get_services
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#importing_and_deleting_files" class="md-nav__link">
Importing and Deleting Files
</a>
<nav class="md-nav" aria-label="Importing and Deleting Files">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#add_files_add_file" class="md-nav__link">
POST /add_files/add_file
</a>
</li>
<li class="md-nav__item">
<a href="#add_files_delete_files" class="md-nav__link">
POST /add_files/delete_files
</a>
</li>
<li class="md-nav__item">
<a href="#add_files_undelete_files" class="md-nav__link">
POST /add_files/undelete_files
</a>
</li>
<li class="md-nav__item">
<a href="#add_files_archive_files" class="md-nav__link">
POST /add_files/archive_files
</a>
</li>
<li class="md-nav__item">
<a href="#add_files_unarchive_files" class="md-nav__link">
POST /add_files/unarchive_files
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#importing_and_editing_urls" class="md-nav__link">
Importing and Editing URLs
</a>
<nav class="md-nav" aria-label="Importing and Editing URLs">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#add_urls_get_url_files" class="md-nav__link">
GET /add_urls/get_url_files
</a>
</li>
<li class="md-nav__item">
<a href="#add_urls_get_url_info" class="md-nav__link">
GET /add_urls/get_url_info
</a>
</li>
<li class="md-nav__item">
<a href="#add_urls_add_url" class="md-nav__link">
POST /add_urls/add_url
</a>
</li>
<li class="md-nav__item">
<a href="#add_urls_associate_url" class="md-nav__link">
POST /add_urls/associate_url
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#editing_file_tags" class="md-nav__link">
Editing File Tags
</a>
<nav class="md-nav" aria-label="Editing File Tags">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#add_tags_clean_tags" class="md-nav__link">
GET /add_tags/clean_tags
</a>
</li>
<li class="md-nav__item">
<a href="#add_tags_get_siblings_and_parents" class="md-nav__link">
GET /add_tags/get_siblings_and_parents
</a>
</li>
<li class="md-nav__item">
<a href="#add_tags_search_tags" class="md-nav__link">
GET /add_tags/search_tags
</a>
</li>
<li class="md-nav__item">
<a href="#add_tags_add_tags" class="md-nav__link">
POST /add_tags/add_tags
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#editing_file_ratings" class="md-nav__link">
Editing File Ratings
</a>
<nav class="md-nav" aria-label="Editing File Ratings">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#edit_ratings_set_rating" class="md-nav__link">
POST /edit_ratings/set_rating
</a>
<nav class="md-nav" aria-label="POST /edit_ratings/set_rating">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#likedislike_ratings" class="md-nav__link">
Like/Dislike Ratings
</a>
</li>
<li class="md-nav__item">
<a href="#numerical_ratings" class="md-nav__link">
Numerical Ratings
</a>
</li>
<li class="md-nav__item">
<a href="#incdec_ratings" class="md-nav__link">
Inc/Dec Ratings
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#editing_file_notes" class="md-nav__link">
Editing File Notes
</a>
<nav class="md-nav" aria-label="Editing File Notes">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#add_notes_set_notes" class="md-nav__link">
POST /add_notes/set_notes
</a>
</li>
<li class="md-nav__item">
<a href="#add_notes_delete_notes" class="md-nav__link">
POST /add_notes/delete_notes
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#searching_and_fetching_files" class="md-nav__link">
Searching and Fetching Files
</a>
<nav class="md-nav" aria-label="Searching and Fetching Files">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#get_files_search_files" class="md-nav__link">
GET /get_files/search_files
</a>
</li>
<li class="md-nav__item">
<a href="#get_files_file_hashes" class="md-nav__link">
GET /get_files/file_hashes
</a>
</li>
<li class="md-nav__item">
<a href="#get_files_file_metadata" class="md-nav__link">
GET /get_files/file_metadata
</a>
<nav class="md-nav" aria-label="GET /get_files/file_metadata">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#basics" class="md-nav__link">
basics
</a>
</li>
<li class="md-nav__item">
<a href="#tags" class="md-nav__link">
tags
</a>
</li>
<li class="md-nav__item">
<a href="#ratings" class="md-nav__link">
ratings
</a>
</li>
<li class="md-nav__item">
<a href="#services" class="md-nav__link">
services
</a>
</li>
<li class="md-nav__item">
<a href="#parameters" class="md-nav__link">
parameters
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#get_files_file" class="md-nav__link">
GET /get_files/file
</a>
</li>
<li class="md-nav__item">
<a href="#get_files_thumbnail" class="md-nav__link">
GET /get_files/thumbnail
</a>
</li>
<li class="md-nav__item">
<a href="#get_files_render" class="md-nav__link">
GET /get_files/render
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_file_relationships" class="md-nav__link">
Managing File Relationships
</a>
<nav class="md-nav" aria-label="Managing File Relationships">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_file_relationships_get_file_relationships" class="md-nav__link">
GET /manage_file_relationships/get_file_relationships
</a>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_get_potentials_count" class="md-nav__link">
GET /manage_file_relationships/get_potentials_count
</a>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_get_potential_pairs" class="md-nav__link">
GET /manage_file_relationships/get_potential_pairs
</a>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_get_random_potentials" class="md-nav__link">
GET /manage_file_relationships/get_random_potentials
</a>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_set_file_relationships" class="md-nav__link">
POST /manage_file_relationships/set_file_relationships
</a>
<nav class="md-nav" aria-label="POST /manage_file_relationships/set_file_relationships">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#king_merge_rules" class="md-nav__link">
king merge rules
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#manage_file_relationships_set_kings" class="md-nav__link">
POST /manage_file_relationships/set_kings
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_cookies" class="md-nav__link">
Managing Cookies
</a>
<nav class="md-nav" aria-label="Managing Cookies">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_cookies_get_cookies" class="md-nav__link">
GET /manage_cookies/get_cookies
</a>
</li>
<li class="md-nav__item">
<a href="#manage_cookies_set_cookies" class="md-nav__link">
POST /manage_cookies/set_cookies
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_http_headers" class="md-nav__link">
Managing HTTP Headers
</a>
<nav class="md-nav" aria-label="Managing HTTP Headers">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_headers_get_headers" class="md-nav__link">
GET /manage_headers/get_headers
</a>
</li>
<li class="md-nav__item">
<a href="#manage_headers_set_headers" class="md-nav__link">
POST /manage_headers/set_headers
</a>
</li>
<li class="md-nav__item">
<a href="#manage_headers_set_user_agent" class="md-nav__link">
POST /manage_headers/set_user_agent
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_pages" class="md-nav__link">
Managing Pages
</a>
<nav class="md-nav" aria-label="Managing Pages">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_pages_get_pages" class="md-nav__link">
GET /manage_pages/get_pages
</a>
</li>
<li class="md-nav__item">
<a href="#manage_pages_get_page_info" class="md-nav__link">
GET /manage_pages/get_page_info
</a>
</li>
<li class="md-nav__item">
<a href="#manage_pages_add_files" class="md-nav__link">
POST /manage_pages/add_files
</a>
</li>
<li class="md-nav__item">
<a href="#manage_pages_focus_page" class="md-nav__link">
POST /manage_pages/focus_page
</a>
</li>
<li class="md-nav__item">
<a href="#manage_pages_refresh_page" class="md-nav__link">
POST /manage_pages/refresh_page
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#managing_the_database" class="md-nav__link">
Managing the Database
</a>
<nav class="md-nav" aria-label="Managing the Database">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#manage_database_lock_on" class="md-nav__link">
POST /manage_database/lock_on
</a>
</li>
<li class="md-nav__item">
<a href="#manage_database_lock_off" class="md-nav__link">
POST /manage_database/lock_off
</a>
</li>
<li class="md-nav__item">
<a href="#manage_database_mr_bones" class="md-nav__link">
GET /manage_database/mr_bones
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/hydrusnetwork/hydrus/edit/master/docs/developer_api.md" title="Edit this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4v-2m10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1 2.1 2.1Z"/></svg>
</a>
<h1 id="api_documentation">API documentation<a class="headerlink" href="#api_documentation" title="Permanent link">&para;</a></h1>
<h2 id="library_modules_created_by_hydrus_users">Library modules created by hydrus users<a class="headerlink" href="#library_modules_created_by_hydrus_users" title="Permanent link">&para;</a></h2>
<ul>
<li><a href="https://gitlab.com/cryzed/hydrus-api">Hydrus API</a>: A python module that talks to the API.</li>
<li><a href="https://github.com/cravxx/hydrus.js">hydrus.js</a>: A node.js module that talks to the API.</li>
<li><a href="https://github.com/stars/hydrusnetwork/lists/hydrus-related-projects">more projects on github</a></li>
</ul>
<h2 id="api">API<a class="headerlink" href="#api" title="Permanent link">&para;</a></h2>
<p>In general, the API deals with standard UTF-8 JSON. POST requests and 200 OK responses are generally going to be a JSON 'Object' with variable names as keys and values obviously as values. There are examples throughout this document. For GET requests, everything is in standard GET parameters, but some variables are complicated and will need to be JSON encoded and then URL encoded. An example would be the 'tags' parameter on <a href="#get_files_search_files">GET /get_files/search_files</a>, which is a list of strings. Since GET http URLs have limits on what characters are allowed, but hydrus tags can have all sorts of characters, you'll be doing this:</p>
<ul>
<li>
<p>Your list of tags:</p>
<div class="highlight"><pre><span></span><code>[ &#39;character:samus aran&#39;, &#39;creator:青い桜&#39;, &#39;system:height &gt; 2000&#39; ]
</code></pre></div>
</li>
<li>
<p>JSON encoded:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="s2">&quot;character:samus aran&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;creator:\\u9752\\u3044\\u685c&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;system:height &gt; 2000&quot;</span><span class="p">]</span>
</code></pre></div>
</li>
<li>
<p>Then URL encoded:</p>
<div class="highlight"><pre><span></span><code>%5B%22character%3Asamus%20aran%22%2C%20%22creator%3A%5Cu9752%5Cu3044%5Cu685c%22%2C%20%22system%3Aheight%20%3E%202000%22%5D
</code></pre></div>
</li>
<li>
<p>In python, converting your tag list to the URL encoded string would be:</p>
<div class="highlight"><pre><span></span><code>urllib.parse.quote( json.dumps( tag_list ) )
</code></pre></div>
</li>
<li>
<p>Full URL path example:</p>
<div class="highlight"><pre><span></span><code>/get_files/search_files?file_sort_type=6&amp;file_sort_asc=false&amp;tags=%5B%22character%3Asamus%20aran%22%2C%20%22creator%3A%5Cu9752%5Cu3044%5Cu685c%22%2C%20%22system%3Aheight%20%3E%202000%22%5D
</code></pre></div>
</li>
</ul>
<p>The API returns JSON for everything except actual file/thumbnail requests. Every JSON response includes the <code>version</code> of the Client API and <code>hydrus_version</code> of the Client hosting it (for brevity, these values are not included in the example responses in this help). For errors, you'll typically get 400 for a missing/invalid parameter, 401/403/419 for missing/insufficient/expired access, and 500 for a real deal serverside error.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>For any request sent to the API, the total size of the initial request line (this includes the URL and any parameters) and the headers must not be larger than 2 megabytes.
Exceeding this limit will cause the request to fail. Make sure to use pagination if you are passing very large JSON arrays as parameters in a GET request.</p>
</div>
<h2 id="cbor">CBOR<a class="headerlink" href="#cbor" title="Permanent link">&para;</a></h2>
<p>The API now tentatively supports CBOR, which is basically 'byte JSON'. If you are in a lower level language or need to do a lot of heavy work quickly, try it out!</p>
<p>To send CBOR, for POST put Content-Type <code>application/cbor</code> in your request header instead of <code>application/json</code>, and for GET just add a <code>cbor=1</code> parameter to the URL string. Use CBOR to encode any parameters that you would previously put in JSON:</p>
<p>For POST requests, just print the pure bytes in the body, like this:</p>
<div class="highlight"><pre><span></span><code>cbor2.dumps( arg_dict )
</code></pre></div>
<p>For GET, encode the parameter value in base64, like this:</p>
<p><div class="highlight"><pre><span></span><code>base64.urlsafe_b64encode( cbor2.dumps( argument ) )
</code></pre></div>
-or-
<div class="highlight"><pre><span></span><code>str( base64.urlsafe_b64encode( cbor2.dumps( argument ) ), &#39;ascii&#39; )
</code></pre></div></p>
<p>If you send CBOR, the client will return CBOR. If you want to send CBOR and get JSON back, or <em>vice versa</em> (or you are uploading a file and can't set CBOR Content-Type), send the Accept request header, like so:</p>
<div class="highlight"><pre><span></span><code>Accept: application/cbor
Accept: application/json
</code></pre></div>
<p>If the client does not support CBOR, you'll get 406.</p>
<h2 id="access_and_permissions">Access and permissions<a class="headerlink" href="#access_and_permissions" title="Permanent link">&para;</a></h2>
<p>The client gives access to its API through different 'access keys', which are the typical 64-character hex used in many other places across hydrus. Each guarantees different permissions such as handling files or tags. Most of the time, a user will provide full access, but do not assume this. If the access header or parameter is not provided, you will get 401, and all insufficient permission problems will return 403 with appropriate error text.</p>
<p>Access is required for every request. You can provide this as an http header, like so:</p>
<div class="highlight"><pre><span></span><code>Hydrus-Client-API-Access-Key : 0150d9c4f6a6d2082534a997f4588dcf0c56dffe1d03ffbf98472236112236ae
</code></pre></div>
<p>Or you can include it in the normal parameters of any request (except <em>POST /add_files/add_file</em>, which uses the entire POST body for the file's bytes). For GET, this means including it into the URL parameters:</p>
<div class="highlight"><pre><span></span><code>/get_files/thumbnail?file_id=452158&amp;Hydrus-Client-API-Access-Key=0150d9c4f6a6d2082534a997f4588dcf0c56dffe1d03ffbf98472236112236ae
</code></pre></div>
<p>For POST, this means in the JSON body parameters, like so:</p>
<div class="highlight"><pre><span></span><code>{
&quot;hash_id&quot; : 123456,
&quot;Hydrus-Client-API-Access-Key&quot; : &quot;0150d9c4f6a6d2082534a997f4588dcf0c56dffe1d03ffbf98472236112236ae&quot;
}
</code></pre></div>
<p>There is also a simple 'session' system, where you can get a temporary key that gives the same access without having to include the permanent access key in every request. You can fetch a session key with the <a href="#session_key">/session_key</a> command and thereafter use it just as you would an access key, just with <em>Hydrus-Client-API-Session-Key</em> instead.</p>
<p>Session keys will expire if they are not used within 24 hours, or if the client is restarted, or if the underlying access key is deleted. An invalid/expired session key will give a <strong>419</strong> result with an appropriate error text.</p>
<p>Bear in mind the Client API is still under construction. Setting up the Client API to be accessible across the internet requires technical experience to be convenient. HTTPS is available for encrypted comms, but the default certificate is self-signed (which basically means an eavesdropper can't see through it, but your ISP/government could if they decided to target you). If you have your own domain to host from and an SSL cert, you can replace them and it'll use them instead (check the db directory for client.crt and client.key). Otherwise, be careful about transmitting sensitive content outside of your localhost/network.</p>
<h2 id="common_complex_parameters">Common Complex Parameters<a class="headerlink" href="#common_complex_parameters" title="Permanent link">&para;</a></h2>
<h3 id="parameters_files"><strong>files</strong><a class="headerlink" href="#parameters_files" title="Permanent link">&para;</a></h3>
<p>If you need to refer to some files, you can use any of the following:</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>file_id</code>: (selective, a numerical file id)</li>
<li><code>file_ids</code>: (selective, a list of numerical file ids)</li>
<li><code>hash</code>: (selective, a hexadecimal SHA256 hash)</li>
<li><code>hashes</code>: (selective, a list of hexadecimal SHA256 hashes)</li>
</ul>
</dd>
</dl>
<p>In GET requests, make sure any list is percent-encoded.</p>
<h3 id="parameters_file_domain"><strong>file domain</strong><a class="headerlink" href="#parameters_file_domain" title="Permanent link">&para;</a></h3>
<p>When you are searching, you may want to specify a particular file domain. Most of the time, you'll want to just set <code>file_service_key</code>, but this can get complex:</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>file_service_key</code>: (optional, selective A, hexadecimal, the file domain on which to search)</li>
<li><code>file_service_keys</code>: (optional, selective A, list of hexadecimals, the union of file domains on which to search)</li>
<li><code>deleted_file_service_key</code>: (optional, selective B, hexadecimal, the 'deleted from this file domain' on which to search)</li>
<li><code>deleted_file_service_keys</code>: (optional, selective B, list of hexadecimals, the union of 'deleted from this file domain' on which to search)</li>
</ul>
</dd>
</dl>
<p>The service keys are as in <a href="#get_services">/get_services</a>.</p>
<p>Hydrus supports two concepts here:</p>
<ul>
<li>Searching over a UNION of subdomains. If the user has several local file domains, e.g. 'favourites', 'personal', 'sfw', and 'nsfw', they might like to search two of them at once.</li>
<li>Searching deleted files of subdomains. You can specifically, and quickly, search the files that have been deleted from somewhere.</li>
</ul>
<p>You can play around with this yourself by clicking 'multiple locations' in the client with <em>help-&gt;advanced mode</em> on.</p>
<p>In extreme edge cases, these two can be mixed by populating both A and B selective, making a larger union of both current and deleted file records.</p>
<p>Please note that unions can be very very computationally expensive. If you can achieve what you want with a single file_service_key, two queries in a row with different service keys, or an umbrella like <code>all my files</code> or <code>all local files</code>, please do. Otherwise, let me know what is running slow and I'll have a look at it.</p>
<p>'deleted from all local files' includes all files that have been physically deleted (i.e. deleted from the trash) and not available any more for fetch file/thumbnail requests. 'deleted from all my files' includes all of those physically deleted files <em>and</em> the trash. If a file is deleted with the special 'do not leave a deletion record' command, then it won't show up in a 'deleted from file domain' search!</p>
<p>'all known files' is a tricky domain. It converts much of the search tech to ignore where files actually are and look at the accompanying tag domain (e.g. all the files that have been tagged), and can sometimes be very expensive.</p>
<p>Also, if you have the option to set both file and tag domains, you cannot enter 'all known files'/'all known tags'. It is too complicated to support, sorry!</p>
<h3 id="legacy_service_name_parameters"><strong>legacy service_name parameters</strong><a class="headerlink" href="#legacy_service_name_parameters" title="Permanent link">&para;</a></h3>
<p>The Client API used to respond to name-based service identifiers, for instance using 'my tags' instead of something like '6c6f63616c2074616773'. Service names can change, and they aren't <em>strictly</em> unique either, so I have moved away from them, but there is some soft legacy support.</p>
<p>The client will attempt to convert any of these to their 'service_key(s)' equivalents:</p>
<ul>
<li>file_service_name</li>
<li>tag_service_name</li>
<li>service_names_to_tags</li>
<li>service_names_to_actions_to_tags</li>
<li>service_names_to_additional_tags</li>
</ul>
<p>But I strongly encourage you to move away from them as soon as reasonably possible. Look up the service keys you need with <a href="#get_service">/get_service</a> or <a href="#get_services">/get_services</a>.</p>
<p>If you have a clever script/program that does many things, then hit up <a href="#get_services">/get_services</a> on session initialisation and cache an internal map of key_to_name for the labels to use when you present services to the user.</p>
<p>Also, note that all users can now copy their service keys from <em>review services</em>.</p>
<h2 id="services_object">The Services Object<a class="headerlink" href="#services_object" title="Permanent link">&para;</a></h2>
<p>Hydrus manages its different available domains and actions with what it calls <em>services</em>. If you are a regular user of the program, you will know about <em>review services</em> and <em>manage services</em>. The Client API needs to refer to services, either to accept commands from you or to tell you what metadata files have and where.</p>
<p>When it does this, it gives you this structure, typically under a <code>services</code> key right off the root node:</p>
<div class="highlight"><span class="filename">Services Object</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;my tags&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;local tag service&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;5674450950748cfb28778b511024cfbf0f9f67355cf833de632244078b5a6f8d&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;example tag repo&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;hydrus tag repository&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2066696c6573&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;my files&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;local file domain&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;7265706f7369746f72792075706461746573&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;repository updates&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">20</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;local update file domain&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;ae7d9a603008919612894fc360130ae3d9925b8577d075cd0473090ac38b12b6&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;example file repo&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;hydrus file repository&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;616c6c206c6f63616c2066696c6573&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;all local files&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">15</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;virtual combined local file service&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;616c6c206c6f63616c206d65646961&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;all my files&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">21</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;virtual combined local media service&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;616c6c206b6e6f776e2066696c6573&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;all known files&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">11</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;virtual combined file service&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;616c6c206b6e6f776e2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;all known tags&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;virtual combined tag service&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;74d52c6238d25f846d579174c11856b1aaccdb04a185cb2c79f0d0e499284f2c&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;example local rating like service&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">7</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;local like/dislike rating service&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;star_shape&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;circle&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;90769255dae5c205c975fc4ce2efff796b8be8a421f786c1737f87f98187ffaf&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;example local rating numerical service&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">6</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;local numerical rating service&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;star_shape&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;fat star&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;min_stars&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;max_stars&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">5</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;b474e0cbbab02ca1479c12ad985f1c680ea909a54eb028e3ad06750ea40d4106&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;example local rating inc/dec service&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">22</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;local inc/dec rating service&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;7472617368&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;trash&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">14</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;local trash file domain&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>I hope you recognise some of the information here. But what's that hex key on each section? It is the <code>service_key</code>.</p>
<p>All services have these properties:</p>
<ul>
<li><code>name</code> - A mutable human-friendly name like 'my tags'. You can use this to present the service to the user--they should recognise it.</li>
<li><code>type</code> - An integer enum saying whether the service is a local tag service or like/dislike rating service or whatever. This cannot change.</li>
<li><code>service_key</code> - The true 'id' of the service. It is a string of hex, sometimes just twenty or so characters but in many cases 64 characters. This cannot change, and it is how we will refer to different services.</li>
</ul>
<p>This <code>service_key</code> is important. A user can rename their services, so <code>name</code> is not an excellent identifier, and definitely not something you should save to any permanent config file.</p>
<p>If we want to search some files on a particular file and tag domain, we should expect to be saying something like <code>file_service_key=6c6f63616c2066696c6573</code> and <code>tag_service_key=f032e94a38bb9867521a05dc7b189941a9c65c25048911f936fc639be2064a4b</code> somewhere in the request.</p>
<p>You won't see all of these, but the service <code>type</code> enum is:</p>
<ul>
<li>0 - tag repository</li>
<li>1 - file repository</li>
<li>2 - a local file domain like 'my files'</li>
<li>5 - a local tag domain like 'my tags'</li>
<li>6 - a 'numerical' rating service with several stars</li>
<li>7 - a 'like/dislike' rating service with on/off status</li>
<li>10 - all known tags -- a union of all the tag services</li>
<li>11 - all known files -- a union of all the file services and files that appear in tag services</li>
<li>12 - the local booru -- you can ignore this</li>
<li>13 - IPFS</li>
<li>14 - trash</li>
<li>15 - all local files -- all files on hard disk ('all my files' + updates + trash) </li>
<li>17 - file notes</li>
<li>18 - Client API</li>
<li>19 - all deleted files -- you can ignore this</li>
<li>20 - local updates -- a file domain to store repository update files in</li>
<li>21 - all my files -- union of all local file domains</li>
<li>22 - a 'inc/dec' rating service with positive integer rating</li>
<li>99 - server administration</li>
</ul>
<p><code>type_pretty</code> is something you can show users. Hydrus uses the same labels in <em>manage services</em> and so on.</p>
<p>Rating services now have some extra data:</p>
<ul>
<li>like/dislike and numerical services have <code>star_shape</code>, which is one of <code>circle | square | fat star | pentagram star</code></li>
<li>numerical services have <code>min_stars</code> (0 or 1) and <code>max_stars</code> (1 to 20)</li>
</ul>
<p>If you are displaying ratings, don't feel crazy obligated to obey the shape! Show a &#8536;, select from a dropdown list, do whatever you like!</p>
<p>If you want to know the services in a client, hit up <a href="#get_services">/get_services</a>, which simply gives the above. The same structure has recently been added to <a href="#get_files_file_metadata">/get_files/file_metadata</a> for convenience, since that refers to many different services when it is talking about file locations and ratings and so on.</p>
<p>Note: If you need to do some quick testing, you should be able to copy the <code>service_key</code> of any service by hitting the 'copy service key' button in <em>review services</em>.</p>
<h2 id="access_management">Access Management<a class="headerlink" href="#access_management" title="Permanent link">&para;</a></h2>
<h3 id="api_version"><strong>GET <code>/api_version</code></strong><a class="headerlink" href="#api_version" title="Permanent link">&para;</a></h3>
<p><em>Gets the current API version. This increments every time I alter the API.</em></p>
<p>Restricted access: NO.</p>
<p>Required Headers: n/a</p>
<p>Arguments: n/a</p>
<dl>
<dt>Response:</dt>
<dd>Some simple JSON describing the current api version (and hydrus client version, if you are interested).</dd>
<dd>Note that this is not very useful any more, for two reasons:</dd>
<dd>
<ol>
<li>The 'Server' header of every response (and a duplicated 'Hydrus-Server' one, if you have a complicated proxy situation that overwrites 'Server') are now in the form "client api/{client_api_version} ({software_version})", e.g. "client api/32 (497)".</li>
</ol>
</dd>
<dd>
<ol>
<li><strong>Every JSON response explicitly includes this now.</strong></li>
</ol>
</dd>
</dl>
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;version&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">17</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hydrus_version&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">441</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="request_new_permissions"><strong>GET <code>/request_new_permissions</code></strong><a class="headerlink" href="#request_new_permissions" title="Permanent link">&para;</a></h3>
<p><em>Register a new external program with the client. This requires the 'add from api request' mini-dialog under</em> services-&gt;review services <em>to be open, otherwise it will 403.</em></p>
<p>Restricted access: NO.</p>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>name</code>: (descriptive name of your access)</li>
<li>
<p><code>basic_permissions</code>: A JSON-encoded list of numerical permission identifiers you want to request.</p>
<p>The permissions are currently:</p>
<ul>
<li>0 - Import and Edit URLs</li>
<li>1 - Import and Delete Files</li>
<li>2 - Edit File Tags</li>
<li>3 - Search for and Fetch Files</li>
<li>4 - Manage Pages</li>
<li>5 - Manage Cookies and Headers</li>
<li>6 - Manage Database</li>
<li>7 - Edit File Notes</li>
<li>8 - Edit File Relationships</li>
<li>9 - Edit File Ratings</li>
</ul>
</li>
</ul>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/request_new_permissions?name=my%20import%20script&amp;basic_permissions=[0,1]
</code></pre></div>
</dd>
<dt>Response:</dt>
<dd>Some JSON with your access key, which is 64 characters of hex. This will not be valid until the user approves the request in the client ui.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;access_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;73c9ab12751dcf3368f028d3abbe1d8e2a3a48d0de25e64f3a8f00f3a1424c57&quot;</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<h3 id="session_key"><strong>GET <code>/session_key</code></strong><a class="headerlink" href="#session_key" title="Permanent link">&para;</a></h3>
<p><em>Get a new session key.</em></p>
<p>Restricted access: YES. No permissions required.</p>
<p>Required Headers: n/a</p>
<p>Arguments: n/a</p>
<dl>
<dt>Response:</dt>
<dd>Some JSON with a new session key in hex. <br />
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;session_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;f6e651e7467255ade6f7c66050f3d595ff06d6f3d3693a3a6fb1a9c2b278f800&quot;</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Note that the access you provide to get a new session key <strong>can</strong> be a session key, if that happens to be useful. As long as you have some kind of access, you can generate a new session key.</p>
<p>A session key expires after 24 hours of inactivity, whenever the client restarts, or if the underlying access key is deleted. A request on an expired session key returns 419.</p>
</div>
<h3 id="verify_access_key"><strong>GET <code>/verify_access_key</code></strong><a class="headerlink" href="#verify_access_key" title="Permanent link">&para;</a></h3>
<p><em>Check your access key is valid.</em></p>
<p>Restricted access: YES. No permissions required.</p>
<p>Required Headers: n/a</p>
<p>Arguments: n/a</p>
<dl>
<dt>Response:</dt>
<dd>401/403/419 and some error text if the provided access/session key is invalid, otherwise some JSON with basic permission info.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;basic_permissions&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;human_description&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;API Permissions (autotagger): add tags to files, import files, search for files: Can search: only autotag this&quot;</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<h3 id="get_service"><strong>GET <code>/get_service</code></strong><a class="headerlink" href="#get_service" title="Permanent link">&para;</a></h3>
<p><em>Ask the client about a specific service.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. At least one of Add Files, Add Tags, Manage Pages, or Search Files permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>service_name</code>: (selective, string, the name of the service)</li>
<li><code>service_key</code>: (selective, hex string, the service key of the service)</li>
</ul>
</dd>
<dt>Example requests:</dt>
<dd><div class="highlight"><span class="filename">Example requests</span><pre><span></span><code>/get_service?service_name=my%20tags
/get_service?service_key=6c6f63616c2074616773
</code></pre></div></dd>
<dt>Response:</dt>
<dd>Some JSON about the service. A similar format as <a href="#get_services">/get_services</a> and <a href="#services_object">The Services Object</a>.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;service&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;my tags&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;service_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;6c6f63616c2074616773&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;type_pretty&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;local tag service&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<p>If the service does not exist, this gives 404. It is very unlikely but edge-case possible that two services will have the same name, in this case you'll get the pseudorandom first.</p>
<p>It will only respond to services in the /get_services list. I will expand the available types in future as we add ratings etc... to the Client API.</p>
<h3 id="get_services"><strong>GET <code>/get_services</code></strong><a class="headerlink" href="#get_services" title="Permanent link">&para;</a></h3>
<p><em>Ask the client about its services.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. At least one of Add Files, Add Tags, Manage Pages, or Search Files permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<p>Arguments: n/a</p>
<dl>
<dt>Response:</dt>
<dd>Some JSON listing the client's services.</dd>
</dl>
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;services&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;The Services Object&quot;</span>
<span class="p">}</span>
</code></pre></div>
<p>This now primarily uses <a href="#services_object">The Services Object</a>.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If you do the request and look at the actual response, you will see a lot more data under different keys--this is deprecated, and will be deleted in 2024. If you use the old structure, please move over!</p>
</div>
<h2 id="importing_and_deleting_files">Importing and Deleting Files<a class="headerlink" href="#importing_and_deleting_files" title="Permanent link">&para;</a></h2>
<h3 id="add_files_add_file"><strong>POST <code>/add_files/add_file</code></strong><a class="headerlink" href="#add_files_add_file" title="Permanent link">&para;</a></h3>
<p><em>Tell the client to import a file.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import Files permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li>Content-Type: <code>application/json</code> (if sending path), <code>application/octet-stream</code> (if sending file)</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>path</code>: (the path you want to import)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;path&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;E:\\to_import\\ayanami.jpg&quot;</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Arguments (as bytes):</dt>
<dd>You can alternately just send the file's bytes as the POST body.</dd>
<dt>Response:</dt>
<dd>
<p>Some JSON with the import result. Please note that file imports for large files may take several seconds, and longer if the client is busy doing other db work, so make sure your request is willing to wait that long for the response.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;29a15ad0c035c0a0e86e2591660207db64b10777ced76565a695102a481c3dd1&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;note&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;&quot;</span>
<span class="p">}</span>
</code></pre></div></p>
<p><code>status</code> is:</p>
<ul>
<li>1 - File was successfully imported</li>
<li>2 - File already in database</li>
<li>3 - File previously deleted</li>
<li>4 - File failed to import</li>
<li>7 - File vetoed</li>
</ul>
<p>A file 'veto' is caused by the file import options (which in this case is the 'quiet' set under the client's <em>options-&gt;importing</em>) stopping the file due to its resolution or minimum file size rules, etc...</p>
<p>'hash' is the file's SHA256 hash in hexadecimal, and 'note' is any additional human-readable text appropriate to the file status that you may recognise from hydrus's normal import workflow. For an outright import error, it will be a summary of the exception that you can present to the user, and a new field <code>traceback</code> will have the full trace for debugging purposes.</p>
</dd>
</dl>
<h3 id="add_files_delete_files"><strong>POST <code>/add_files/delete_files</code></strong><a class="headerlink" href="#add_files_delete_files" title="Permanent link">&para;</a></h3>
<p><em>Tell the client to send files to the trash.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import Files permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: <code>application/json</code></li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
<li><code>reason</code>: (optional, string, the reason attached to the delete action)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;78f92ba4a786225ee2a1236efa6b7dc81dd729faf4af99f96f3e20bad6d8b538&quot;</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 and no content.</dd>
</dl>
<p>If you specify a file service, the file will only be deleted from that location. Only local file domains are allowed (so you can't delete from a file repository or unpin from ipfs yet). It defaults to 'all my files', which will delete from all local services (i.e. force sending to trash). Sending 'all local files' on a file already in the trash will trigger a physical file delete. </p>
<h3 id="add_files_undelete_files"><strong>POST <code>/add_files/undelete_files</code></strong><a class="headerlink" href="#add_files_undelete_files" title="Permanent link">&para;</a></h3>
<p><em>Tell the client to pull files back out of the trash.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import Files permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;78f92ba4a786225ee2a1236efa6b7dc81dd729faf4af99f96f3e20bad6d8b538&quot;</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 and no content.</dd>
</dl>
<p>You can use hash or hashes, whichever is more convenient.</p>
<p>This is the reverse of a delete_files--removing files from trash and putting them back where they came from. If you specify a file service, the files will only be undeleted to there (if they have a delete record, otherwise this is nullipotent). The default, 'all my files', undeletes to all local file services for which there are deletion records. There is no error if any of the files do not currently exist in 'trash'.</p>
<h3 id="add_files_archive_files"><strong>POST <code>/add_files/archive_files</code></strong><a class="headerlink" href="#add_files_archive_files" title="Permanent link">&para;</a></h3>
<p><em>Tell the client to archive inboxed files.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import Files permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;78f92ba4a786225ee2a1236efa6b7dc81dd729faf4af99f96f3e20bad6d8b538&quot;</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 and no content.</dd>
</dl>
<p>This puts files in the 'archive', taking them out of the inbox. It only has meaning for files currently in 'my files' or 'trash'. There is no error if any files do not currently exist or are already in the archive.</p>
<h3 id="add_files_unarchive_files"><strong>POST <code>/add_files/unarchive_files</code></strong><a class="headerlink" href="#add_files_unarchive_files" title="Permanent link">&para;</a></h3>
<p><em>Tell the client re-inbox archived files.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import Files permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;78f92ba4a786225ee2a1236efa6b7dc81dd729faf4af99f96f3e20bad6d8b538&quot;</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 and no content.</dd>
</dl>
<p>This puts files back in the inbox, taking them out of the archive. It only has meaning for files currently in 'my files' or 'trash'. There is no error if any files do not currently exist or are already in the inbox.</p>
<h2 id="importing_and_editing_urls">Importing and Editing URLs<a class="headerlink" href="#importing_and_editing_urls" title="Permanent link">&para;</a></h2>
<h3 id="add_urls_get_url_files"><strong>GET <code>/add_urls/get_url_files</code></strong><a class="headerlink" href="#add_urls_get_url_files" title="Permanent link">&para;</a></h3>
<p><em>Ask the client about an URL's files.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import URLs permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>url</code>: (the url you want to ask about)</li>
<li><code>doublecheck_file_system</code>: true or false (optional, defaults False)</li>
</ul>
</dd>
<dt>Example request:</dt>
<dd>for URL <code>http://safebooru.org/index.php?page=post&amp;s=view&amp;id=2753608</code>:
<div class="highlight"><pre><span></span><code>/add_urls/get_url_files?url=http%3A%2F%2Fsafebooru.org%2Findex.php%3Fpage%3Dpost%26s%3Dview%26id%3D2753608
</code></pre></div></dd>
<dt>Response:</dt>
<dd>Some JSON which files are known to be mapped to that URL. Note this needs a database hit, so it may be delayed if the client is otherwise busy. Don't rely on this to always be fast.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;normalised_url&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://safebooru.org/index.php?id=2753608&amp;page=post&amp;s=view&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;url_file_statuses&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;20e9002824e5e7ffc240b91b6e4a6af552b3143993c1778fd523c30d9fdde02c&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;note&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;url recognised: Imported at 2015/10/18 10:58:01, which was 3 years 4 months ago (before this check).&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<p>The <code>url_file_statuses</code> is a list of zero-to-n JSON Objects, each representing a file match the client found in its database for the URL. Typically, it will be of length 0 (for as-yet-unvisited URLs or Gallery/Watchable URLs that are not attached to files) or 1, but sometimes multiple files are given the same URL (sometimes by mistaken misattribution, sometimes by design, such as pixiv manga pages). Handling n files per URL is a pain but an unavoidable issue you should account for.</p>
<p><code>status</code> is the same as for <code>/add_files/add_file</code>:</p>
<ul>
<li>0 - File not in database, ready for import (you will only see this very rarely--usually in this case you will just get no matches)</li>
<li>2 - File already in database</li>
<li>3 - File previously deleted</li>
</ul>
<p><code>hash</code> is the file's SHA256 hash in hexadecimal, and 'note' is some occasional additional human-readable text you may recognise from hydrus's normal import workflow.</p>
<p>If you set <code>doublecheck_file_system</code> to <code>true</code>, then any result that is 'already in db' (2) will be double-checked against the actual file system. This check happens on any normal file import process, just to check for and fix missing files (if the file is missing, the status becomes 0--new), but the check can take more than a few milliseconds on an HDD or a network drive, so the default behaviour, assuming you mostly just want to spam for 'seen this before' file statuses, is to not do it. </p>
<h3 id="add_urls_get_url_info"><strong>GET <code>/add_urls/get_url_info</code></strong><a class="headerlink" href="#add_urls_get_url_info" title="Permanent link">&para;</a></h3>
<p><em>Ask the client for information about a URL.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import URLs permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>url</code>: (the url you want to ask about)</li>
</ul>
</dd>
<dt>Example request:</dt>
<dd>for URL <code>https://8ch.net/tv/res/1846574.html</code>:
<div class="highlight"><pre><span></span><code>/add_urls/get_url_info?url=https%3A%2F%2F8ch.net%2Ftv%2Fres%2F1846574.html
</code></pre></div></dd>
<dt>Response:</dt>
<dd>
<p>Some JSON describing what the client thinks of the URL.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;normalised_url&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://8ch.net/tv/res/1846574.html&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;url_type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;url_type_string&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;watchable url&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;match_name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;8chan thread&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;can_parse&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span>
<span class="p">}</span>
</code></pre></div></p>
<p>The url types are currently:</p>
<ul>
<li>0 - Post URL</li>
<li>2 - File URL</li>
<li>3 - Gallery URL</li>
<li>4 - Watchable URL</li>
<li>5 - Unknown URL (i.e. no matching URL Class)</li>
</ul>
<p>'Unknown' URLs are treated in the client as direct File URLs. Even though the 'File URL' type is available, most file urls do not have a URL Class, so they will appear as Unknown. Adding them to the client will pass them to the URL Downloader as a raw file for download and import.</p>
</dd>
</dl>
<h3 id="add_urls_add_url"><strong>POST <code>/add_urls/add_url</code></strong><a class="headerlink" href="#add_urls_add_url" title="Permanent link">&para;</a></h3>
<p><em>Tell the client to 'import' a URL. This triggers the exact same routine as drag-and-dropping a text URL onto the main client window.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import URLs permission needed. Add Tags needed to include tags.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: <code>application/json</code></li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>url</code>: (the url you want to add)</li>
<li><code>destination_page_key</code>: (optional page identifier for the page to receive the url)</li>
<li><code>destination_page_name</code>: (optional page name to receive the url)</li>
<li><code>show_destination_page</code>: (optional, defaulting to false, controls whether the UI will change pages on add)</li>
<li><code>service_keys_to_additional_tags</code>: (optional, selective, tags to give to any files imported from this url)</li>
<li><code>filterable_tags</code>: (optional tags to be filtered by any tag import options that applies to the URL)</li>
</ul>
</dd>
</dl>
<p>If you specify a <code>destination_page_name</code> and an appropriate importer page already exists with that name, that page will be used. Otherwise, a new page with that name will be recreated (and used by subsequent calls with that name). Make sure it that page name is unique (e.g. '/b/ threads', not 'watcher') in your client, or it may not be found.</p>
<p>Alternately, <code>destination_page_key</code> defines exactly which page should be used. Bear in mind this page key is only valid to the current session (they are regenerated on client reset or session reload), so you must figure out which one you want using the <a href="#manage_pages_get_pages">/manage_pages/get_pages</a> call. If the correct page_key is not found, or the page it corresponds to is of the incorrect type, the standard page selection/creation rules will apply.</p>
<p><code>show_destination_page</code> defaults to False to reduce flicker when adding many URLs to different pages quickly. If you turn it on, the client will behave like a URL drag and drop and select the final page the URL ends up on.</p>
<p><code>service_keys_to_additional_tags</code> uses the same data structure as in /add_tags/add_tags--service keys to a list of tags to add. You will need 'add tags' permission or this will 403. These tags work exactly as 'additional' tags work in a <em>tag import options</em>. They are service specific, and always added unless some advanced tag import options checkbox (like 'only add tags to new files') is set.</p>
<p>filterable_tags works like the tags parsed by a hydrus downloader. It is just a list of strings. They have no inherant service and will be sent to a <em>tag import options</em>, if one exists, to decide which tag services get what. This parameter is useful if you are pulling all a URL's tags outside of hydrus and want to have them processed like any other downloader, rather than figuring out service names and namespace filtering on your end. Note that in order for a tag import options to kick in, I think you will have to have a Post URL URL Class hydrus-side set up for the URL so some tag import options (whether that is Class-specific or just the default) can be loaded at import time.</p>
<p><div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;url&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://8ch.net/tv/res/1846574.html&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;destination_page_name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;kino zone&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;service_keys_to_additional_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;as seen on /tv/&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;url&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://safebooru.org/index.php?page=post&amp;s=view&amp;id=3195917&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filterable_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;1girl&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;artist name&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;creator:azto dio&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;blonde hair&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;blue eyes&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;breasts&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;character name&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;commentary&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;english commentary&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;formal&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;full body&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;glasses&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;gloves&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;hair between eyes&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;high heels&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;highres&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;large breasts&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;long hair&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;long sleeves&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;looking at viewer&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;series:metroid&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;mole&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;mole under mouth&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;patreon username&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;ponytail&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;character:samus aran&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;solo&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;standing&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;suit&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;watermark&quot;</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></p>
<dl>
<dt>Response:</dt>
<dd>Some JSON with info on the URL added.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;human_result_text&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;\&quot;https://8ch.net/tv/res/1846574.html\&quot; URL added successfully.&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;normalised_url&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://8ch.net/tv/res/1846574.html&quot;</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<h3 id="add_urls_associate_url"><strong>POST <code>/add_urls/associate_url</code></strong><a class="headerlink" href="#add_urls_associate_url" title="Permanent link">&para;</a></h3>
<p><em>Manage which URLs the client considers to be associated with which files.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Import URLs permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: <code>application/json</code></li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>url_to_add</code>: (optional, selective A, an url you want to associate with the file(s))</li>
<li><code>urls_to_add</code>: (optional, selective A, a list of urls you want to associate with the file(s))</li>
<li><code>url_to_delete</code>: (optional, selective B, an url you want to disassociate from the file(s))</li>
<li><code>urls_to_delete</code>: (optional, selective B, a list of urls you want to disassociate from the file(s))</li>
<li><a href="#parameters_files">files</a></li>
</ul>
<p>The single/multiple arguments work the same--just use whatever is convenient for you. Unless you really know what you are doing with URL Classes, I strongly recommend you stick to associating URLs with just one single 'hash' at a time. Multiple hashes pointing to the same URL is unusual and frequently unhelpful.
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;url_to_add&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://rule34.xxx/index.php?id=2588418&amp;page=post&amp;s=view&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3b820114f658d768550e4e3d4f1dced3ff8db77443472b5ad93700647ad2d3ba&quot;</span>
<span class="p">}</span>
</code></pre></div></p>
</dd>
<dt>Response:</dt>
<dd>200 with no content. Like when adding tags, this is safely idempotent--do not worry about re-adding URLs associations that already exist or accidentally trying to delete ones that don't.</dd>
</dl>
<h2 id="editing_file_tags">Editing File Tags<a class="headerlink" href="#editing_file_tags" title="Permanent link">&para;</a></h2>
<h3 id="add_tags_clean_tags"><strong>GET <code>/add_tags/clean_tags</code></strong><a class="headerlink" href="#add_tags_clean_tags" title="Permanent link">&para;</a></h3>
<p><em>Ask the client about how it will see certain tags.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Add Tags permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><code>tags</code>: (a list of the tags you want cleaned)</li>
</ul>
</dd>
<dt>Example request:</dt>
<dd>Given tags <code class="highlight"><span class="p">[</span><span class="w"> </span><span class="s2">&quot; bikini &quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;blue eyes&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot; character : samus aran &quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot; :)&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot; &quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;10&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;11&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;9&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;system:wew&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;-flower&quot;</span><span class="w"> </span><span class="p">]</span></code>:
<div class="highlight"><pre><span></span><code>/add_tags/clean_tags?tags=%5B%22%20bikini%20%22%2C%20%22blue%20%20%20%20eyes%22%2C%20%22%20character%20%3A%20samus%20aran%20%22%2C%20%22%3A%29%22%2C%20%22%20%20%20%22%2C%20%22%22%2C%20%2210%22%2C%20%2211%22%2C%20%229%22%2C%20%22system%3Awew%22%2C%20%22-flower%22%5D
</code></pre></div></dd>
<dt>Response:</dt>
<dd>
<p>The tags cleaned according to hydrus rules. They will also be in hydrus human-friendly sorting order.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;9&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;10&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;11&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot; ::)&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;bikini&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;blue eyes&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;character:samus aran&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;flower&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;wew&quot;</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></p>
<p>Mostly, hydrus simply trims excess whitespace, but the other examples are rare issues you might run into. 'system' is an invalid namespace, tags cannot be prefixed with hyphens, and any tag starting with ':' is secretly dealt with internally as "[no namespace]:[colon-prefixed-subtag]". Again, you probably won't run into these, but if you see a mismatch somewhere and want to figure it out, or just want to sort some numbered tags, you might like to try this.</p>
</dd>
</dl>
<h3 id="add_tags_get_siblings_and_parents"><strong>GET <code>/add_tags/get_siblings_and_parents</code></strong><a class="headerlink" href="#add_tags_get_siblings_and_parents" title="Permanent link">&para;</a></h3>
<p><em>Ask the client about tags' sibling and parent relationships.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Add Tags permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><code>tags</code>: (a list of the tags you want info on)</li>
</ul>
</dd>
<dt>Example request:</dt>
<dd>Given tags <code class="highlight"><span class="p">[</span><span class="w"> </span><span class="s2">&quot;blue eyes&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;samus aran&quot;</span><span class="w"> </span><span class="p">]</span></code>:
<div class="highlight"><pre><span></span><code>/add_tags/get_siblings_and_parents?tags=%5B%22blue%20eyes%22%2C%20%22samus%20aran%22%5D
</code></pre></div></dd>
<dt>Response:</dt>
<dd>
<p>An Object showing all the display relationships for each tag on each service. Also <a href="#services_object">The Services Object</a>.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;services&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="nt">&quot;The Services Object&quot;</span>
<span class="w"> </span><span class="nt">&quot;tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;blue eyes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;ideal_tag&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;blue eyes&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;siblings&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;blue eyes&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;blue_eyes&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;blue eye&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;blue_eye&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;descendants&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[],</span>
<span class="w"> </span><span class="nt">&quot;ancestors&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[]</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;877bfcf81f56e7e3e4bc3f8d8669f92290c140ba0acfd6c7771c5e1dc7be62d7&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;ideal_tag&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;blue eyes&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;siblings&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;blue eyes&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;descendants&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[],</span>
<span class="w"> </span><span class="nt">&quot;ancestors&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;samus aran&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;ideal_tag&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;character:samus aran&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;siblings&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;samus aran&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;samus_aran&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;character:samus aran&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;descendants&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;character:samus aran (zero suit)&quot;</span>
<span class="w"> </span><span class="s2">&quot;cosplay:samus aran&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;ancestors&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;series:metroid&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;studio:nintendo&quot;</span>
<span class="w"> </span><span class="p">]</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;877bfcf81f56e7e3e4bc3f8d8669f92290c140ba0acfd6c7771c5e1dc7be62d7&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;ideal_tag&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;samus aran&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;siblings&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;samus aran&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;descendants&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;zero suit samus&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;samus_aran_(cosplay)&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;ancestors&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></p>
<p>This data is essentially how mappings in the <code>storage</code> <code>tag_display_type</code> become <code>display</code>.</p>
<p>The hex keys are the service keys, which you will have seen elsewhere, like <a href="#get_files_file_metadata">GET /get_files/file_metadata</a>. Note that there is no concept of 'all known tags' here. If a tag is in 'my tags', it follows the rules of 'my tags', and then all the services' display tags are merged into the 'all known tags' pool for user display.</p>
<p><strong>Also, the siblings and parents here are not just what is in <em>tags-&gt;manage tag siblings/parents</em>, they are the final computed combination of rules as set in <em>tags-&gt;manage where tag siblings and parents apply</em>.</strong> The data given here is not guaranteed to be useful for editing siblings and parents on a particular service. That data, which is currently pair-based, will appear in a different API request in future.</p>
<ul>
<li><code>ideal_tag</code> is how the tag appears in normal display to the user.</li>
<li><code>siblings</code> is every tag that will show as the <code>ideal_tag</code>, including the <code>ideal_tag</code> itself.</li>
<li><code>descendants</code> is every child (and recursive grandchild, great-grandchild...) that implies the <code>ideal_tag</code>.</li>
<li><code>ancestors</code> is every parent (and recursive grandparent, great-grandparent...) that our tag implies.</li>
</ul>
<p>Every descendant and ancestor is an <code>ideal_tag</code> itself that may have its own siblings.</p>
<p>Most situations are simple, but remember that siblings and parents in hydrus can get complex. If you want to display this data, I recommend you plan to support simple service-specific workflows, and add hooks to recognise conflicts and other difficulty and, when that happens, abandon ship (send the user back to Hydrus proper). Also, if you show summaries of the data anywhere, make sure you add a 'and 22 more...' overflow mechanism to your menus, since if you hit up 'azur lane' or 'pokemon', you are going to get hundreds of children.</p>
<p>I generally warn you off computing sibling and parent mappings or counts yourself. The data from this request is best used for sibling and parent decorators on individual tags in a 'manage tags' presentation. The code that actually computes what siblings and parents look like in the 'display' context can be a pain at times, and I've already done it. Just run /search_tags or /file_metadata again after any changes you make and you'll get updated values.</p>
</dd>
</dl>
<h3 id="add_tags_search_tags"><strong>GET <code>/add_tags/search_tags</code></strong><a class="headerlink" href="#add_tags_search_tags" title="Permanent link">&para;</a></h3>
<p><em>Search the client for tags.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Search for Files and Add Tags permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>search</code>: (the tag text to search for, enter exactly what you would in the client UI)</li>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
<li><code>tag_service_key</code>: (optional, hexadecimal, the tag domain on which to search, defaults to 'all known tags')</li>
<li><code>tag_display_type</code>: (optional, string, to select whether to search raw or sibling-processed tags, defaults to 'storage')</li>
</ul>
</dd>
</dl>
<p>The <code>file domain</code> and <code>tag_service_key</code> perform the function of the file and tag domain buttons in the client UI.</p>
<p>The <code>tag_display_type</code> can be either <code>storage</code> (the default), which searches your file's stored tags, just as they appear in a 'manage tags' dialog, or <code>display</code>, which searches the sibling-processed tags, just as they appear in a normal file search page. In the example above, setting the <code>tag_display_type</code> to <code>display</code> could well combine the two kim possible tags and give a count of 3 or 4. </p>
<p>'all my files'/'all known tags' works fine for most cases, but a specific tag service or 'all known files'/'tag service' can work better for editing tag repository <code>storage</code> contexts, since it provides results just for that service, and for repositories, it gives tags for all the non-local files other users have tagged.</p>
<dl>
<dt>Example request:</dt>
<dd><div class="highlight"><span class="filename">Example request</span><pre><span></span><code><span class="err">/add_tags/search_tags?search=kim&amp;tag_display_type=display</span>
</code></pre></div></dd>
<dt>Response:</dt>
<dd>Some JSON listing the client's matching tags.</dd>
<dd><div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;series:kim possible&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;count&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">3</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;kimchee&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;count&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">2</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;character:kimberly ann possible&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;count&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<p>The <code>tags</code> list will be sorted by descending count. The various rules in <em>tags-&gt;manage tag display and search</em> (e.g. no pure <code>*</code> searches on certain services) will also be checked--and if violated, you will get 200 OK but an empty result.</p>
<p>Note that if your client api access is only allowed to search certain tags, the results will be similarly filtered.</p>
<h3 id="add_tags_add_tags"><strong>POST <code>/add_tags/add_tags</code></strong><a class="headerlink" href="#add_tags_add_tags" title="Permanent link">&para;</a></h3>
<p><em>Make changes to the tags that files have.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Add Tags permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
<li><code>service_keys_to_tags</code>: (selective B, an Object of service keys to lists of tags to be 'added' to the files)</li>
<li><code>service_keys_to_actions_to_tags</code>: (selective B, an Object of service keys to content update actions to lists of tags)</li>
</ul>
<p>In 'service_keys_to...', the keys are as in <a href="#get_services">/get_services</a>. You may need some selection UI on your end so the user can pick what to do if there are multiple choices.</p>
<p>Also, you can use either '...to_tags', which is simple and add-only, or '...to_actions_to_tags', which is more complicated and allows you to remove/petition or rescind pending content.</p>
<p>The permitted 'actions' are:</p>
<ul>
<li>0 - Add to a local tag service.</li>
<li>1 - Delete from a local tag service.</li>
<li>2 - Pend to a tag repository.</li>
<li>3 - Rescind a pend from a tag repository.</li>
<li>4 - Petition from a tag repository. (This is special)</li>
<li>5 - Rescind a petition from a tag repository.</li>
</ul>
<p>When you petition a tag from a repository, a 'reason' for the petition is typically needed. If you send a normal list of tags here, a default reason of "Petitioned from API" will be given. If you want to set your own reason, you can instead give a list of [ tag, reason ] pairs.</p>
</dd>
<dt>Some example requests:</dt>
<dd>
<p><div class="highlight"><span class="filename">Adding some tags to a file</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;df2a7b286d21329fc496e3aa8b8a08b67bb1747ca32749acb3f5d544cbfc0f56&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;service_keys_to_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;character:supergirl&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;rating:safe&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<div class="highlight"><span class="filename">Adding more tags to two files</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hashes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;df2a7b286d21329fc496e3aa8b8a08b67bb1747ca32749acb3f5d544cbfc0f56&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;f2b022214e711e9a11e2fcec71bfd524f10f0be40c250737a7861a5ddd3faebf&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;service_keys_to_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;process this&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;ccb0cf2f9e92c2eb5bd40986f72a339ef9497014a5fb8ce4cea6d6c9837877d9&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;creator:dandon fuga&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<div class="highlight"><span class="filename">A complicated transaction with all possible actions</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;df2a7b286d21329fc496e3aa8b8a08b67bb1747ca32749acb3f5d544cbfc0f56&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;service_keys_to_actions_to_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;0&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;character:supergirl&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;rating:safe&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;1&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;character:superman&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;aa0424b501237041dab0308c02c35454d377eebd74cfbc5b9d7b3e16cc2193e9&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;2&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;character:supergirl&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;rating:safe&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;3&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;filename:image.jpg&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;4&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[[</span><span class="s2">&quot;creator:danban faga&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;typo&quot;</span><span class="p">],</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;character:super_girl&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;underscore&quot;</span><span class="p">]],</span>
<span class="w"> </span><span class="nt">&quot;5&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;skirt&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></p>
<p>This last example is far more complicated than you will usually see. Pend rescinds and petition rescinds are not common. Petitions are also quite rare, and gathering a good petition reason for each tag is often a pain.</p>
<p>Note that the enumerated status keys in the service_keys_to_actions_to_tags structure are strings, not ints (JSON does not support int keys for Objects).</p>
</dd>
<dt>Response description:</dt>
<dd>200 and no content.</dd>
</dl>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Note also that hydrus tag actions are safely idempotent. You can pend a tag that is already pended, or add a tag that already exists, and not worry about an error--the surplus add action will be discarded. The same is true if you try to pend a tag that actually already exists, or rescinding a petition that doesn't. Any invalid actions will fail silently.</p>
<p>It is fine to just throw your 'process this' tags at every file import and not have to worry about checking which files you already added them to.</p>
</div>
<div class="admonition danger">
<p class="admonition-title">HOWEVER</p>
<p>When you delete a tag, a deletion record is made <em>even if the tag does not exist on the file</em>. This is important if you expect to add the tags again via parsing, because, in general, when hydrus adds tags through a downloader, it will not overwrite a previously 'deleted' tag record (this is to stop re-downloads overwriting the tags you hand-removed previously). Undeletes usually have to be done manually by a human. </p>
<p>So, <em>do</em> be careful about how you spam delete unless it is something that doesn't matter or it is something you'll only be touching again via the API anyway.</p>
</div>
<h2 id="editing_file_ratings">Editing File Ratings<a class="headerlink" href="#editing_file_ratings" title="Permanent link">&para;</a></h2>
<h3 id="edit_ratings_set_rating"><strong>POST <code>/edit_ratings/set_rating</code></strong><a class="headerlink" href="#edit_ratings_set_rating" title="Permanent link">&para;</a></h3>
<p><em>Add or remove ratings associated with a file.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Edit Ratings permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: <code>application/json</code></li>
</ul>
</dd>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
<li><code>rating_service_key</code> : (hexadecimal, the rating service you want to edit)</li>
<li><code>rating</code> : (mixed datatype, the rating value you want to set)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3b820114f658d768550e4e3d4f1dced3ff8db77443472b5ad93700647ad2d3ba&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;rating_service_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;282303611ba853659aa60aeaa5b6312d40e05b58822c52c57ae5e320882ba26e&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;rating&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">2</span>
<span class="p">}</span>
</code></pre></div>
<p>This is fairly simple, but there are some caveats around the different rating service types and the actual data you are setting here. It is the same as you'll see in <a href="#get_files_file_metadata">GET /get_files/file_metadata</a>. </p>
<h4 id="likedislike_ratings">Like/Dislike Ratings<a class="headerlink" href="#likedislike_ratings" title="Permanent link">&para;</a></h4>
<p>Send <code>true</code> for 'like', <code>false</code> for 'dislike', or <code>null</code> for 'unset'.</p>
<h4 id="numerical_ratings">Numerical Ratings<a class="headerlink" href="#numerical_ratings" title="Permanent link">&para;</a></h4>
<p>Send an <code>int</code> for the number of stars to set, or <code>null</code> for 'unset'.</p>
<h4 id="incdec_ratings">Inc/Dec Ratings<a class="headerlink" href="#incdec_ratings" title="Permanent link">&para;</a></h4>
<p>Send an <code>int</code> for the number to set. 0 is your minimum.</p>
<p>As with <a href="#get_files_file_metadata">GET /get_files/file_metadata</a>, check <a href="#services_object">The Services Object</a> for the min/max stars on a numerical rating service. </p>
<dl>
<dt>Response:</dt>
<dd>200 and no content.</dd>
</dl>
<h2 id="editing_file_notes">Editing File Notes<a class="headerlink" href="#editing_file_notes" title="Permanent link">&para;</a></h2>
<h3 id="add_notes_set_notes"><strong>POST <code>/add_notes/set_notes</code></strong><a class="headerlink" href="#add_notes_set_notes" title="Permanent link">&para;</a></h3>
<p><em>Add or update notes associated with a file.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Add Notes permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: <code>application/json</code></li>
</ul>
</dd>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><code>notes</code>: (an Object mapping string names to string texts)</li>
<li><code>hash</code>: (selective, an SHA256 hash for the file in 64 characters of hexadecimal)</li>
<li><code>file_id</code>: (selective, the integer numerical identifier for the file)</li>
<li><code>merge_cleverly</code>: true or false (optional, defaults false)</li>
<li><code>extend_existing_note_if_possible</code>: true or false (optional, defaults true)</li>
<li><code>conflict_resolution</code>: 0, 1, 2, or 3 (optional, defaults 3)</li>
</ul>
</dd>
</dl>
<p>With <code>merge_cleverly</code> left <code>false</code>, then this is a simple update operation. Existing notes will be overwritten exactly as you specify. Any other notes the file has will be untouched.
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;notes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;note name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;content of note&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;another note&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;asdf&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3b820114f658d768550e4e3d4f1dced3ff8db77443472b5ad93700647ad2d3ba&quot;</span>
<span class="p">}</span>
</code></pre></div></p>
<p>If you turn on <code>merge_cleverly</code>, then the client will merge your new notes into the file's existing notes using the same logic you have seen in Note Import Options and the Duplicate Metadata Merge Options. This navigates conflict resolution, and you should use it if you are adding potential duplicate content from an 'automatic' source like a parser and do not want to wade into the logic. Do not use it for a user-editing experience (a user expects a strict overwrite/replace experience and will be confused by this mode).</p>
<p>To start off, in this mode, if your note text exists under a different name for the file, your dupe note will not be added to your new name. <code>extend_existing_note_if_possible</code> makes it so your existing note text will overwrite an existing name (or a '... (1)' rename of that name) if the existing text is inside your given text. <code>conflict_resolution</code> is an enum governing what to do in all other conflicts:</p>
<dl>
<dt><em>If a new note name already exists and its new text differs from what already exists:</em></dt>
<dd>
<ul>
<li>0 - replace - Overwrite the existing conflicting note.</li>
<li>1 - ignore - Make no changes.</li>
<li>2 - append - Append the new text to the existing text.</li>
<li>3 - rename (default) - Add the new text under a 'name (x)'-style rename.</li>
</ul>
</dd>
<dt>Response:</dt>
<dd>200 with the note changes actually sent through. If <code>merge_cleverly=false</code>, this is exactly what you gave, and this operation is idempotent. If <code>merge_cleverly=true</code>, then this may differ, even be empty, and this operation might not be idempotent.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;notes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;note name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;content of note&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;another note (1)&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;asdf&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<h3 id="add_notes_delete_notes"><strong>POST <code>/add_notes/delete_notes</code></strong><a class="headerlink" href="#add_notes_delete_notes" title="Permanent link">&para;</a></h3>
<p><em>Remove notes associated with a file.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Add Notes permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: <code>application/json</code></li>
</ul>
</dd>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><code>note_names</code>: (a list of string note names to delete)</li>
<li><code>hash</code>: (selective, an SHA256 hash for the file in 64 characters of hexadecimal)</li>
<li><code>file_id</code>: (selective, the integer numerical identifier for the file)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;note_names&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;note name&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;another note&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3b820114f658d768550e4e3d4f1dced3ff8db77443472b5ad93700647ad2d3ba&quot;</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 with no content. This operation is idempotent.</dd>
</dl>
<h2 id="searching_and_fetching_files">Searching and Fetching Files<a class="headerlink" href="#searching_and_fetching_files" title="Permanent link">&para;</a></h2>
<p>File search in hydrus is not paginated like a booru--all searches return all results in one go. In order to keep this fast, search is split into two steps--fetching file identifiers with a search, and then fetching file metadata in batches. You may have noticed that the client itself performs searches like this--thinking a bit about a search and then bundling results in batches of 256 files before eventually throwing all the thumbnails on screen.</p>
<h3 id="get_files_search_files"><strong>GET <code>/get_files/search_files</code></strong><a class="headerlink" href="#get_files_search_files" title="Permanent link">&para;</a></h3>
<p><em>Search for the client's files.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Search for Files permission needed. Additional search permission limits may apply.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><code>tags</code>: (a list of tags you wish to search for)</li>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
<li><code>tag_service_key</code>: (optional, hexadecimal, the tag domain on which to search, defaults to 'all my files')</li>
<li><code>file_sort_type</code>: (optional, integer, the results sort method, defaults to 'all known tags')</li>
<li><code>file_sort_asc</code>: true or false (optional, the results sort order)</li>
<li><code>return_file_ids</code>: true or false (optional, default true, returns file id results)</li>
<li><code>return_hashes</code>: true or false (optional, default false, returns hex hash results)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request for 16 files (system:limit=16) in the inbox with tags "blue eyes", "blonde hair", and "кино"</span><pre><span></span><code>/get_files/search_files?tags=%5B%22blue%20eyes%22%2C%20%22blonde%20hair%22%2C%20%22%5Cu043a%5Cu0438%5Cu043d%5Cu043e%22%2C%20%22system%3Ainbox%22%2C%20%22system%3Alimit%3D16%22%5D
</code></pre></div>
<p>If the access key's permissions only permit search for certain tags, at least one positive whitelisted/non-blacklisted tag must be in the "tags" list or this will 403. Tags can be prepended with a hyphen to make a negated tag (e.g. "-green eyes"), but these will not be checked against the permissions whitelist.</p>
<p>Wildcards and namespace searches are supported, so if you search for 'character:sam*' or 'series:*', this will be handled correctly clientside.</p>
<p><strong>Many system predicates are also supported using a text parser!</strong> The parser was designed by a clever user for human input and allows for a certain amount of error (e.g. ~= instead of ≈, or "isn't" instead of "is not") or requires more information (e.g. the specific hashes for a hash lookup). <strong>Here's a big list of examples that are supported:</strong></p>
<details class="example">
<summary>System Predicates</summary>
<ul>
<li>system:everything</li>
<li>system:inbox</li>
<li>system:archive</li>
<li>system:has duration</li>
<li>system:no duration</li>
<li>system:is the best quality file of its duplicate group</li>
<li>system:is not the best quality file of its duplicate group</li>
<li>system:has audio</li>
<li>system:no audio</li>
<li>system:has exif</li>
<li>system:no exif</li>
<li>system:has human-readable embedded metadata</li>
<li>system:no human-readable embedded metadata</li>
<li>system:has icc profile</li>
<li>system:no icc profile</li>
<li>system:has tags</li>
<li>system:no tags</li>
<li>system:untagged</li>
<li>system:number of tags &gt; 5</li>
<li>system:number of tags ~= 10</li>
<li>system:number of tags &gt; 0</li>
<li>system:number of words &lt; 2</li>
<li>system:height = 600</li>
<li>system:height &gt; 900</li>
<li>system:width &lt; 200</li>
<li>system:width &gt; 1000</li>
<li>system:filesize ~= 50 kilobytes</li>
<li>system:filesize &gt; 10megabytes</li>
<li>system:filesize &lt; 1 GB</li>
<li>system:filesize &gt; 0 B</li>
<li>system:similar to abcdef01 abcdef02 abcdef03, abcdef04 with distance 3</li>
<li>system:similar to abcdef distance 5</li>
<li>system:limit = 100</li>
<li>system:filetype = image/jpg, image/png, apng</li>
<li>system:hash = abcdef01 abcdef02 abcdef03 <em>(this does sha256)</em></li>
<li>system:hash = abcdef01 abcdef02 md5</li>
<li>system:modified date &lt; 7 years 45 days 7h</li>
<li>system:modified date &gt; 2011-06-04</li>
<li>system:last viewed time &lt; 7 years 45 days 7h</li>
<li>system:last view time &lt; 7 years 45 days 7h</li>
<li>system:date modified &gt; 7 years 2 months</li>
<li>system:date modified &lt; 0 years 1 month 1 day 1 hour</li>
<li>system:import time &lt; 7 years 45 days 7h</li>
<li>system:time imported &lt; 7 years 45 days 7h</li>
<li>system:time imported &gt; 2011-06-04</li>
<li>system:time imported &gt; 7 years 2 months</li>
<li>system:time imported &lt; 0 years 1 month 1 day 1 hour</li>
<li>system:time imported ~= 2011-1-3</li>
<li>system:time imported ~= 1996-05-2</li>
<li>system:duration &lt; 5 seconds</li>
<li>system:duration ~= 600 msecs</li>
<li>system:duration &gt; 3 milliseconds</li>
<li>system:file service is pending to my files</li>
<li>system:file service currently in my files</li>
<li>system:file service is not currently in my files</li>
<li>system:file service is not pending to my files</li>
<li>system:number of file relationships = 2 duplicates</li>
<li>system:number of file relationships &gt; 10 potential duplicates</li>
<li>system:num file relationships &lt; 3 alternates</li>
<li>system:num file relationships &gt; 3 false positives</li>
<li>system:ratio is wider than 16:9</li>
<li>system:ratio is 16:9</li>
<li>system:ratio taller than 1:1</li>
<li>system:num pixels &gt; 50 px</li>
<li>system:num pixels &lt; 1 megapixels</li>
<li>system:num pixels ~= 5 kilopixel</li>
<li>system:media views ~= 10</li>
<li>system:all views &gt; 0</li>
<li>system:preview views &lt; 10</li>
<li>system:media viewtime &lt; 1 days 1 hour 0 minutes</li>
<li>system:all viewtime &gt; 1 hours 100 seconds</li>
<li>system:preview viewtime ~= 1 day 30 hours 100 minutes 90s</li>
<li>system:has url matching regex index\.php</li>
<li>system:does not have a url matching regex index\.php</li>
<li>system:has url https://safebooru.donmai.us/posts/4695284</li>
<li>system:does not have url https://safebooru.donmai.us/posts/4695284</li>
<li>system:has domain safebooru.com</li>
<li>system:does not have domain safebooru.com</li>
<li>system:has a url with class safebooru file page</li>
<li>system:does not have a url with url class safebooru file page</li>
<li>system:tag as number page &lt; 5</li>
<li>system:has notes</li>
<li>system:no notes</li>
<li>system:does not have notes</li>
<li>system:num notes is 5</li>
<li>system:num notes &gt; 1</li>
<li>system:has note with name note name</li>
<li>system:no note with name note name</li>
<li>system:does not have note with name note name</li>
<li>system:has a rating for <code>service_name</code></li>
<li>system:does not have a rating for <code>service_name</code></li>
<li>system:rating for <code>service_name</code> &gt; &#8535; (numerical services)</li>
<li>system:rating for <code>service_name</code> is like (like/dislike services)</li>
<li>system:rating for <code>service_name</code> = 13 (inc/dec services)</li>
</ul>
</details>
<p>Please test out the system predicates you want to send. If you are in <em>help-&gt;advanced mode</em>, you can test this parser in the advanced text input dialog when you click the OR* button on a tag autocomplete dropdown. More system predicate types and input formats will be available in future. Reverse engineering system predicate data from text is obviously tricky. If a system predicate does not parse, you'll get 400.</p>
<p>Also, OR predicates are now supported! Just nest within the tag list, and it'll be treated like an OR. For instance:</p>
<ul>
<li><code class="highlight"><span class="p">[</span><span class="w"> </span><span class="s2">&quot;skirt&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&quot;samus aran&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;lara croft&quot;</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">&quot;system:height &gt; 1000&quot;</span><span class="w"> </span><span class="p">]</span></code></li>
</ul>
<p>Makes:</p>
<ul>
<li>skirt</li>
<li>samus aran OR lara croft</li>
<li>system:height &gt; 1000</li>
</ul>
<p>The file and tag services are for search domain selection, just like clicking the buttons in the client. They are optional--default is 'all my files' and 'all known tags'. </p>
<p>File searches occur in the <code>display</code> <code>tag_display_type</code>. If you want to pair autocomplete tag lookup from <a href="#add_tags_search_tags">/search_tags</a> to this file search (e.g. for making a standard booru search interface), then make sure you are searching <code>display</code> tags there.</p>
<p>file_sort_asc is 'true' for ascending, and 'false' for descending. The default is descending.</p>
<p>file_sort_type is by default <em>import time</em>. It is an integer according to the following enum, and I have written the semantic (asc/desc) meaning for each type after:</p>
<ul>
<li>0 - file size (smallest first/largest first)</li>
<li>1 - duration (shortest first/longest first)</li>
<li>2 - import time (oldest first/newest first)</li>
<li>3 - filetype (N/A)</li>
<li>4 - random (N/A)</li>
<li>5 - width (slimmest first/widest first)</li>
<li>6 - height (shortest first/tallest first)</li>
<li>7 - ratio (tallest first/widest first)</li>
<li>8 - number of pixels (ascending/descending)</li>
<li>9 - number of tags (on the current tag domain) (ascending/descending)</li>
<li>10 - number of media views (ascending/descending)</li>
<li>11 - total media viewtime (ascending/descending)</li>
<li>12 - approximate bitrate (smallest first/largest first)</li>
<li>13 - has audio (audio first/silent first)</li>
<li>14 - modified time (oldest first/newest first)</li>
<li>15 - framerate (slowest first/fastest first)</li>
<li>16 - number of frames (smallest first/largest first)</li>
<li>18 - last viewed time (oldest first/newest first)</li>
<li>19 - archive timestamp (oldest first/newest first)</li>
<li>20 - hash hex (N/A)</li>
</ul>
<dl>
<dt>Response:</dt>
<dd>
<p>The full list of numerical file ids that match the search.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_ids&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">125462</span><span class="p">,</span><span class="w"> </span><span class="mi">4852415</span><span class="p">,</span><span class="w"> </span><span class="mi">123</span><span class="p">,</span><span class="w"> </span><span class="mi">591415</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<div class="highlight"><span class="filename">Example response with return_hashes=true</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hashes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;1b04c4df7accd5a61c5d02b36658295686b0abfebdc863110e7d7249bba3f9ad&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;fe416723c731d679aa4d20e9fd36727f4a38cd0ac6d035431f0f452fad54563f&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;b53505929c502848375fbc4dab2f40ad4ae649d34ef72802319a348f81b52bad&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;file_ids&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">125462</span><span class="p">,</span><span class="w"> </span><span class="mi">4852415</span><span class="p">,</span><span class="w"> </span><span class="mi">123</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></p>
<p>You can of course also specify <code>return_hashes=true&amp;return_file_ids=false</code> just to get the hashes. The order of both lists is the same.</p>
<p>File ids are internal and specific to an individual client. For a client, a file with hash H always has the same file id N, but two clients will have different ideas about which N goes with which H. IDs are a bit faster to retrieve than hashes and search with <em>en masse</em>, which is why they are exposed here.</p>
<p>This search does <strong>not</strong> apply the implicit limit that most clients set to all searches (usually 10,000), so if you do system:everything on a client with millions of files, expect to get boshed. Even with a system:limit included, complicated queries with large result sets may take several seconds to respond. Just like the client itself.</p>
</dd>
</dl>
<h3 id="get_files_file_hashes"><strong>GET <code>/get_files/file_hashes</code></strong><a class="headerlink" href="#get_files_file_hashes" title="Permanent link">&para;</a></h3>
<p><em>Lookup file hashes from other hashes.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Search for Files permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><code>hash</code>: (selective, a hexadecimal hash)</li>
<li><code>hashes</code>: (selective, a list of hexadecimal hashes)</li>
<li><code>source_hash_type</code>: [sha256|md5|sha1|sha512] (optional, defaulting to sha256)</li>
<li><code>desired_hash_type</code>: [sha256|md5|sha1|sha512]</li>
</ul>
</dd>
</dl>
<p>If you have some MD5 hashes and want to see what their SHA256 are, or <em>vice versa</em>, this is the place. Hydrus records the non-SHA256 hashes for every file it has ever imported. This data is not removed on file deletion.</p>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/get_files/file_hashes?hash=ec5c5a4d7da4be154597e283f0b6663c&amp;source_hash_type=md5&amp;desired_hash_type=sha256
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>A mapping Object of the successful lookups. Where no matching hash is found, no entry will be made (therefore, if none of your source hashes have matches on the client, this will return an empty <code>hashes</code> Object).
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hashes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;ec5c5a4d7da4be154597e283f0b6663c&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2a0174970defa6f147f2eabba829c5b05aba1f1aea8b978611a07b7bb9cf9399&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<h3 id="get_files_file_metadata"><strong>GET <code>/get_files/file_metadata</code></strong><a class="headerlink" href="#get_files_file_metadata" title="Permanent link">&para;</a></h3>
<p><em>Get metadata about files in the client.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Search for Files permission needed. Additional search permission limits may apply.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
<li><code>create_new_file_ids</code>: true or false (optional if asking with hash(es), defaulting to false)</li>
<li><code>only_return_identifiers</code>: true or false (optional, defaulting to false)</li>
<li><code>only_return_basic_information</code>: true or false (optional, defaulting to false)</li>
<li><code>detailed_url_information</code>: true or false (optional, defaulting to false)</li>
<li><code>include_blurhash</code>: true or false (optional, defaulting to false. Only applies when <code>only_return_basic_information</code> is true)</li>
<li><code>include_notes</code>: true or false (optional, defaulting to false)</li>
<li><code>include_services_object</code>: true or false (optional, defaulting to true)</li>
<li><code>hide_service_keys_tags</code>: <strong>Deprecated, will be deleted soon!</strong> true or false (optional, defaulting to true)</li>
</ul>
</dd>
</dl>
<p>If your access key is restricted by tag, <strong>the files you search for must have been in the most recent search result</strong>.</p>
<div class="highlight"><span class="filename">Example request for two files with ids 123 and 4567</span><pre><span></span><code>/get_files/file_metadata?file_ids=%5B123%2C%204567%5D
</code></pre></div>
<div class="highlight"><span class="filename">The same, but only wants hashes back</span><pre><span></span><code>/get_files/file_metadata?file_ids=%5B123%2C%204567%5D&amp;only_return_identifiers=true
</code></pre></div>
<div class="highlight"><span class="filename">And one that fetches two hashes</span><pre><span></span><code>/get_files/file_metadata?hashes=%5B%224c77267f93415de0bc33b7725b8c331a809a924084bee03ab2f5fae1c6019eb2%22%2C%20%223e7cb9044fe81bda0d7a84b5cb781cba4e255e4871cba6ae8ecd8207850d5b82%22%5D
</code></pre></div>
<p>This request string can obviously get pretty ridiculously long. It also takes a bit of time to fetch metadata from the database. In its normal searches, the client usually fetches file metadata in batches of 256.</p>
<dl>
<dt>Response:</dt>
<dd>A list of JSON Objects that store a variety of file metadata. Also <a href="#services_object">The Services Object</a> for service reference.</dd>
</dl>
<p><div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;services&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;The Services Object&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;metadata&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_id&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">123</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;4c77267f93415de0bc33b7725b8c331a809a924084bee03ab2f5fae1c6019eb2&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;size&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">63405</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;mime&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;image/jpeg&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filetype_human&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;jpeg&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filetype_enum&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;ext&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;.jpg&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;width&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">640</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;height&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">480</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;thumbnail_width&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;thumbnail_height&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">150</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;duration&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;time_modified&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;time_modified_details&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{},</span>
<span class="w"> </span><span class="nt">&quot;file_services&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;current&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{},</span>
<span class="w"> </span><span class="nt">&quot;deleted&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;ipfs_multihashes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{},</span>
<span class="w"> </span><span class="nt">&quot;has_audio&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;blurhash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;U6PZfSi_.AyE_3t7t7R**0o#DgR4_3R*D%xt&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;pixel_hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2519e40f8105599fcb26187d39656b1b46f651786d0e32fff2dc5a9bc277b5bb&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_frames&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_words&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;is_inbox&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;is_local&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;is_trashed&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;is_deleted&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;has_exif&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;has_human_readable_embedded_metadata&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;has_icc_profile&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;known_urls&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[],</span>
<span class="w"> </span><span class="nt">&quot;ratings&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;74d52c6238d25f846d579174c11856b1aaccdb04a185cb2c79f0d0e499284f2c&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;90769255dae5c205c975fc4ce2efff796b8be8a421f786c1737f87f98187ffaf&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;b474e0cbbab02ca1479c12ad985f1c680ea909a54eb028e3ad06750ea40d4106&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;storage_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{},</span>
<span class="w"> </span><span class="nt">&quot;display_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;37e3849bda234f53b0e9792a036d14d4f3a9a136d1cb939705dbcd5287941db4&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;storage_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{},</span>
<span class="w"> </span><span class="nt">&quot;display_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;616c6c206b6e6f776e2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;storage_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{},</span>
<span class="w"> </span><span class="nt">&quot;display_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_id&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4567</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3e7cb9044fe81bda0d7a84b5cb781cba4e255e4871cba6ae8ecd8207850d5b82&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;size&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">199713</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;mime&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;video/webm&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filetype_human&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;webm&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filetype_enum&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">21</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;ext&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;.webm&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;width&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1920</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;height&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1080</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;thumbnail_width&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;thumbnail_height&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">113</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;duration&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4040</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;time_modified&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1604055647</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;time_modified_details&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;local&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1641044491</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;gelbooru.com&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1604055647</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;file_services&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;current&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;616c6c206c6f63616c2066696c6573&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;time_imported&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1641044491</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;616c6c206c6f63616c206d65646961&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;time_imported&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1641044491</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;cb072cffbd0340b67aec39e1953c074e7430c2ac831f8e78fb5dfbda6ec8dcbd&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;time_imported&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1641204220</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;deleted&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2066696c6573&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;time_deleted&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1641204274</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;time_imported&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1641044491</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;ipfs_multihashes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;55af93e0deabd08ce15ffb2b164b06d1254daab5a18d145e56fa98f71ddb6f11&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;QmReHtaET3dsgh7ho5NVyHb5U13UgJoGipSWbZsnuuM8tb&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;has_audio&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;blurhash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;UHF5?xYk^6#M@-5b,1J5@[or[k6.};FxngOZ&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;pixel_hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;1dd9625ce589eee05c22798a9a201602288a1667c59e5cd1fb2251a6261fbd68&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_frames&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">102</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_words&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;is_inbox&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;is_local&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;is_trashed&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;is_deleted&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;has_exif&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;has_human_readable_embedded_metadata&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;has_icc_profile&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;known_urls&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;https://gelbooru.com/index.php?page=post&amp;s=view&amp;id=4841557&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;https://img2.gelbooru.com//images/80/c8/80c8646b4a49395fb36c805f316c49a9.jpg&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;http://origin-orig.deviantart.net/ed31/f/2019/210/7/8/beachqueen_samus_by_dandonfuga-ddcu1xg.jpg&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;ratings&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;74d52c6238d25f846d579174c11856b1aaccdb04a185cb2c79f0d0e499284f2c&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;90769255dae5c205c975fc4ce2efff796b8be8a421f786c1737f87f98187ffaf&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;b474e0cbbab02ca1479c12ad985f1c680ea909a54eb028e3ad06750ea40d4106&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">11</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;6c6f63616c2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;storage_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;0&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;samus favourites&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;2&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;process this later&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;display_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;0&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;samus favourites&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;favourites&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;2&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;process this later&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;37e3849bda234f53b0e9792a036d14d4f3a9a136d1cb939705dbcd5287941db4&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;storage_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;0&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;blonde_hair&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;blue_eyes&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;looking_at_viewer&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;1&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;bodysuit&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;display_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;0&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;blonde hair&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;blue_eyes&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;looking at viewer&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;1&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;bodysuit&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;clothing&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;616c6c206b6e6f776e2074616773&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;storage_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;0&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;samus favourites&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;blonde_hair&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;blue_eyes&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;looking_at_viewer&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;1&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;bodysuit&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;display_tags&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;0&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;samus favourites&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;favourites&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;blonde hair&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;blue_eyes&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;looking at viewer&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;1&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;bodysuit&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;clothing&quot;</span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<div class="highlight"><span class="filename">And one where only_return_identifiers is true</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;services&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;The Services Object&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;metadata&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_id&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">123</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;4c77267f93415de0bc33b7725b8c331a809a924084bee03ab2f5fae1c6019eb2&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_id&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4567</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3e7cb9044fe81bda0d7a84b5cb781cba4e255e4871cba6ae8ecd8207850d5b82&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<div class="highlight"><span class="filename">And where only_return_basic_information is true</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;services&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;The Services Object&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;metadata&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_id&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">123</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;4c77267f93415de0bc33b7725b8c331a809a924084bee03ab2f5fae1c6019eb2&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;size&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">63405</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;mime&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;image/jpeg&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filetype_human&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;jpeg&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filetype_enum&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;ext&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;.jpg&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;width&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">640</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;height&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">480</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;duration&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;has_audio&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_frames&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_words&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_id&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4567</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3e7cb9044fe81bda0d7a84b5cb781cba4e255e4871cba6ae8ecd8207850d5b82&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;size&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">199713</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;mime&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;video/webm&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filetype_human&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;webm&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;filetype_enum&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">21</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;ext&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;.webm&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;width&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1920</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;height&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1080</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;duration&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4040</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;has_audio&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_frames&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">102</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_words&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></p>
<h4 id="basics">basics<a class="headerlink" href="#basics" title="Permanent link">&para;</a></h4>
<p>Size is in bytes. Duration is in milliseconds, and may be an int or a float.</p>
<p><code>is_trashed</code> means if the file is currently in the trash but available on the hard disk. <code>is_deleted</code> means currently either in the trash or completely deleted from disk.</p>
<p><code>file_services</code> stores which file services the file is <i>current</i>ly in and <em>deleted</em> from. The entries are by the service key, same as for tags later on. In rare cases, the timestamps may be <code>null</code>, if they are unknown (e.g. a <code>time_deleted</code> for the file deleted before this information was tracked). The <code>time_modified</code> can also be null. Time modified is just the filesystem modified time for now, but it will evolve into more complicated storage in future with multiple locations (website post times) that'll be aggregated to a sensible value in UI.</p>
<p><code>ipfs_multihashes</code> stores the ipfs service key to any known multihash for the file. </p>
<p>The <code>thumbnail_width</code> and <code>thumbnail_height</code> are a generally reliable prediction but aren't a promise. The actual thumbnail you get from <a href="#get_files_thumbnail">/get_files/thumbnail</a> will be different if the user hasn't looked at it since changing their thumbnail options. You only get these rows for files that hydrus actually generates an actual thumbnail for. Things like pdf won't have it. You can use your own thumb, or ask the api and it'll give you a fixed fallback; those are mostly 200x200, but you can and should size them to whatever you want.</p>
<p>If the file has a thumbnail, <code>blurhash</code> gives a base 83 encoded string of its <a href="https://blurha.sh/">blurhash</a>. <code>pixel_hash</code> is an SHA256 of the image's pixel data and should exactly match for pixel-identical files (it is used in the duplicate system for 'must be pixel duplicates').</p>
<h4 id="tags">tags<a class="headerlink" href="#tags" title="Permanent link">&para;</a></h4>
<p>The <code>tags</code> structure is similar to the <a href="#add_tags_add_tags">/add_tags/add_tags</a> scheme, excepting that the status numbers are:</p>
<ul>
<li>0 - current</li>
<li>1 - pending</li>
<li>2 - deleted</li>
<li>3 - petitioned</li>
</ul>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Since JSON Object keys must be strings, these status numbers are strings, not ints.</p>
</div>
<p>While the 'storage_tags' represent the actual tags stored on the database for a file, 'display_tags' reflect how tags appear in the UI, after siblings are collapsed and parents are added. If you want to edit a file's tags, refer to the storage tags. If you want to render to the user, use the display tags. The display tag calculation logic is very complicated; if the storage tags change, do not try to guess the new display tags yourself--just ask the API again. </p>
<h4 id="ratings">ratings<a class="headerlink" href="#ratings" title="Permanent link">&para;</a></h4>
<p>The <code>ratings</code> structure is simple, but it holds different data types. For each service:</p>
<ul>
<li>For a like/dislike service, 'no rating' is null. 'like' is true, 'dislike' is false.</li>
<li>For a numerical service, 'no rating' is null. Otherwise it will be an integer, for the number of stars.</li>
<li>For an inc/dec service, it is always an integer. The default value is 0 for all files.</li>
</ul>
<p>Check <a href="#services_object">The Services Object</a> to see the shape of a rating star, and min/max number of stars in a numerical service. </p>
<h4 id="services">services<a class="headerlink" href="#services" title="Permanent link">&para;</a></h4>
<p>The <code>tags</code>, <code>ratings</code>, and <code>file_services</code> structures use the hexadecimal <code>service_key</code> extensively. If you need to look up the respective service name or type, check <a href="#services_object">The Services Object</a> under the top level <code>services</code> key.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If you look, those file structures actually include the service name and type already, but this bloated data is deprecated and will be deleted in 2024, so please transition over.</p>
</div>
<p>If you don't want the services object (it is generally superfluous on the 'simple' responses), then add <code>include_services_object=false</code>.</p>
<h4 id="parameters">parameters<a class="headerlink" href="#parameters" title="Permanent link">&para;</a></h4>
<p>The <code>metadata</code> list <em>should</em> come back in the same sort order you asked, whether that is in <code>file_ids</code> or <code>hashes</code>!</p>
<p>If you ask with hashes rather than file_ids, hydrus will, by default, only return results when it has seen those hashes before. This is to stop the client making thousands of new file_id records in its database if you perform a scanning operation. If you ask about a hash the client has never encountered before--for which there is no file_id--you will get this style of result:</p>
<div class="highlight"><span class="filename">Missing file_id example</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;metadata&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_id&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;766da61f81323629f982bc1b71b5c1f9bba3f3ed61caf99906f7f26881c3ae93&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<p>You can change this behaviour with <code>create_new_file_ids=true</code>, but bear in mind you will get a fairly 'empty' metadata result with lots of 'null' lines, so this is only useful for gathering the numerical ids for later Client API work.</p>
<p>If you ask about file_ids that do not exist, you'll get 404.</p>
<p>If you set <code>only_return_basic_information=true</code>, this will be much faster for first-time requests than the full metadata result, but it will be slower for repeat requests. The full metadata object is cached after first fetch, the limited file info object is not. You can optionally set <code>include_blurhash</code> when using this option to fetch blurhash strings for the files.</p>
<p>If you add <code>detailed_url_information=true</code>, a new entry, <code>detailed_known_urls</code>, will be added for each file, with a list of the same structure as /<code>add_urls/get_url_info</code>. This may be an expensive request if you are querying thousands of files at once.</p>
<div class="highlight"><span class="filename">For example</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;detailed_known_urls&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;normalised_url&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://gelbooru.com/index.php?id=4841557&amp;page=post&amp;s=view&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;url_type&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;url_type_string&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;post url&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;match_name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;gelbooru file page&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;can_parse&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;normalised_url&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://img2.gelbooru.com//images/80/c8/80c8646b4a49395fb36c805f316c49a9.jpg&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;url_type&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;url_type_string&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;unknown url&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;match_name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;unknown url&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;can_parse&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="get_files_file"><strong>GET <code>/get_files/file</code></strong><a class="headerlink" href="#get_files_file" title="Permanent link">&para;</a></h3>
<p><em>Get a file.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Search for Files permission needed. Additional search permission limits may apply.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments :</dt>
<dd>
<ul>
<li><code>file_id</code>: (selective, numerical file id for the file)</li>
<li><code>hash</code>: (selective, a hexadecimal SHA256 hash for the file)</li>
<li><code>download</code>: (optional, boolean, default <code>false</code>)</li>
</ul>
<p>Only use one of file_id or hash. As with metadata fetching, you may only use the hash argument if you have access to all files. If you are tag-restricted, you will have to use a file_id in the last search you ran.</p>
</dd>
</dl>
<p><div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/get_files/file?file_id=452158
</code></pre></div>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/get_files/file?hash=7f30c113810985b69014957c93bc25e8eb4cf3355dae36d8b9d011d8b0cf623a&amp;download=true
</code></pre></div></p>
<dl>
<dt>Response:</dt>
<dd>The file itself. You should get the correct mime type as the Content-Type header.</dd>
</dl>
<p>By default, this will set the <code>Content-Disposition</code> header to <code>inline</code>, which causes a web browser to show the file. If you set <code>download=true</code>, it will set it to <code>attachment</code>, which triggers the browser to automatically download it (or open the 'save as' dialog) instead.</p>
<h3 id="get_files_thumbnail"><strong>GET <code>/get_files/thumbnail</code></strong><a class="headerlink" href="#get_files_thumbnail" title="Permanent link">&para;</a></h3>
<p><em>Get a file's thumbnail.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Search for Files permission needed. Additional search permission limits may apply.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>file_id</code>: (selective, numerical file id for the file)</li>
<li><code>hash</code>: (selective, a hexadecimal SHA256 hash for the file)</li>
</ul>
<p>Only use one. As with metadata fetching, you may only use the hash argument if you have access to all files. If you are tag-restricted, you will have to use a file_id in the last search you ran.</p>
</dd>
</dl>
<p><div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/get_files/thumbnail?file_id=452158
</code></pre></div>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/get_files/thumbnail?hash=7f30c113810985b69014957c93bc25e8eb4cf3355dae36d8b9d011d8b0cf623a
</code></pre></div></p>
<dl>
<dt>Response:</dt>
<dd>
<p>The thumbnail for the file. Some hydrus thumbs are jpegs, some are pngs. It should give you the correct image/jpeg or image/png Content-Type.</p>
<p>If hydrus keeps no thumbnail for the filetype, for instance with pdfs, then you will get the same default 'pdf' icon you see in the client. If the file does not exist in the client, or the thumbnail was expected but is missing from storage, you will get the fallback 'hydrus' icon, again just as you would in the client itself. This request should never give a 404.</p>
</dd>
</dl>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If you get a 'default' filetype thumbnail like the pdf or hydrus one, you will be pulling the defaults straight from the hydrus/static folder. They will most likely be 200x200 pixels. </p>
</div>
<h3 id="get_files_render"><strong>GET <code>/get_files/render</code></strong><a class="headerlink" href="#get_files_render" title="Permanent link">&para;</a></h3>
<p><em>Get an image file as rendered by Hydrus.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Search for Files permission needed. Additional search permission limits may apply.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments :</dt>
<dd>
<ul>
<li><code>file_id</code>: (selective, numerical file id for the file)</li>
<li><code>hash</code>: (selective, a hexadecimal SHA256 hash for the file)</li>
<li><code>download</code>: (optional, boolean, default <code>false</code>)</li>
</ul>
<p>Only use one of file_id or hash. As with metadata fetching, you may only use the hash argument if you have access to all files. If you are tag-restricted, you will have to use a file_id in the last search you ran.</p>
</dd>
</dl>
<p>The file you request must be a still image file that Hydrus can render (this includes PSD files). This request uses the client image cache.</p>
<p><div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/get_files/render?file_id=452158
</code></pre></div>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/get_files/render?hash=7f30c113810985b69014957c93bc25e8eb4cf3355dae36d8b9d011d8b0cf623a&amp;download=true
</code></pre></div></p>
<dl>
<dt>Response:</dt>
<dd>A PNG file of the image as would be rendered in the client. It will be converted to sRGB color if the file had a color profile but the rendered PNG will not have any color profile.</dd>
</dl>
<p>By default, this will set the <code>Content-Disposition</code> header to <code>inline</code>, which causes a web browser to show the file. If you set <code>download=true</code>, it will set it to <code>attachment</code>, which triggers the browser to automatically download it (or open the 'save as' dialog) instead.</p>
<h2 id="managing_file_relationships">Managing File Relationships<a class="headerlink" href="#managing_file_relationships" title="Permanent link">&para;</a></h2>
<p>This refers to the File Relationships system, which includes 'potential duplicates', 'duplicates', and 'alternates'.</p>
<p>This system is pending significant rework and expansion, so please do not get too married to some of the routines here. I am mostly just exposing my internal commands, so things are a little ugly/hacked. I expect duplicate and alternate groups to get some form of official identifier in future, which may end up being the way to refer and edit things here.</p>
<p>Also, at least for now, 'Manage File Relationships' permission is not going to be bound by the search permission restrictions that normal file search does. Getting this file relationship management permission allows you to search anything.</p>
<p><em>There is more work to do here, including adding various 'dissolve'/'undo' commands to break groups apart.</em></p>
<h3 id="manage_file_relationships_get_file_relationships"><strong>GET <code>/manage_file_relationships/get_file_relationships</code></strong><a class="headerlink" href="#manage_file_relationships_get_file_relationships" title="Permanent link">&para;</a></h3>
<p><em>Get the current relationships for one or more files.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage File Relationships permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/manage_file_relationships/get_file_relationships?hash=ac940bb9026c430ea9530b4f4f6980a12d9432c2af8d9d39dfc67b05d91df11d
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>A JSON Object mapping the hashes to their relationships.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_relationships&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;ac940bb9026c430ea9530b4f4f6980a12d9432c2af8d9d39dfc67b05d91df11d&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;is_king&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;king&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;8784afbfd8b59de3dcf2c13dc1be9d7cb0b3d376803c8a7a8b710c7c191bb657&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;king_is_on_file_domain&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;king_is_local&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;0&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;1&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[],</span>
<span class="w"> </span><span class="nt">&quot;3&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;8bf267c4c021ae4fd7c4b90b0a381044539519f80d148359b0ce61ce1684fefe&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;8&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;8784afbfd8b59de3dcf2c13dc1be9d7cb0b3d376803c8a7a8b710c7c191bb657&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;3fa8ef54811ec8c2d1892f4f08da01e7fc17eed863acae897eb30461b051d5c3&quot;</span>
<span class="w"> </span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<p><code>king</code> refers to which file is set as the best of a duplicate group. If you are doing potential duplicate comparisons, the kings of your two groups are usually the ideal representatives, and the 'get some pairs to filter'-style commands try to select the kings of the various to-be-compared duplicate groups. <code>is_king</code> is a convenience bool for when a file is king of its own group.</p>
<p><strong>It is possible for the king to not be available.</strong> Every group has a king, but if that file has been deleted, or if the file domain here is limited and the king is on a different file service, then it may not be available. A similar issue occurs when you search for filtering pairs--while it is ideal to compare kings with kings, if you set 'files must be pixel dupes', then the user will expect to see those pixel duplicates, not their champions--you may be forced to compare non-kings. <code>king_is_on_file_domain</code> lets you know if the king is on the file domain you set, and <code>king_is_local</code> lets you know if it is on the hard disk--if <code>king_is_local=true</code>, you can do a <code>/get_files/file</code> request on it. It is generally rare, but you have to deal with the king being unavailable--in this situation, your best bet is to just use the file itself as its own representative.</p>
<p>All the relationships you get are filtered by the file domain. If you set the file domain to 'all known files', you will get every relationship a file has, including all deleted files, which is often less useful than you would think. The default, 'all my files' is usually most useful.</p>
<p>A file that has no duplicates is considered to be in a duplicate group of size 1 and thus is always its own king.</p>
<p>The numbers are from a duplicate status enum, as so:</p>
<ul>
<li>0 - potential duplicates</li>
<li>1 - false positives</li>
<li>3 - alternates</li>
<li>8 - duplicates</li>
</ul>
<p>Note that because of JSON constraints, these are the string versions of the integers since they are Object keys.</p>
<p>All the hashes given here are in 'all my files', i.e. not in the trash. A file may have duplicates that have long been deleted, but, like the null king above, they will not show here.</p>
<h3 id="manage_file_relationships_get_potentials_count"><strong>GET <code>/manage_file_relationships/get_potentials_count</code></strong><a class="headerlink" href="#manage_file_relationships_get_potentials_count" title="Permanent link">&para;</a></h3>
<p><em>Get the count of remaining potential duplicate pairs in a particular search domain. Exactly the same as the counts you see in the duplicate processing page.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage File Relationships permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
<li><code>tag_service_key_1</code>: (optional, default 'all known tags', a hex tag service key)</li>
<li><code>tags_1</code>: (optional, default system:everything, a list of tags you wish to search for)</li>
<li><code>tag_service_key_2</code>: (optional, default 'all known tags', a hex tag service key)</li>
<li><code>tags_2</code>: (optional, default system:everything, a list of tags you wish to search for)</li>
<li><code>potentials_search_type</code>: (optional, integer, default 0, regarding how the pairs should match the search(es))</li>
<li><code>pixel_duplicates</code>: (optional, integer, default 1, regarding whether the pairs should be pixel duplicates)</li>
<li><code>max_hamming_distance</code>: (optional, integer, default 4, the max 'search distance' of the pairs)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/manage_file_relationships/get_potentials_count?tag_service_key_1=c1ba23c60cda1051349647a151321d43ef5894aacdfb4b4e333d6c4259d56c5f&amp;tags_1=%5B%22dupes_to_process%22%2C%20%22system%3Awidth%3C400%22%5D&amp;potentials_search_type=1&amp;pixel_duplicates=2&amp;max_hamming_distance=0&amp;max_num_pairs=50
</code></pre></div>
<p><code>tag_service_key_x</code> and <code>tags_x</code> work the same as <a href="#get_files_search_files">/get_files/search_files</a>. The <code>_2</code> variants are only useful if the <code>potentials_search_type</code> is 2.</p>
<p><code>potentials_search_type</code> and <code>pixel_duplicates</code> are enums:</p>
<ul>
<li>0 - one file matches search 1</li>
<li>1 - both files match search 1</li>
<li>2 - one file matches search 1, the other 2</li>
</ul>
<p>-and-</p>
<ul>
<li>0 - must be pixel duplicates</li>
<li>1 - can be pixel duplicates</li>
<li>2 - must not be pixel duplicates</li>
</ul>
<p>The <code>max_hamming_distance</code> is the same 'search distance' you see in the Client UI. A higher number means more speculative 'similar files' search. If <code>pixel_duplicates</code> is set to 'must be', then <code>max_hamming_distance</code> is obviously ignored.</p>
<dl>
<dt>Response:</dt>
<dd>A JSON Object stating the count.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;potential_duplicates_count&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">17</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<p>If you confirm that a pair of potentials are duplicates, this may transitively collapse other potential pairs and decrease the count by more than 1.</p>
<h3 id="manage_file_relationships_get_potential_pairs"><strong>GET <code>/manage_file_relationships/get_potential_pairs</code></strong><a class="headerlink" href="#manage_file_relationships_get_potential_pairs" title="Permanent link">&para;</a></h3>
<p><em>Get some potential duplicate pairs for a filtering workflow. Exactly the same as the 'duplicate filter' in the duplicate processing page.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage File Relationships permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
<li><code>tag_service_key_1</code>: (optional, default 'all known tags', a hex tag service key)</li>
<li><code>tags_1</code>: (optional, default system:everything, a list of tags you wish to search for)</li>
<li><code>tag_service_key_2</code>: (optional, default 'all known tags', a hex tag service key)</li>
<li><code>tags_2</code>: (optional, default system:everything, a list of tags you wish to search for)</li>
<li><code>potentials_search_type</code>: (optional, integer, default 0, regarding how the pairs should match the search(es))</li>
<li><code>pixel_duplicates</code>: (optional, integer, default 1, regarding whether the pairs should be pixel duplicates)</li>
<li><code>max_hamming_distance</code>: (optional, integer, default 4, the max 'search distance' of the pairs)</li>
<li><code>max_num_pairs</code>: (optional, integer, defaults to client's option, how many pairs to get in a batch)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/manage_file_relationships/get_potential_pairs?tag_service_key_1=c1ba23c60cda1051349647a151321d43ef5894aacdfb4b4e333d6c4259d56c5f&amp;tags_1=%5B%22dupes_to_process%22%2C%20%22system%3Awidth%3C400%22%5D&amp;potentials_search_type=1&amp;pixel_duplicates=2&amp;max_hamming_distance=0&amp;max_num_pairs=50
</code></pre></div>
<p>The search arguments work the same as <a href="#manage_file_relationships_get_potentials_count">/manage_file_relationships/get_potentials_count</a>.</p>
<p><code>max_num_pairs</code> is simple and just caps how many pairs you get.</p>
<dl>
<dt>Response:</dt>
<dd>A JSON Object listing a batch of hash pairs.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;potential_duplicate_pairs&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&quot;16470d6e73298cd75d9c7e8e2004810e047664679a660a9a3ba870b0fa3433d3&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;7ed062dc76265d25abeee5425a859cfdf7ab26fd291f50b8de7ca381e04db079&quot;</span><span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&quot;eeea390357f259b460219d9589b4fa11e326403208097b1a1fbe63653397b210&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;9215dfd39667c273ddfae2b73d90106b11abd5fd3cbadcc2afefa526bb226608&quot;</span><span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&quot;a1ea7d671245a3ae35932c603d4f3f85b0d0d40c5b70ffd78519e71945031788&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;8e9592b2dfb436fe0a8e5fa15de26a34a6dfe4bca9d4363826fac367a9709b25&quot;</span><span class="w"> </span><span class="p">]</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<p>The selected pair sample and their order is strictly hardcoded for now (e.g. to guarantee that a decision will not invalidate any other pair in the batch, you shouldn't see the same file twice in a batch, nor two files in the same duplicate group). Treat it as the client filter does, where you fetch batches to process one after another. I expect to make it more flexible in future, in the client itself and here.</p>
<p>You will see significantly fewer than <code>max_num_pairs</code> (and potential duplicate count) as you close to the last available pairs, and when there are none left, you will get an empty list.</p>
<h3 id="manage_file_relationships_get_random_potentials"><strong>GET <code>/manage_file_relationships/get_random_potentials</code></strong><a class="headerlink" href="#manage_file_relationships_get_random_potentials" title="Permanent link">&para;</a></h3>
<p><em>Get some random potentially duplicate file hashes. Exactly the same as the 'show some random potential dupes' button in the duplicate processing page.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage File Relationships permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
<li><code>tag_service_key_1</code>: (optional, default 'all known tags', a hex tag service key)</li>
<li><code>tags_1</code>: (optional, default system:everything, a list of tags you wish to search for)</li>
<li><code>tag_service_key_2</code>: (optional, default 'all known tags', a hex tag service key)</li>
<li><code>tags_2</code>: (optional, default system:everything, a list of tags you wish to search for)</li>
<li><code>potentials_search_type</code>: (optional, integer, default 0, regarding how the files should match the search(es))</li>
<li><code>pixel_duplicates</code>: (optional, integer, default 1, regarding whether the files should be pixel duplicates)</li>
<li><code>max_hamming_distance</code>: (optional, integer, default 4, the max 'search distance' of the files)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/manage_file_relationships/get_random_potentials?tag_service_key_1=c1ba23c60cda1051349647a151321d43ef5894aacdfb4b4e333d6c4259d56c5f&amp;tags_1=%5B%22dupes_to_process%22%2C%20%22system%3Awidth%3C400%22%5D&amp;potentials_search_type=1&amp;pixel_duplicates=2&amp;max_hamming_distance=0
</code></pre></div>
<p>The arguments work the same as <a href="#manage_file_relationships_get_potentials_count">/manage_file_relationships/get_potentials_count</a>, with the caveat that <code>potentials_search_type</code> has special logic:</p>
<ul>
<li>0 - first file matches search 1</li>
<li>1 - all files match search 1</li>
<li>2 - first file matches search 1, the others 2</li>
</ul>
<p>Essentially, the first hash is the 'master' to which the others are paired. The other files will include every matching file.</p>
<dl>
<dt>Response:</dt>
<dd>A JSON Object listing a group of hashes exactly as the client would.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;random_potential_duplicate_hashes&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;16470d6e73298cd75d9c7e8e2004810e047664679a660a9a3ba870b0fa3433d3&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;7ed062dc76265d25abeee5425a859cfdf7ab26fd291f50b8de7ca381e04db079&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;9e0d6b928b726562d70e1f14a7b506ba987c6f9b7f2d2e723809bb11494c73e6&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;9e01744819b5ff2a84dda321e3f1a326f40d0e7f037408ded9f18a11ee2b2da8&quot;</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></dd>
</dl>
<p>If there are no potential duplicate groups in the search, this returns an empty list.</p>
<h3 id="manage_file_relationships_set_file_relationships"><strong>POST <code>/manage_file_relationships/set_file_relationships</code></strong><a class="headerlink" href="#manage_file_relationships_set_file_relationships" title="Permanent link">&para;</a></h3>
<p>Set the relationships to the specified file pairs.</p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage File Relationships permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>relationships</code>: (a list of Objects, one for each file-pair being set)</li>
</ul>
</dd>
</dl>
<p>Each Object is:</p>
<div class="highlight"><pre><span></span><code>* `hash_a`: (a hexadecimal SHA256 hash)
* `hash_b`: (a hexadecimal SHA256 hash)
* `relationship`: (integer enum for the relationship being set)
* `do_default_content_merge`: (bool)
* `delete_a`: (optional, bool, default false)
* `delete_b`: (optional, bool, default false)
</code></pre></div>
<p><code>hash_a</code> and <code>hash_b</code> are normal hex SHA256 hashes for your file pair.</p>
<p><code>relationship</code> is one of this enum:</p>
<ul>
<li>0 - set as potential duplicates</li>
<li>1 - set as false positives</li>
<li>2 - set as same quality</li>
<li>3 - set as alternates</li>
<li>4 - set A as better</li>
<li>7 - set B as better</li>
</ul>
<p>2, 4, and 7 all make the files 'duplicates' (8 under <code>/get_file_relationships</code>), which, specifically, merges the two files' duplicate groups. 'same quality' has different duplicate content merge options to the better/worse choices, but it ultimately sets something similar to A&gt;B (but see below for more complicated outcomes). You obviously don't have to use 'B is better' if you prefer just to swap the hashes. Do what works for you.</p>
<p><code>do_default_content_merge</code> sets whether the user's duplicate content merge options should be loaded and applied to the files along with the relationship. Most operations in the client do this automatically, so the user may expect it to apply, but if you want to do content merge yourself, set this to false.</p>
<p><code>delete_a</code> and <code>delete_b</code> are booleans that select whether to delete A and/or B in the same operation as setting the relationship. You can also do this externally if you prefer.</p>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;relationships&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash_a&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;b54d09218e0d6efc964b78b070620a1fa19c7e069672b4c6313cee2c9b0623f2&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash_b&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;bbaa9876dab238dcf5799bfd8319ed0bab805e844f45cf0de33f40697b11a845&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;relationship&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;do_default_content_merge&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;delete_b&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash_a&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;22667427eaa221e2bd7ef405e1d2983846c863d40b2999ce8d1bf5f0c18f5fb2&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash_b&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;65d228adfa722f3cd0363853a191898abe8bf92d9a514c6c7f3c89cfed0bf423&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;relationship&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;do_default_content_merge&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;delete_b&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;hash_a&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0480513ffec391b77ad8c4e57fe80e5b710adfa3cb6af19b02a0bd7920f2d3ec&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash_b&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;5fab162576617b5c3fc8caabea53ce3ab1a3c8e0a16c16ae7b4e4a21eab168a7&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;relationship&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;do_default_content_merge&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 with no content.</dd>
</dl>
<p>If you try to add an invalid or redundant relationship, for instance setting files that are already duplicates as potential duplicates, no changes are made.</p>
<p>This is the file relationships request that is probably most likely to change in future. I may implement content merge options. I may move from file pairs to group identifiers. When I expand alternates, those file groups are going to support more variables.</p>
<h4 id="king_merge_rules">king merge rules<a class="headerlink" href="#king_merge_rules" title="Permanent link">&para;</a></h4>
<p>Recall in <code>/get_file_relationships</code> that we discussed how duplicate groups have a 'king' for their best file. This file is the most useful representative when you do comparisons, since if you say "King A &gt; King B", then we know that King A is also better than all of King B's normal duplicate group members. We can merge the group simply just by folding King B and all the other members into King A's group.</p>
<p>So what happens if you say 'A = B'? We have to have a king, so which should it be?</p>
<p>What happens if you say "non-king member of A &gt; non-king member of B"? We don't want to merge all of B into A, since King B might be higher quality than King A.</p>
<p>The logic here can get tricky, but I have tried my best to avoid overcommitting and accidentally promoting the wrong king. Here are all the possible situations ('&gt;' means 'better than', and '=' means 'same quality as'):</p>
<details class="abstract">
<summary>Merges</summary>
<ul>
<li>King A &gt; King B <ul>
<li>Merge B into A</li>
<li>King A is king of the new combined group</li>
</ul>
</li>
<li>Non-King A &gt; King B<ul>
<li>Merge B into A</li>
<li>King of A is king of the new combined group</li>
</ul>
</li>
<li>King A &gt; Non-King B<ul>
<li>Remove Non-King B from B and merge it into A</li>
<li>King A stays king of A</li>
<li>King of B stays king of B</li>
</ul>
</li>
<li>Non-King A &gt; Non-King B<ul>
<li>Remove Non-King B from B and merge it into A</li>
<li>King of A stays king of A</li>
<li>King of B stays king of B</li>
</ul>
</li>
<li>King A = King B<ul>
<li>Merge B into A</li>
<li>King A is king of the new combined group</li>
</ul>
</li>
<li>Non-King A = King B<ul>
<li>Merge B into A</li>
<li>King of A is king of the new combined group</li>
</ul>
</li>
<li>King A = Non-King B<ul>
<li>Merge A into B</li>
<li>King of B is king of the new combined group</li>
</ul>
</li>
<li>Non-King A = Non-King B<ul>
<li>Remove Non-King B from B and merge it into A</li>
<li>King of A stays king of A</li>
<li>King of B stays king of B</li>
</ul>
</li>
</ul>
</details>
<p>So, if you can, always present kings to your users, and action using those kings' hashes. It makes the merge logic easier in all cases. Remember that you can set <code>system:is the best quality file of its duplicate group</code> in any file search to exclude any non-kings (e.g. if you are hunting for easily actionable pixel potential duplicates).</p>
<h3 id="manage_file_relationships_set_kings"><strong>POST <code>/manage_file_relationships/set_kings</code></strong><a class="headerlink" href="#manage_file_relationships_set_kings" title="Permanent link">&para;</a></h3>
<p>Set the specified files to be the kings of their duplicate groups.</p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage File Relationships permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><a href="#parameters_files">files</a></li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_id&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">123</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 with no content.</dd>
</dl>
<p>The files will be promoted to be the kings of their respective duplicate groups. If the file is already the king (also true for any file with no duplicates), this is idempotent. It also processes the files in the given order, so if you specify two files in the same group, the latter will be the king at the end of the request.</p>
<h2 id="managing_cookies">Managing Cookies<a class="headerlink" href="#managing_cookies" title="Permanent link">&para;</a></h2>
<p>This refers to the cookies held in the client's session manager, which you can review under <em>network-&gt;data-&gt;manage session cookies</em>. These are sent to every request on the respective domains.</p>
<h3 id="manage_cookies_get_cookies"><strong>GET <code>/manage_cookies/get_cookies</code></strong><a class="headerlink" href="#manage_cookies_get_cookies" title="Permanent link">&para;</a></h3>
<p><em>Get the cookies for a particular domain.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Cookies and Headers permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>domain</code></li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request (for gelbooru.com)</span><pre><span></span><code>/manage_cookies/get_cookies?domain=gelbooru.com
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>A JSON Object listing all the cookies for that domain in [ name, value, domain, path, expires ] format.</dd>
</dl>
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;cookies&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">[</span><span class="s2">&quot;__cfduid&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;f1bef65041e54e93110a883360bc7e71&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;.gelbooru.com&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;/&quot;</span><span class="p">,</span><span class="w"> </span><span class="mi">1596223327</span><span class="p">],</span>
<span class="w"> </span><span class="p">[</span><span class="s2">&quot;pass_hash&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;0b0833b797f108e340b315bc5463c324&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;gelbooru.com&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;/&quot;</span><span class="p">,</span><span class="w"> </span><span class="mi">1585855361</span><span class="p">],</span>
<span class="w"> </span><span class="p">[</span><span class="s2">&quot;user_id&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;123456&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;gelbooru.com&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;/&quot;</span><span class="p">,</span><span class="w"> </span><span class="mi">1585855361</span><span class="p">]</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<div class="highlight"><pre><span></span><code>Note that these variables are all strings except &#39;expires&#39;, which is either an integer timestamp or _null_ for session cookies.
This request will also return any cookies for subdomains. The session system in hydrus generally stores cookies according to the second-level domain, so if you request for specific.someoverbooru.net, you will still get the cookies for someoverbooru.net and all its subdomains.
</code></pre></div>
<h3 id="manage_cookies_set_cookies"><strong>POST <code>/manage_cookies/set_cookies</code></strong><a class="headerlink" href="#manage_cookies_set_cookies" title="Permanent link">&para;</a></h3>
<p>Set some new cookies for the client. This makes it easier to 'copy' a login from a web browser or similar to hydrus if hydrus's login system can't handle the site yet.</p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Cookies and Headers permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>cookies</code>: (a list of cookie rows in the same format as the GET request above)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;cookies&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">[</span><span class="s2">&quot;PHPSESSID&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;07669eb2a1a6e840e498bb6e0799f3fb&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;.somesite.com&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;/&quot;</span><span class="p">,</span><span class="w"> </span><span class="mi">1627327719</span><span class="p">],</span>
<span class="w"> </span><span class="p">[</span><span class="s2">&quot;tag_filter&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;1&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;.somesite.com&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;/&quot;</span><span class="p">,</span><span class="w"> </span><span class="mi">1627327719</span><span class="p">]</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<p>You can set 'value' to be null, which will clear any existing cookie with the corresponding name, domain, and path (acting essentially as a delete).</p>
<p>Expires can be null, but session cookies will time-out in hydrus after 60 minutes of non-use.</p>
<h2 id="managing_http_headers">Managing HTTP Headers<a class="headerlink" href="#managing_http_headers" title="Permanent link">&para;</a></h2>
<p>This refers to the custom headers you can see under <em>network-&gt;data-&gt;manage http headers</em>.</p>
<h3 id="manage_headers_get_headers"><strong>GET <code>/manage_headers/get_headers</code></strong><a class="headerlink" href="#manage_headers_get_headers" title="Permanent link">&para;</a></h3>
<p>Get the custom http headers.</p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Cookies and Headers permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>domain</code>: optional, the domain to fetch headers for</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request (for gelbooru.com)</span><pre><span></span><code>/manage_headers/get_headers?domain=gelbooru.com
</code></pre></div>
<div class="highlight"><span class="filename">Example request (for global)</span><pre><span></span><code>/manage_headers/get_headers
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>A JSON Object listing all the headers:</dd>
</dl>
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;network_context&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;data&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;gelbooru.com&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;headers&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;User-Agent&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;approved&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;approved&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;reason&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Set by Client API&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;DNT&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;1&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;approved&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;approved&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;reason&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Set by Client API&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="manage_headers_set_headers"><strong>POST <code>/manage_headers/set_headers</code></strong><a class="headerlink" href="#manage_headers_set_headers" title="Permanent link">&para;</a></h3>
<p>Manages the custom http headers.</p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Cookies and Headers permission needed.</dd>
<dt>Required Headers:</dt>
<dd>* <code>Content-Type</code>: application/json</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>domain</code>: (optional, the specific domain to set the header for)</li>
<li><code>headers</code>: (a JSON Object that holds "key" objects)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;domain&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;mysite.com&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;headers&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;User-Agent&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;DNT&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;1&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;CoolStuffToken&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;abcdef0123456789&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;approved&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;pending&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;reason&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;This unlocks the Sonic fanfiction!&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<div class="highlight"><span class="filename">Example request body that deletes</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;domain&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;myothersite.com&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;headers&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;User-Agent&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;Authorization&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">null</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>If you do not set a domain, or you set it to <code>null</code>, the 'context' will be the global context, which applies as a fallback to all jobs.</p>
<p>Domain headers also apply to their subdomains--unless they are overwritten by specific subdomain entries.</p>
<p>Each <code>key</code> Object under <code>headers</code> has the same form as <a href="#manage_headers_get_headers">/manage_headers/get_headers</a>. <code>value</code> is obvious--it is the value of the header. If the pair doesn't exist yet, you need the <code>value</code>, but if you just want to approve something, it is optional. Set it to <code>null</code> to delete an existing pair.</p>
<p>You probably won't ever use <code>approved</code> or <code>reason</code>, but they plug into the 'validation' system in the client. They are both optional. Approved can be any of <code>[ approved, denied, pending ]</code>, and by default everything you add will be <code>approved</code>. If there is anything <code>pending</code> when a network job asks, the user will be presented with a yes/no popup presenting the reason for the header. If they click 'no', the header is set to <code>denied</code> and the network job goes ahead without it. If you have a header that changes behaviour or unlocks special content, you might like to make it optional in this way.</p>
<p>If you need to reinstate it, the default <code>global</code> <code>User-Agent</code> is <code>Mozilla/5.0 (compatible; Hydrus Client)</code>.</p>
<h3 id="manage_headers_set_user_agent"><strong>POST <code>/manage_headers/set_user_agent</code></strong><a class="headerlink" href="#manage_headers_set_user_agent" title="Permanent link">&para;</a></h3>
<p><em>This is deprecated--move to <a href="#manage_headers_set_headers">/manage_headers/set_headers</a>!</em></p>
<p>This sets the 'Global' User-Agent for the client, as typically editable under <em>network-&gt;data-&gt;manage http headers</em>, for instance if you want hydrus to appear as a specific browser associated with some cookies.</p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Cookies and Headers permission needed.</dd>
<dt>Required Headers:</dt>
<dd>* <code>Content-Type</code>: application/json</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>user-agent</code>: (a string)</li>
</ul>
</dd>
</dl>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;user-agent&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0&quot;</span>
<span class="p">}</span>
</code></pre></div>
<p>Send an empty string to reset the client back to the default User-Agent, which should be <code>Mozilla/5.0 (compatible; Hydrus Client)</code>.</p>
<h2 id="managing_pages">Managing Pages<a class="headerlink" href="#managing_pages" title="Permanent link">&para;</a></h2>
<p>This refers to the pages of the main client UI.</p>
<h3 id="manage_pages_get_pages"><strong>GET <code>/manage_pages/get_pages</code></strong><a class="headerlink" href="#manage_pages_get_pages" title="Permanent link">&para;</a></h3>
<p><em>Get the page structure of the current UI session.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Pages permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<p>Arguments: n/a</p>
<dl>
<dt>Response:</dt>
<dd>
<p>A JSON Object of the top-level page 'notebook' (page of pages) detailing its basic information and current sub-pages. Page of pages beneath it will list their own sub-page lists.
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;pages&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;top pages notebook&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3b28d8a59ec61834325eb6275d9df012860a1ecfd9e1246423059bc47fb6d5bd&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_state&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;selected&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;pages&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;files&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;d436ff5109215199913705eb9a7669d8a6b67c52e41c3b42904db083255ca84d&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_state&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">6</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;selected&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;thread watcher&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;40887fa327edca01e1d69b533dddba4681b2c43e0b4ebee0576177852e8c32e7&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_state&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">9</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;selected&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;pages&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2ee7fa4058e1e23f2bd9e915cdf9347ae90902a8622d6559ba019a83a785c4dc&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_state&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;selected&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;pages&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;urls&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;9fe22cb760d9ee6de32575ed9f27b76b4c215179cf843d3f9044efeeca98411f&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_state&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">7</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;selected&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;files&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2977d57fc9c588be783727bcd54225d577b44e8aa2f91e365a3eb3c3f580dc4e&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_state&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">6</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;selected&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></p>
<p><code>name</code> is the full text on the page tab. </p>
<p><code>page_key</code> is a unique identifier for the page. It will stay the same for a particular page throughout the session, but new ones are generated on a session reload.</p>
<p><code>page_type</code> is as follows:</p>
<ul>
<li>1 - Gallery downloader</li>
<li>2 - Simple downloader</li>
<li>3 - Hard drive import</li>
<li>5 - Petitions (used by repository janitors)</li>
<li>6 - File search</li>
<li>7 - URL downloader</li>
<li>8 - Duplicates</li>
<li>9 - Thread watcher</li>
<li>10 - Page of pages</li>
</ul>
<p><code>page_state</code> is as follows:</p>
<ul>
<li>0 - ready</li>
<li>1 - initialising</li>
<li>2 - searching/loading</li>
<li>3 - search cancelled</li>
</ul>
<p>Most pages will be 0, normal/ready, at all times. Large pages will start in an 'initialising' state for a few seconds, which means their session-saved thumbnails aren't loaded yet. Search pages will enter 'searching' after a refresh or search change and will either return to 'ready' when the search is complete, or fall to 'search cancelled' if the search was interrupted (usually this means the user clicked the 'stop' button that appears after some time). </p>
<p><code>selected</code> means which page is currently in view. It will propagate down the page of pages until it terminates. It may terminate in an empty page of pages, so do not assume it will end on a media page. </p>
<p>The top page of pages will always be there, and always selected.</p>
</dd>
</dl>
<h3 id="manage_pages_get_page_info"><strong>GET <code>/manage_pages/get_page_info</code></strong><a class="headerlink" href="#manage_pages_get_page_info" title="Permanent link">&para;</a></h3>
<p><em>Get information about a specific page.</em></p>
<div class="admonition warning">
<p class="admonition-title">Under Construction</p>
<p>This is under construction. The current call dumps a ton of info for different downloader pages. Please experiment in IRL situations and give feedback for now! I will flesh out this help with more enumeration info and examples as this gets nailed down. POST commands to alter pages (adding, removing, highlighting), will come later.</p>
</div>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Pages permission needed.</dd>
</dl>
<p>Required Headers: n/a</p>
<dl>
<dt>Arguments:</dt>
<dd>
<ul>
<li><code>page_key</code>: (hexadecimal page_key as stated in <a href="#manage_pages_get_pages">/manage_pages/get_pages</a>)</li>
<li><code>simple</code>: true or false (optional, defaulting to true)</li>
</ul>
<div class="highlight"><span class="filename">Example request</span><pre><span></span><code>/manage_pages/get_page_info?page_key=aebbf4b594e6986bddf1eeb0b5846a1e6bc4e07088e517aff166f1aeb1c3c9da&amp;simple=true
</code></pre></div>
</dd>
<dt>Response description</dt>
<dd>
<p>A JSON Object of the page's information. At present, this mostly means downloader information.
<div class="highlight"><span class="filename">Example response with simple = true</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;page_info&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;threads&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;aebbf4b594e6986bddf1eeb0b5846a1e6bc4e07088e517aff166f1aeb1c3c9da&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_state&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;page_type&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;management&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;multiple_watcher_import&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;watcher_imports&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;url&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://someimageboard.net/m/123456&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;watcher_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;cf8c3525c57a46b0e5c2625812964364a2e801f8c49841c216b8f8d7a4d06d85&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;created&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1566164269</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;last_check_time&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1566164272</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;next_check_time&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1566174272</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;files_paused&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;checking_paused&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;checking_status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;subject&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;gundam pictures&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;imports&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;4 successful (2 already in db)&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;simple_status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;4&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_processed&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_to_process&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;gallery_log&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;1 successful&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;simple_status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;1&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_processed&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_to_process&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;url&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;https://someimageboard.net/a/1234&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;watcher_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;6bc17555b76da5bde2dcceedc382cf7d23281aee6477c41b643cd144ec168510&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;created&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1566063125</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;last_check_time&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1566063133</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;next_check_time&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1566104272</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;files_paused&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;checking_paused&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;checking_status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;subject&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;anime pictures&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;imports&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;124 successful (22 already in db), 2 previously deleted&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;simple_status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;124&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_processed&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">124</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_to_process&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">124</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;gallery_log&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3 successful&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;simple_status&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_processed&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_to_process&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">3</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;highlight&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;cf8c3525c57a46b0e5c2625812964364a2e801f8c49841c216b8f8d7a4d06d85&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;media&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;num_files&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">4</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></p>
<p><code>name</code>, <code>page_key</code>, <code>page_state</code>, and <code>page_type</code> are as in <a href="#manage_pages_get_pages">/manage_pages/get_pages</a>.</p>
<p>As you can see, even the 'simple' mode can get very large. Imagine that response for a page watching 100 threads! Turning simple mode off will display every import item, gallery log entry, and all hashes in the media (thumbnail) panel.</p>
<p>For this first version, the five importer pages--hdd import, simple downloader, url downloader, gallery page, and watcher page--all give rich info based on their specific variables. The first three only have one importer/gallery log combo, but the latter two of course can have multiple. The "imports" and "gallery_log" entries are all in the same data format.</p>
</dd>
</dl>
<h3 id="manage_pages_add_files"><strong>POST <code>/manage_pages/add_files</code></strong><a class="headerlink" href="#manage_pages_add_files" title="Permanent link">&para;</a></h3>
<p><em>Add files to a page.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Pages permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>page_key</code>: (the page key for the page you wish to add files to)</li>
<li><a href="#parameters_files">files</a></li>
</ul>
</dd>
</dl>
<p>The files you set will be appended to the given page, just like a thumbnail drag and drop operation. The page key is the same as fetched in the <a href="#manage_pages_get_pages">/manage_pages/get_pages</a> call.</p>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;af98318b6eece15fef3cf0378385ce759bfe056916f6e12157cd928eb56c1f18&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;file_ids&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">123</span><span class="p">,</span><span class="w"> </span><span class="mi">124</span><span class="p">,</span><span class="w"> </span><span class="mi">125</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 with no content. If the page key is not found, this will 404.</dd>
</dl>
<h3 id="manage_pages_focus_page"><strong>POST <code>/manage_pages/focus_page</code></strong><a class="headerlink" href="#manage_pages_focus_page" title="Permanent link">&para;</a></h3>
<p><em>'Show' a page in the main GUI, making it the current page in view. If it is already the current page, no change is made.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Pages permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>page_key</code>: (the page key for the page you wish to show)</li>
</ul>
</dd>
</dl>
<p>The page key is the same as fetched in the <a href="#manage_pages_get_pages">/manage_pages/get_pages</a> call.</p>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;af98318b6eece15fef3cf0378385ce759bfe056916f6e12157cd928eb56c1f18&quot;</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 with no content. If the page key is not found, this will 404.</dd>
</dl>
<h3 id="manage_pages_refresh_page"><strong>POST <code>/manage_pages/refresh_page</code></strong><a class="headerlink" href="#manage_pages_refresh_page" title="Permanent link">&para;</a></h3>
<p><em>Refresh a page in the main GUI. Like hitting F5 in the client, this obviously makes file search pages perform their search again, but for other page types it will force the currently in-view files to be re-sorted.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Pages permission needed.</dd>
<dt>Required Headers:</dt>
<dd>
<ul>
<li><code>Content-Type</code>: application/json</li>
</ul>
</dd>
<dt>Arguments (in JSON):</dt>
<dd>
<ul>
<li><code>page_key</code>: (the page key for the page you wish to refresh)</li>
</ul>
</dd>
</dl>
<p>The page key is the same as fetched in the <a href="#manage_pages_get_pages">/manage_pages/get_pages</a> call. If a file search page is not set to 'searching immediately', a 'refresh' command does nothing.</p>
<div class="highlight"><span class="filename">Example request body</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;page_key&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;af98318b6eece15fef3cf0378385ce759bfe056916f6e12157cd928eb56c1f18&quot;</span>
<span class="p">}</span>
</code></pre></div>
<dl>
<dt>Response:</dt>
<dd>200 with no content. If the page key is not found, this will 404.</dd>
</dl>
<p>Poll the <code>page_state</code> in <a href="#manage_pages_get_pages">/manage_pages/get_pages</a> or <a href="#manage_pages_get_page_info">/manage_pages/get_page_info</a> to see when the search is complete.</p>
<h2 id="managing_the_database">Managing the Database<a class="headerlink" href="#managing_the_database" title="Permanent link">&para;</a></h2>
<h3 id="manage_database_lock_on"><strong>POST <code>/manage_database/lock_on</code></strong><a class="headerlink" href="#manage_database_lock_on" title="Permanent link">&para;</a></h3>
<p><em>Pause the client's database activity and disconnect the current connection.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Database permission needed.</dd>
</dl>
<p>Arguments: None</p>
<p>This is a hacky prototype. It commands the client database to pause its job queue and release its connection (and related file locks and journal files). This puts the client in a similar position as a long VACUUM command--it'll hang in there, but not much will work, and since the UI async code isn't great yet, the UI may lock up after a minute or two. If you would like to automate database backup without shutting the client down, this is the thing to play with.</p>
<p>This should return pretty quick, but it will wait up to five seconds for the database to actually disconnect. If there is a big job (like a VACUUM) current going on, it may take substantially longer to finish that up and process this STOP command. You might like to check for the existence of a journal file in the db dir just to be safe.</p>
<p>As long as this lock is on, all Client API calls except the unlock command will return 503. (This is a decent way to test the current lock status, too)</p>
<h3 id="manage_database_lock_off"><strong>POST <code>/manage_database/lock_off</code></strong><a class="headerlink" href="#manage_database_lock_off" title="Permanent link">&para;</a></h3>
<p><em>Reconnect the client's database and resume activity.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Database permission needed.</dd>
</dl>
<p>Arguments: None</p>
<p>This is the obvious complement to the lock. The client will resume processing its job queue and will catch up. If the UI was frozen, it should free up in a few seconds, just like after a big VACUUM.</p>
<h3 id="manage_database_mr_bones"><strong>GET <code>/manage_database/mr_bones</code></strong><a class="headerlink" href="#manage_database_mr_bones" title="Permanent link">&para;</a></h3>
<p><em>Get the data from help-&gt;how boned am I?. This is a simple Object of numbers just for hacky advanced purposes if you want to build up some stats in the background. The numbers are the same as the dialog shows, so double check that to confirm what means what.</em></p>
<dl>
<dt>Restricted access:</dt>
<dd>YES. Manage Database permission needed.</dd>
<dt>Arguments (in percent-encoded JSON):</dt>
<dd>
<ul>
<li><code>tags</code>: (optional, a list of tags you wish to search for)</li>
<li><a href="#parameters_file_domain">file domain</a> (optional, defaults to 'all my files')</li>
<li><code>tag_service_key</code>: (optional, hexadecimal, the tag domain on which to search, defaults to 'all my files')</li>
</ul>
<div class="highlight"><span class="filename">Example requests</span><pre><span></span><code>/manage_database/mr_bones
/manage_database/mr_bones?tags=%5B%22blonde_hair%22%2C%20%22blue_eyes%22%5D
</code></pre></div>
</dd>
</dl>
<div class="highlight"><span class="filename">Example response</span><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;boned_stats&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;num_inbox&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">8356</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_archive&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">229</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;num_deleted&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">7010</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;size_inbox&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">7052596762</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;size_archive&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">262911007</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;size_deleted&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">13742290193</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;earliest_import_time&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1451408539</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_viewtime&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">3280</span><span class="p">,</span><span class="w"> </span><span class="mi">41621</span><span class="p">,</span><span class="w"> </span><span class="mi">2932</span><span class="p">,</span><span class="w"> </span><span class="mi">83021</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;total_alternate_files&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">265</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_duplicate_files&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">125</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_potential_pairs&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">3252</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>The arguments here are the same as for <a href="#get_files_search_files">GET /get_files/search_files</a>. You can set any or none of them to set a search domain like in the dialog.</p>
<hr>
<div class="md-source-file">
<small>
Last update:
<span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date">October 18, 2023</span>
</small>
</div>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var tab,labels=set.querySelector(".tabbed-labels");for(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>
</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 8v12Z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<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 class="md-social">
<a href="https://github.com/hydrusnetwork/hydrus" target="_blank" rel="noopener" title="github.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.4.2 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 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</a>
<a href="https://twitter.com/hydrusnetwork" target="_blank" rel="noopener" title="twitter.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 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 2023 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
</a>
<a href="https://hydrus.tumblr.com/" target="_blank" rel="noopener" title="hydrus.tumblr.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.4.2 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 2023 Fonticons, Inc.--><path d="M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"/></svg>
</a>
<a href="mailto:hydrus.admin@gmail.com" target="_blank" rel="noopener" title="" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 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 2023 Fonticons, Inc.--><path d="M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4l217.6 163.2c11.4 8.5 27 8.5 38.4 0l217.6-163.2c12.1-9.1 19.2-23.3 19.2-38.4 0-26.5-21.5-48-48-48H48zM0 176v208c0 35.3 28.7 64 64 64h384c35.3 0 64-28.7 64-64V176L294.4 339.2a63.9 63.9 0 0 1-76.8 0L0 176z"/></svg>
</a>
<a href="https://discord.gg/wPHPCUZ" target="_blank" rel="noopener" title="discord.gg" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.4.2 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 2023 Fonticons, Inc.--><path d="M524.531 69.836a1.5 1.5 0 0 0-.764-.7A485.065 485.065 0 0 0 404.081 32.03a1.816 1.816 0 0 0-1.923.91 337.461 337.461 0 0 0-14.9 30.6 447.848 447.848 0 0 0-134.426 0 309.541 309.541 0 0 0-15.135-30.6 1.89 1.89 0 0 0-1.924-.91 483.689 483.689 0 0 0-119.688 37.107 1.712 1.712 0 0 0-.788.676C39.068 183.651 18.186 294.69 28.43 404.354a2.016 2.016 0 0 0 .765 1.375 487.666 487.666 0 0 0 146.825 74.189 1.9 1.9 0 0 0 2.063-.676A348.2 348.2 0 0 0 208.12 430.4a1.86 1.86 0 0 0-1.019-2.588 321.173 321.173 0 0 1-45.868-21.853 1.885 1.885 0 0 1-.185-3.126 251.047 251.047 0 0 0 9.109-7.137 1.819 1.819 0 0 1 1.9-.256c96.229 43.917 200.41 43.917 295.5 0a1.812 1.812 0 0 1 1.924.233 234.533 234.533 0 0 0 9.132 7.16 1.884 1.884 0 0 1-.162 3.126 301.407 301.407 0 0 1-45.89 21.83 1.875 1.875 0 0 0-1 2.611 391.055 391.055 0 0 0 30.014 48.815 1.864 1.864 0 0 0 2.063.7A486.048 486.048 0 0 0 610.7 405.729a1.882 1.882 0 0 0 .765-1.352c12.264-126.783-20.532-236.912-86.934-334.541ZM222.491 337.58c-28.972 0-52.844-26.587-52.844-59.239s23.409-59.241 52.844-59.241c29.665 0 53.306 26.82 52.843 59.239 0 32.654-23.41 59.241-52.843 59.241Zm195.38 0c-28.971 0-52.843-26.587-52.843-59.239s23.409-59.241 52.843-59.241c29.667 0 53.307 26.82 52.844 59.239 0 32.654-23.177 59.241-52.844 59.241Z"/></svg>
</a>
<a href="https://www.patreon.com/hydrus_dev" target="_blank" rel="noopener" title="www.patreon.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 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 2023 Fonticons, Inc.--><path d="M512 194.8c0 101.3-82.4 183.8-183.8 183.8-101.7 0-184.4-82.4-184.4-183.8 0-101.6 82.7-184.3 184.4-184.3C429.6 10.5 512 93.2 512 194.8zM0 501.5h90v-491H0v491z"/></svg>
</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">{"base": ".", "features": ["navigation.tracking", "navigation.sections", "navigation.tabs", "content.tabs.link", "navigation.top", "search.suggest", "content.code.annotate", "navigation.instant", "content.action.edit"], "search": "assets/javascripts/workers/search.f886a092.min.js", "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"}}</script>
<script src="assets/javascripts/bundle.aecac24b.min.js"></script>
</body>
</html>