Skip to main content

YAML indexer definitions

This reference documents the YAML format for defining custom indexers in Cinephage.

Overview

Cinephage uses a unified YAML-only indexer architecture. All indexers are defined entirely through YAML files — no code changes needed to add new indexers.

Architecture Features

  • YAML-only definitions — All indexer logic in declarative YAML files
  • Protocol handlers — Separate handlers for torrent, usenet, and streaming protocols
  • Dynamic capability discovery — Automatically fetches /api?t=caps to determine supported search parameters
  • Enhanced health tracking — Tracks consecutive failures with exponential backoff
  • Protocol-specific settings — Custom columns for torrent, usenet, and streaming configurations

Protocol Support

ProtocolHandlerFeatures
TorrenttorrentMagnet links, .torrent files, CSS selectors
UsenetusenetNewznab API, NZB downloads
StreamingstreamingHLS streams, CORS proxy integration

Dynamic Capability Discovery

Newznab-compatible indexers (including UNIT3D trackers) automatically discover capabilities:

name: My UNIT3D Tracker
protocol: usenet
categories:
- movies
- tv
settings:
apiUrl: https://tracker.example.com/api
apiKey: your-api-key
# Capabilities fetched from /api?t=caps automatically

This allows the indexer to:

  • Know which search parameters are supported
  • Optimize search requests
  • Handle different Newznab implementations

YAML Structure

Basic Template

name: Display Name # Human-readable name (required)
protocol: torrent # torrent, usenet, or streaming (required)
categories: # Supported content types (required)
- movies
- tv
enabled: true # Enable/disable (default: true)
priority: 25 # Search priority 1-50 (default: 25)
description: Optional description
settings: # Protocol-specific settings
# See protocol sections below

Required Fields

FieldTypeDescription
idstringUnique identifier (alphanumeric, hyphens, underscores)
namestringDisplay name shown in UI
protocolstringtorrent, usenet, or streaming
categoriesarrayContent types: movies, tv
settingsobjectProtocol-specific configuration

Optional Fields

FieldTypeDefaultDescription
enabledbooleantrueWhether indexer is active
priorityinteger25Search priority (lower = higher priority)
descriptionstring-Optional description

Torrent Indexers

Basic Torrent Definition

name: Example Torrent Site
protocol: torrent
categories:
- movies
- tv
enabled: true
priority: 20
settings:
baseUrl: https://example.com
search:
path: /search?q={{query}}
method: GET
selectors:
rows: table.results tr
title: td.title a
magnet: td.magnet a
torrent: td.download a
size: td.size
seeders: td.seeders
leechers: td.leechers
date: td.date

Search Configuration

settings:
baseUrl: https://example.com
search:
path: /search?q={{query}}&page={{page}}&category={{category}}
method: GET
headers:
User-Agent: Mozilla/5.0
Accept: text/html
cookies:
session: abc123

Search Variables:

VariableDescriptionExample
{{query}}Search term"Inception 2010"
{{page}}Page number1, 2, 3
{{category}}Category IDmovies, tv
{{year}}Release year2010

CSS Selectors

Define how to extract data from HTML:

selectors:
rows: string # CSS selector for result rows
title: string # Title element within row
magnet: string # Magnet link element
torrent: string # Torrent file link element
size: string # File size element
seeders: string # Seeders count element
leechers: string # Leechers count element
date: string # Upload date element
category: string # Category element

Selector Examples:

selectors:
rows: tr.result-row
title: td.name a
magnet: a[href^="magnet:"]
torrent: a[href$=".torrent"]
size: td.size text() # Extract text content
seeders: td.peers span.seeders

Attribute Extraction

Extract specific attributes:

selectors:
magnet:
selector: a.magnet-link
attribute: href # Extract href attribute

title:
selector: a.title
attribute: title # Extract title attribute

size:
selector: td.size
regex: '(\d+\.?\d*)\s*(GB|MB|KB)' # Extract with regex

Authentication

For sites requiring login:

settings:
baseUrl: https://example.com
auth:
type: cookie
cookies:
uid: your-user-id
pass: your-pass-key

