autobrr Dir Scan API
Directory scanner operations for data-based matching and injection
Directory scanner operations for data-based matching and injection
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/autobrr:autobrr-dir-scan-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: qui Dir Scan API
description: 'qui API for managing multiple qBittorrent instances.
If allowedHosts is configured, a missing, invalid, or unlisted received Host
returns HTTP 400 before authentication or routing. X-Forwarded-Host is ignored.
Request ports do not affect matching. Only direct loopback GET and HEAD
requests to /health, /healthz/readiness, and /healthz/liveness bypass the list.
For automation create and update requests, set `conditions.category.enabled` to `true`
and `conditions.category.category` to an empty string to remove the torrent category.
Set `conditions.category.enabled` to `false` to disable the category action.'
version: 1.0.0
license:
name: GPL-2.0-or-later
url: https://opensource.org/licenses/GPL-2.0
servers:
- url: http://localhost:7476
description: Local development server
- url: /
description: Current server
security:
- ApiKeyAuth: []
- SessionAuth: []
tags:
- name: Dir Scan
description: Directory scanner operations for data-based matching and injection
paths:
/api/dir-scan/settings:
get:
tags:
- Dir Scan
summary: Get dir scan settings
description: Returns the global directory scanner configuration
responses:
'200':
description: Current directory scanner settings
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanSettings'
'500':
description: Failed to load directory scanner settings
operationId: getApiDirScanSettings
x-operation-id-source: derived
patch:
tags:
- Dir Scan
summary: Update dir scan settings
description: Partially updates global directory scanner settings
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanSettingsPatch'
responses:
'200':
description: Updated directory scanner settings
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanSettings'
'400':
description: Invalid request body
'500':
description: Failed to update directory scanner settings
operationId: patchApiDirScanSettings
x-operation-id-source: derived
/api/dir-scan/directories:
get:
tags:
- Dir Scan
summary: List scan directories
description: Returns all configured scan directories
responses:
'200':
description: Configured scan directories
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DirScanDirectory'
'500':
description: Failed to list directories
operationId: getApiDirScanDirectories
x-operation-id-source: derived
post:
tags:
- Dir Scan
summary: Create scan directory
description: Creates a new scan directory configuration
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanDirectoryCreate'
responses:
'201':
description: Created scan directory
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanDirectory'
'400':
description: Invalid request body
'500':
description: Failed to create directory
operationId: postApiDirScanDirectories
x-operation-id-source: derived
/api/dir-scan/directories/{directoryID}:
get:
tags:
- Dir Scan
summary: Get scan directory
description: Returns a scan directory by ID
parameters:
- $ref: '#/components/parameters/directoryID'
responses:
'200':
description: Scan directory
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanDirectory'
'404':
description: Directory not found
'500':
description: Failed to get directory
operationId: getApiDirScanDirectoriesByDirectoryID
x-operation-id-source: derived
patch:
tags:
- Dir Scan
summary: Update scan directory
description: Partially updates a scan directory configuration
parameters:
- $ref: '#/components/parameters/directoryID'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanDirectoryPatch'
responses:
'200':
description: Updated scan directory
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanDirectory'
'400':
description: Invalid request body
'404':
description: Directory not found
'500':
description: Failed to update directory
operationId: patchApiDirScanDirectoriesByDirectoryID
x-operation-id-source: derived
delete:
tags:
- Dir Scan
summary: Delete scan directory
description: Deletes a scan directory configuration and all associated history
parameters:
- $ref: '#/components/parameters/directoryID'
responses:
'204':
description: Directory deleted
'404':
description: Directory not found
'500':
description: Failed to delete directory
operationId: deleteApiDirScanDirectoriesByDirectoryID
x-operation-id-source: derived
/api/dir-scan/directories/{directoryID}/reset-files:
post:
tags:
- Dir Scan
summary: Reset directory scan progress
description: Deletes tracked dir-scan file state for the directory so the next scan re-processes it
parameters:
- $ref: '#/components/parameters/directoryID'
responses:
'204':
description: Scan progress reset
'404':
description: Directory not found
'500':
description: Failed to reset scan progress
operationId: postApiDirScanDirectoriesByDirectoryIDResetFiles
x-operation-id-source: derived
/api/dir-scan/directories/{directoryID}/requeue-no-match:
post:
tags:
- Dir Scan
summary: Requeue unmatched files
description: Resets no_match files for the directory to pending so the next scan searches them again. Matched and already-seeding files are kept.
parameters:
- $ref: '#/components/parameters/directoryID'
responses:
'200':
description: Number of files requeued
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanRequeueResponse'
'404':
description: Directory not found
'409':
description: A scan is running
'500':
description: Failed to requeue files
operationId: postApiDirScanDirectoriesByDirectoryIDRequeueNoMatch
x-operation-id-source: derived
/api/dir-scan/directories/{directoryID}/scan:
post:
tags:
- Dir Scan
summary: Trigger a directory scan
description: Starts a manual scan run for the given directory
parameters:
- $ref: '#/components/parameters/directoryID'
responses:
'202':
description: Scan started
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanTriggerResponse'
'404':
description: Directory not found
'409':
description: A full scan is already queued or in progress. A webhook scan in progress does not block a manual scan.
'500':
description: Failed to start scan
operationId: postApiDirScanDirectoriesByDirectoryIDScan
x-operation-id-source: derived
delete:
tags:
- Dir Scan
summary: Cancel a directory scan
description: Cancels every queued and running scan of the given directory, full scans and webhook scans
parameters:
- $ref: '#/components/parameters/directoryID'
responses:
'204':
description: Scan canceled (or no scan running)
'404':
description: Directory not found
'500':
description: Failed to cancel scan
operationId: deleteApiDirScanDirectoriesByDirectoryIDScan
x-operation-id-source: derived
/api/dir-scan/webhook/scan:
post:
tags:
- Dir Scan
summary: Trigger a directory scan from an external webhook
description: 'Accepts a plain `path` payload or native Sonarr, Radarr, Lidarr, or Readarr webhook payloads.
qui accepts `eventType: test` payloads as a no-op health check. For real events,
it extracts the path, matches it against enabled scan directories using longest-prefix matching,
and starts a scan rooted at the provided path subtree.'
security:
- ApiKeyAuth: []
- SessionAuth: []
- ApiKeyQuery: []
requestBody:
required: true
content:
application/json:
schema:
description: Plain path payload or native *arr webhook payload.
oneOf:
- type: object
required:
- path
properties:
path:
type: string
description: Plain path to match against configured scan directories.
example: /data/media/movies/Movie Name (2024)
downloadClient:
type: string
description: Optional *arr download client name used for per-directory webhook filtering.
- type: object
required:
- series
properties:
eventType:
type: string
downloadClient:
type: string
series:
type: object
required:
- path
properties:
path:
type: string
- type: object
required:
- movie
properties:
eventType:
type: string
downloadClient:
type: string
movie:
type: object
required:
- folderPath
properties:
folderPath:
type: string
- type: object
required:
- artist
properties:
eventType:
type: string
downloadClient:
type: string
artist:
type: object
required:
- path
properties:
path:
type: string
- type: object
required:
- author
properties:
eventType:
type: string
downloadClient:
type: string
author:
type: object
required:
- path
properties:
path:
type: string
- type: object
required:
- eventType
properties:
eventType:
type: string
enum:
- test
responses:
'200':
description: Webhook accepted but scan skipped by directory filters
content:
application/json:
schema:
type: object
properties:
skipped:
type: boolean
reason:
type: string
required:
- skipped
- reason
'202':
description: Scan started
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanTriggerResponse'
'204':
description: Test webhook accepted; no scan started
'400':
description: Invalid request body or no supported path found in payload
'404':
description: No enabled directory matched the provided path
'409':
description: More than one enabled directory matches the path
'500':
description: Failed to start scan
operationId: postApiDirScanWebhookScan
x-operation-id-source: derived
/api/dir-scan/directories/{directoryID}/status:
get:
tags:
- Dir Scan
summary: Get directory scan status
description: 'Returns the queued and running scan runs of the directory. A directory can have a full scan
and a webhook scan in progress at the same time. If no run is queued or running, the list holds
the most recent run. A directory without runs returns an empty list.'
parameters:
- $ref: '#/components/parameters/directoryID'
responses:
'200':
description: Current scan status
content:
application/json:
schema:
$ref: '#/components/schemas/DirScanStatus'
'404':
description: Directory not found
'500':
description: Failed to get scan status
operationId: getApiDirScanDirectoriesByDirectoryIDStatus
x-operation-id-source: derived
/api/dir-scan/directories/{directoryID}/runs:
get:
tags:
- Dir Scan
summary: List directory scan runs
description: Returns recent scan runs for a directory
parameters:
- $ref: '#/components/parameters/directoryID'
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
description: Maximum number of runs to return
responses:
'200':
description: Scan runs
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DirScanRun'
'404':
description: Directory not found
'500':
description: Failed to list runs
operationId: getApiDirScanDirectoriesByDirectoryIDRuns
x-operation-id-source: derived
/api/dir-scan/directories/{directoryID}/runs/{runID}/injections:
get:
tags:
- Dir Scan
summary: List directory scan run injections
description: Returns injection attempts (added/failed) for a scan run
parameters:
- $ref: '#/components/parameters/directoryID'
- $ref: '#/components/parameters/runID'
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 200
description: Maximum number of items to return
- name: offset
in: query
schema:
type: integer
minimum: 0
description: Offset for pagination
responses:
'200':
description: Injection attempts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DirScanRunInjection'
'404':
description: Directory or run not found
'500':
description: Failed to list run injections
operationId: getApiDirScanDirectoriesByDirectoryIDRunsByRunIDInjections
x-operation-id-source: derived
/api/dir-scan/directories/{directoryID}/files:
get:
tags:
- Dir Scan
summary: List directory scan files
description: Returns tracked files for a directory with optional status filtering
parameters:
- $ref: '#/components/parameters/directoryID'
- name: status
in: query
schema:
$ref: '#/components/schemas/DirScanFileStatus'
description: Filter files by status
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 1000
description: Maximum number of items to return
- name: offset
in: query
schema:
type: integer
minimum: 0
description: Offset for pagination
responses:
'200':
description: Tracked files
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DirScanFile'
'404':
description: Directory not found
'500':
description: Failed to list files
operationId: getApiDirScanDirectoriesByDirectoryIDFiles
x-operation-id-source: derived
components:
parameters:
runID:
name: runID
in: path
required: true
schema:
type: integer
description: Directory scan run ID
directoryID:
name: directoryID
in: path
required: true
schema:
type: integer
description: Directory scan directory ID
schemas:
DirScanRequeueResponse:
type: object
properties:
requeued:
type: integer
format: int64
description: Number of files reset to pending
required:
- requeued
DirScanSettingsPatch:
type: object
properties:
enabled:
type: boolean
matchMode:
$ref: '#/components/schemas/DirScanMatchMode'
sizeTolerancePercent:
type: number
format: double
minPieceRatio:
type: number
format: double
maxSearcheesPerRun:
type: integer
maxSearcheeAgeDays:
type: integer
allowPartial:
type: boolean
skipPieceBoundarySafetyCheck:
type: boolean
startPaused:
type: boolean
downloadMissingFiles:
type: boolean
category:
type: string
tags:
type: array
items:
type: string
DirScanRunStatus:
type: string
enum:
- queued
- scanning
- searching
- injecting
- success
- failed
- canceled
DirScanDirectory:
type: object
properties:
id:
type: integer
path:
type: string
qbitPathPrefix:
type: string
nullable: true
category:
type: string
nullable: true
tags:
type: array
items:
type: string
allowedDownloadClients:
type: array
items:
type: string
enabled:
type: boolean
arrInstanceId:
type: integer
nullable: true
targetInstanceId:
type: integer
scanIntervalMinutes:
type: integer
skipIndividualEpisodes:
type: boolean
description: Skip searches for single TV episodes. Season packs are still searched.
lastScanAt:
type: string
format: date-time
nullable: true
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
required:
- id
- path
- tags
- allowedDownloadClients
- enabled
- targetInstanceId
- scanIntervalMinutes
- skipIndividualEpisodes
- createdAt
- updatedAt
DirScanDirectoryPatch:
type: object
properties:
path:
type: string
qbitPathPrefix:
type: string
category:
type: string
tags:
type: array
items:
type: string
allowedDownloadClients:
type: array
items:
type: string
enabled:
type: boolean
arrInstanceId:
type: integer
description: Set to -1 to clear
targetInstanceId:
type: integer
scanIntervalMinutes:
type: integer
skipIndividualEpisodes:
type: boolean
DirScanRun:
type: object
properties:
id:
type: integer
directoryId:
type: integer
status:
$ref: '#/components/schemas/DirScanRunStatus'
triggeredBy:
type: string
scanRoot:
type: string
description: Effective scan root for the run. Empty when the run scanned the configured directory path.
filesFound:
type: integer
filesSkipped:
type: integer
matchesFound:
type: integer
torrentsAdded:
type: integer
errorMessage:
type: string
nullable: true
startedAt:
type: string
format: date-time
completedAt:
type: string
format: date-time
nullable: true
required:
- id
- directoryId
- status
- triggeredBy
- filesFound
- filesSkipped
- matchesFound
- torrentsAdded
- startedAt
DirScanFileStatus:
type: string
enum:
- pending
- matched
- no_match
- error
- already_seeding
- in_qbittorrent
DirScanRunInjectionStatus:
type: string
enum:
- added
- failed
DirScanTriggerResponse:
type: object
properties:
runId:
type: integer
format: int64
description: Started scan run ID.
directoryId:
type: integer
description: Matched dir-scan directory ID.
directoryPath:
type: string
description: Matched dir-scan directory path.
scanRoot:
type: string
description: Effective scan root for this run.
required:
- runId
- directoryId
- directoryPath
- scanRoot
DirScanRunInjection:
type: object
properties:
id:
type: integer
runId:
type: integer
directoryId:
type: integer
status:
$ref: '#/components/schemas/DirScanRunInjectionStatus'
searcheeName:
type: string
torrentName:
type: string
infoHash:
type: string
contentType:
type: string
indexerName:
type: string
nullable: true
trackerDomain:
type: string
nullable: true
trackerDisplayName:
type: string
nullable: true
linkMode:
type: string
nullable: true
savePath:
type: string
nullable: true
category:
type: string
nullable: true
tags:
type: array
items:
type: string
errorMessage:
type: string
nullable: true
createdAt:
type: string
format: date-time
required:
- id
- runId
- directoryId
- status
- searcheeName
- torrentName
- infoHash
- contentType
- tags
- createdAt
DirScanFile:
type: object
properties:
id:
type: integer
directoryId:
type: integer
filePath:
type: string
fileSize:
type: integer
format: int64
fileModTime:
type: string
format: date-time
status:
$ref: '#/components/schemas/DirScanFileStatus'
matchedTorrentHash:
type: string
nullable: true
matchedIndexerId:
type: integer
nullable: true
searchedIndexerIds:
type: array
items:
type: integer
nullable: true
description: Indexer IDs that the search covered when the file was stamped no_match
lastProcessedAt:
type: string
format: date-time
nullable: true
required:
- id
- directoryId
- filePath
- fileSize
- fileModTime
- status
DirScanDirectoryCreate:
type: object
properties:
path:
type: string
qbitPathPrefix:
type: string
category:
type: string
tags:
type: array
items:
type: string
allowedDownloadClients:
type: array
items:
type: string
enabled:
type: boolean
arrInstanceId:
type: integer
nullable: true
targetInstanceId:
type: integer
scanIntervalMinutes:
type: integer
skipIndividualEpisodes:
type: boolean
required:
- path
- targetInstanceId
DirScanStatus:
type: object
properties:
runs:
type: array
items:
$ref: '#/components/schemas/DirScanRun'
required:
- runs
DirScanSettings:
type: object
properties:
id:
type: integer
enabled:
type: boolean
matchMode:
$ref: '#/components/schemas/DirScanMatchMode'
sizeTolerancePercent:
type: number
format: double
minPieceRatio:
type: number
format: double
description: Minimum percent of torrent pieces that must already exist on disk for partial matches
maxSearcheesPerRun:
type: integer
description: Maximum eligible searchees to process per scan run (0 = unlimited)
maxSearcheeAgeDays:
type: integer
description: Skip searchees older than this many days using file modification time (0 = disabled)
allowPartial:
type: boolean
skipPieceBoundarySafetyCheck:
type: boolean
startPaused:
type: boolean
downloadMissingFiles:
type: boolean
category:
type: string
tags:
type: array
items:
type: string
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
required:
- id
- enabled
- matchMode
- sizeTolerancePercent
- minPieceRatio
- maxSearcheesPerRun
- maxSearcheeAgeDays
- allowPartial
- skipPieceBoundarySafetyCheck
- startPaused
- downloadMissingFiles
- category
- tags
- createdAt
- updatedAt
DirScanMatchMode:
type: string
enum:
- strict
- flexible
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: API key for authentication
ApiKeyQuery:
type: apiKey
in: query
name: apikey
description: API key via query parameter for external webhook integrations
SessionAuth:
type: apiKey
in: cookie
name: qui_user_session
description: 'Browser session cookie set by the qui web UI. POST, PUT, PATCH, and DELETE
requests authenticated by this cookie must also send an `X-Requested-With`
header. Other clients should use an API key.
'