# Or using headers
search:
headers:
Authorization: Bearer YOUR_API_KEY
X-API-Key: YOUR_KEY

Advanced: Login Flow

For sites requiring form login:

settings:
baseUrl: https://example.com
auth:
type: form
loginUrl: /login
usernameField: username
passwordField: password
submitButton: input[type="submit"]
successCheck: .user-profile # Element that exists after login

Usenet Indexers (Newznab)

Standard Newznab

name: NZBGeek
protocol: usenet
categories:
- movies
- tv
settings:
apiUrl: https://api.nzbgeek.info/
apiKey: your-api-key
categories:
movies: 2000
tv: 5000
timeout: 30
retries: 3

Newznab Settings

settings:
apiUrl: string # API endpoint URL
apiKey: string # Your API key
username: string # Username (if required)
password: string # Password (if required)

categories: # Category mappings
movies: integer # Movies category ID
tv: integer # TV category ID

timeout: integer # Request timeout seconds (default: 30)
retries: integer # Retry attempts (default: 3)
rateLimit: integer # Requests per minute (optional)

Common Newznab Categories

IDCategory
2000Movies
2010Movies/Foreign
2040Movies/HD
2050Movies/BluRay
2060Movies/3D
5000TV
5040TV/HD
5050TV/Foreign
5080TV/Documentary

Streaming Indexers

Basic Streaming Definition

name: Example Streaming
protocol: streaming
categories:
- movies
- tv
settings:
baseUrl: https://api.example.com
apiKey: your-api-key
timeout: 30
endpoints:
search: /v1/search
resolve: /v1/resolve

Streaming Settings

settings:
baseUrl: string # Base API URL
apiKey: string # API key
apiSecret: string # API secret (if required)

timeout: integer # Request timeout seconds (default: 30)

endpoints: # API endpoints
search: string # Search endpoint
resolve: string # Stream resolution endpoint

headers: # Custom headers
X-Custom-Header: value

Torznab Indexers (via Jackett/Prowlarr)

name: 1337x via Jackett
protocol: torrent
categories:
- movies
- tv
settings:
apiUrl: http://jackett:9117/api/v2.0/indexers/1337x/results/torznab/
apiKey: your-jackett-api-key
categories:
movies: 2000
tv: 5000

Practical Examples

This section provides complete, working indexer definitions demonstrating common patterns and configurations.

Example 1: Basic Public Tracker

Public tracker with simple search form and no authentication.

When to use this pattern:

  • Open torrent sites accessible without login
  • Sites using standard HTML table layouts
  • Public domain or open trackers
# Basic public torrent tracker
# 1337x.to - Simple search with table results
name: 1337x
protocol: torrent
categories:
- movies
- tv
priority: 25
settings:
baseUrl: https://1337x.to
search:
# {{query}} is URL-encoded automatically
path: /search/{{query}}/1/
method: GET
selectors:
# Each row in the results table
rows: table.table-list tbody tr
# Second link in the name column (first is category)
title: td.name a:nth-child(2)
# Direct magnet link
magnet: td.coll-1 a[href^="magnet:"]
# Size column text
size: td.size
# Seeders count
seeders: td.seeds
# Leechers count
leechers: td.leeches
# Upload date
date: td.date

Example 2: Private Tracker with Authentication

Private tracker requiring cookie-based authentication.

When to use this pattern:

  • Private trackers requiring login
  • Sites with cookie/session-based auth
  • When API keys are not available
# Private tracker with cookie authentication
# Requires session cookies from browser
name: Private Tracker
protocol: torrent
categories:
- movies
- tv
priority: 10
settings:
baseUrl: https://tracker.example.com
auth:
type: cookie
cookies:
# Get these from browser dev tools after logging in
uid: 12345
pass: abcdef1234567890
session: xyz789
search:
path: /torrents.php?search={{query}}&category={{category}}
headers:
# Some sites check User-Agent
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
selectors:
rows: table.torrents tr.torrent
title: td.name a
# Direct .torrent download link
torrent: td.download a
size: td.size
seeders: td.seeders
leechers: td.leechers
date: td.date

Example 3: Usenet Indexer (Newznab API)

Standard Newznab-compatible usenet indexer.

When to use this pattern:

  • Newznab-compatible sites (NZBGeek, DrunkenSlug, etc.)
  • UNIT3D-based private trackers with API
  • Any site supporting Newznab standard
# Usenet indexer using Newznab API
# NZBGeek - Newznab-compatible
name: NZBGeek
protocol: usenet
categories:
- movies
- tv
priority: 5
settings:
# API endpoint (trailing slash required for some)
apiUrl: https://api.nzbgeek.info/
# Your personal API key from account settings
apiKey: YOUR_API_KEY_HERE
# Category mapping to Newznab IDs
categories:
movies: 2000
tv: 5000
# Connection settings
timeout: 30
retries: 3
rateLimit: 60 # Max requests per minute

Example 4: Torznab via Jackett

Torrent indexer accessed through Jackett's Torznab API.

When to use this pattern:

  • Accessing trackers through Jackett/Prowlarr
  • Unified API for multiple torrent sources
  • When direct access is not possible
# Torznab indexer via Jackett
# Accesses torrent sites through Jackett's API
name: 1337x via Jackett
protocol: torrent
categories:
- movies
- tv
priority: 15
settings:
# Jackett torznab endpoint for specific indexer
apiUrl: http://jackett:9117/api/v2.0/indexers/1337x/results/torznab/
# Jackett API key from Jackett UI
apiKey: your-jackett-api-key
categories:
movies: 2000
tv: 5000
timeout: 30

Indexer with pagination support and complex selectors.

When to use this pattern:

  • Sites with paginated results
  • Complex HTML structures
  • When extracting additional metadata
# Advanced tracker with pagination and complex selectors
name: Advanced Tracker
protocol: torrent
categories:
- movies
- tv
settings:
baseUrl: https://tracker.example.com
search:
# Page variable for pagination
path: /search?q={{query}}&p={{page}}&cat={{category}}
method: GET
selectors:
rows: div.torrent-row
# Extract title from data attribute
title:
selector: a.torrent-title
attribute: data-title
# Extract magnet from href
magnet:
selector: a[href^="magnet:"]
attribute: href
# Extract size with regex
size:
selector: span.size
regex: '([\d.]+\s*[GMTK]B)'
# Extract seeders, remove non-numeric
seeders:
selector: span.seeders
regex: '(\d+)'
# Category extraction
category:
selector: span.category
attribute: data-category

Example 6: Special Date Parsing

Indexer with custom date format parsing.

When to use this pattern:

  • Non-standard date formats
  • Relative dates ("2 hours ago")
  • Multiple date formats on same site
# Tracker with custom date parsing
name: Date Format Tracker
protocol: torrent
categories:
- movies
- tv
settings:
baseUrl: https://tracker.example.com
search:
path: /search?q={{query}}
selectors:
rows: tr.result
title: td.title a
magnet: td.magnet a
size: td.size
seeders: td.seeders
# Date with multiple format support
date:
selector: td.date
# Supports common formats automatically
# ISO 8601: 2024-01-15
# US: 01/15/2024
# European: 15/01/2024
# Unix timestamp
# Relative: "2 hours ago", "Yesterday"

Example 7: UNIT3D Private Tracker

UNIT3D-based private tracker with full API support.

When to use this pattern:

  • Modern private trackers using UNIT3D
  • API-based authentication
  • Dynamic capability discovery
# UNIT3D private tracker with Newznab API
# OldToons.World - Classic animation tracker
name: OldToons.World
protocol: usenet
categories:
- tv
enabled: true
priority: 15
description: Private UNIT3D tracker for classic animated content
settings:
apiUrl: https://oldtoons.world/api
apiKey: YOUR_API_KEY_HERE
categories:
tv: 5000
timeout: 30
retries: 3
rateLimit: 60

Example 8: Streaming Provider

Basic streaming service indexer.

When to use this pattern:

  • HLS/DASH streaming services
  • API-based content providers
  • Sites requiring stream resolution
# Streaming provider with API
name: Streaming Provider
protocol: streaming
categories:
- movies
- tv
priority: 5
settings:
baseUrl: https://api.streaming.example.com
apiKey: YOUR_API_KEY
timeout: 30
endpoints:
# Search for content
search: /v1/search
# Resolve stream URLs
resolve: /v1/resolve

Common Patterns

This section describes recurring patterns across indexer definitions.

Authentication Methods

For sites requiring session cookies.

auth:
type: cookie
cookies:
uid: "your-user-id"
pass: "your-pass-key"
session: "session-token"

Form Login

For sites with traditional login forms.

auth:
type: form
loginUrl: /login
usernameField: username
passwordField: password
submitButton: input[type="submit"]
successCheck: .user-profile

API Key Authentication

For API-based access.

# In search headers
search:
headers:
Authorization: Bearer YOUR_API_KEY
X-API-Key: YOUR_KEY

# Or in settings
settings:
apiKey: YOUR_API_KEY

Search Field Mapping

Map Cinephage search parameters to indexer fields.

Cinephage FieldVariableExample Value
Search query{{query}}"Inception 2010"
Page number{{page}}1, 2, 3
Category{{category}}2000, 5000
Year{{year}}2010

URL construction:

search:
# Basic keyword search
path: /search?q={{query}}

# With pagination
path: /search?q={{query}}&p={{page}}

# With category filtering
path: /search?q={{query}}&cat={{category}}&page={{page}}

# Complex with all parameters
path: /browse?search={{query}}&category={{category}}&page={{page}}&year={{year}}

Result Extraction

Standard fields to extract from search results.

selectors:
# Required fields
rows: string # Container for each result
title: string # Release name/title

# At least one download method required
magnet: string # Magnet link
torrent: string # Direct .torrent link

# Optional metadata
size: string # File size (e.g., "1.5 GB")
seeders: string # Number of seeders
leechers: string # Number of leechers
date: string # Upload date
category: string # Content category

Download link priority:

  1. magnet - Preferred for torrents
  2. torrent - Direct .torrent file
  3. download - Generic download link

Date Parsing Formats

Cinephage automatically parses common date formats.

FormatExampleNotes
ISO 86012024-01-15T10:30:00ZFull timestamp
Date only2024-01-15YYYY-MM-DD
US format01/15/2024MM/DD/YYYY
European15/01/2024DD/MM/YYYY
Unix timestamp1705315800Seconds since epoch
Relative2 hours agoAutomatically converted

Category Mapping

Map content types to indexer category IDs.

# For Newznab/Torznab
settings:
categories:
movies: 2000
tv: 5000

# For torrent sites
settings:
search:
path: /browse?cat={{category}}
categories:
movies: "movies" # String categories
tv: "tv-shows"

Common category IDs:

TypeNewznab IDDescription
Movies2000All movies
Movies/HD2040HD movies
Movies/BluRay2050BluRay releases
TV5000All TV
TV/HD5040HD TV episodes
TV/Documentary5080Documentaries

Handling Pagination

Configure multi-page search results.

search:
# Page variable in URL
path: /search?q={{query}}&p={{page}}

# Or offset-based
path: /search?q={{query}}&offset={{page}}0 # page * 10

# Or page size parameter
path: /search?q={{query}}&page={{page}}&limit=50

Page variable behavior:

  • Starts at 1 for most sites
  • Incremented automatically for additional results
  • Used only when more results are needed

Error Handling

Cinephage handles common error scenarios automatically.

ErrorBehaviorConfigurable
HTTP 4xx/5xxAutomatic retry with backoffYes (retries)
TimeoutRetry with exponential backoffYes (timeout)
Parse errorLog and skip resultNo
Empty resultsContinue to next indexerNo
Auth failureMark indexer unhealthyNo

Configuration:

settings:
timeout: 30 # Seconds before timeout
retries: 3 # Number of retry attempts
rateLimit: 60 # Max requests per minute

Complete Examples

Example 1: Public Torrent Tracker

name: 1337x
protocol: torrent
categories:
- movies
- tv
priority: 25
settings:
baseUrl: https://1337x.to
search:
path: /search/{{query}}/1/
method: GET
selectors:
rows: table.table-list tbody tr
title: td.name a:nth-child(2)
magnet: td.coll-1 a[href^="magnet:"]
size: td.size
seeders: td.seeds
leechers: td.leeches
date: td.date

Example 2: Private Tracker with Login

name: Private Tracker
protocol: torrent
categories:
- movies
- tv
priority: 10
settings:
baseUrl: https://tracker.example.com
auth:
type: cookie
cookies:
uid: 12345
pass: abcdef1234567890
search:
path: /torrents.php?search={{query}}&category={{category}}
selectors:
rows: table.torrents tr.torrent
title: td.name a
torrent: td.download a
size: td.size
seeders: td.seeders
leechers: td.leechers

Example 3: Usenet Indexer

name: NZBGeek
protocol: usenet
categories:
- movies
- tv
priority: 5
settings:
apiUrl: https://api.nzbgeek.info/
apiKey: YOUR_API_KEY_HERE
categories:
movies: 2000
tv: 5000
timeout: 30
retries: 3

Example 4: Streaming Provider

name: My Streaming Service
protocol: streaming
categories:
- movies
- tv
priority: 5
settings:
baseUrl: https://api.streaming.example.com
apiKey: YOUR_API_KEY
timeout: 30
endpoints:
search: /v1/search
resolve: /v1/resolve

Example 5: UNIT3D Private Tracker (OldToons.World)

name: OldToons.World
protocol: usenet
categories:
- tv
enabled: true
priority: 15
description: Private UNIT3D tracker for classic animated content
settings:
apiUrl: https://oldtoons.world/api
apiKey: YOUR_API_KEY_HERE
categories:
tv: 5000
timeout: 30
retries: 3
rateLimit: 60

UNIT3D Tracker Notes:

  • Uses Newznab-compatible API
  • Requires API key authentication
  • Supports name and search query parameters
  • Dynamic capability discovery from /api?t=caps

Testing Indexers

Validate YAML Syntax

Before adding to Cinephage, validate YAML:

# Using Python
python3 -c "import yaml; yaml.safe_load(open('indexer.yaml'))"

# Or online validators
# https://yaml-online-parser.appspot.com/

Test Selectors

Use browser DevTools to test CSS selectors:

  1. Open the site in browser
  2. Press F12 for DevTools
  3. In Console tab, test:
    document.querySelectorAll('table.results tr');

Add to Cinephage

  1. Go to Settings > Integrations > Indexers
  2. Click Add Indexer
  3. Select YAML Definition
  4. Paste your YAML
  5. Click Validate
  6. Click Test
  7. Click Save

Troubleshooting

YAML Parse Errors

Problem: "Invalid YAML" error

Solutions:

  • Check indentation (spaces, not tabs)
  • Validate YAML syntax online
  • Check for special characters in strings
  • Use quotes around strings with colons

Selector Not Found

Problem: No results from working site

Solutions:

  • Test selectors in browser DevTools
  • Check if site uses JavaScript rendering
  • Verify selector matches actual HTML
  • Try more specific selectors

Authentication Fails

Problem: 401 or login errors

Solutions:

  • Verify credentials/cookies
  • Check if site requires 2FA
  • Try different auth type
  • Check if IP is whitelisted

Empty Results

Problem: Test succeeds but no search results

Solutions:

  • Check if search term works on site directly
  • Verify category parameters
  • Check if site requires specific search format
  • Try different query variables

Best Practices

Naming Conventions

  • Use descriptive IDs: nyaa not indexer1
  • Keep names concise but clear
  • Use consistent casing

Priority Guidelines

PriorityUse Case
1-10Primary, high-quality indexers
11-20Good indexers, regular use
21-30Backup indexers
31-50Fallback, public trackers

Categories

Only enable categories the indexer supports:

  • Movies: Movie releases
  • TV: TV series releases
  • Both: General indexers

Security

  • Never commit API keys to version control
  • Use environment variables for sensitive data
  • Rotate API keys periodically
  • Use read-only keys when available

See Also