Torznab API
Trackarr implements the Torznab API specification, enabling seamless integration with the *arr ecosystem including Prowlarr, Sonarr, Radarr, and Lidarr.
Overview
Torznab is an extension of the Newznab API tailored for torrent indexers. It provides a standardized interface that automation tools use to search and download torrents.
Features
- 🔍 Full-text search with category filtering
- 📺 TV search with season/episode parsing
- 🎬 Movie search with IMDB support
- 🔐 Passkey authentication for secure API access
- 📦 Personalized downloads with announce URL injection
Setup with Prowlarr
Step 1: Get Your Passkey
- Log in to Trackarr
- Click your username in the top-right → Passkey
- Copy your Passkey (40-character hex string)
Step 2: Add Indexer in Prowlarr
- Open Prowlarr → Indexers → Add Indexer
- Select Generic Torznab
- Configure:
| Field | Value |
|---|---|
| Name | Trackarr |
| URL | https://your-tracker.com/api/torznab |
| API Key | Your passkey from Step 1 |
- Click Test to verify the connection
- Click Save
Step 3: Sync with *arr Apps
Prowlarr will automatically sync Trackarr as an indexer to your connected Sonarr, Radarr, and Lidarr instances.
API Endpoints
All endpoints are accessed via a single base URL with function parameters:
GET /api/torznab?t={function}&apikey={passkey}&...Capabilities (t=caps)
Returns XML describing indexer capabilities. No authentication required.
curl "https://your-tracker.com/api/torznab?t=caps"Response: XML with supported search types and categories.
Search (t=search)
General torrent search.
curl "https://your-tracker.com/api/torznab?t=search&apikey=YOUR_PASSKEY&q=ubuntu"| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | No | Search query |
cat | string | No | Comma-separated Newznab category IDs |
limit | integer | No | Max results (default: 25, max: 100) |
offset | integer | No | Result offset for pagination |
TV Search (t=tvsearch)
Search with TV-specific parameters.
curl "https://your-tracker.com/api/torznab?t=tvsearch&apikey=YOUR_PASSKEY&q=Breaking+Bad&season=1&ep=1"| Parameter | Type | Description |
|---|---|---|
season | string | Season number |
ep | string | Episode number |
Movie Search (t=movie)
Search with movie-specific parameters.
curl "https://your-tracker.com/api/torznab?t=movie&apikey=YOUR_PASSKEY&imdbid=tt0111161"| Parameter | Type | Description |
|---|---|---|
imdbid | string | IMDB ID (e.g., tt1234567) |
Download
Download a torrent file with your passkey embedded.
curl -O "https://your-tracker.com/api/torznab/download?id=INFO_HASH&apikey=YOUR_PASSKEY"Federated releases (opt-in)
By default the feed carries only this instance's own catalogue. An admin can turn on Federated releases (Admin → Torznab) to also fold in releases mirrored from federated partners.
Because the mirror is metadata only — there is no .torrent held here — a federated item's download link is a magnet built from its infohash, and its <link> points at the on-site /federated/<id> detail page rather than a download endpoint. The magnet carries only the infohash and a display name — no tracker (tr=), because an announce URL on this software carries a passkey. It is therefore resolvable through DHT/PEX alone, which a partner's private swarm does not answer: for an *arr stack these results are genuinely grabbable only for content that is also publicly seeded (or once a data-sharing path makes a partner's release retrievable from here). That is why the toggle is off by default — turning it on trades a fuller search for the chance of un-grabbable results in automation.
Federated items are appended after local ones, and within a page never duplicate an infohash the local catalogue already serves. (The dedupe is per response: with offset past the first page the same federated rows can reappear, since the mirror read is not paginated.)
Their emitted Newznab id comes from the release's coarse type — movie → 2000, tv → 5000, game → 4000, book → 7000, anything else → 8000 (Other) — not from the taxonomy mapping; the <category> element carries the partner's raw slug. The mapping (Admin → Federated taxonomy) governs which mirrored rows a cat= query matches, not the id they are labelled with.
The same toggle also folds mirrored rows into /api/rss/category/<slug>, there with no magnet and no enclosure — the RSS link is the on-site detail page, so that surface is discovery only. Both feeds respect the requesting account's adult-content setting.
Category Mapping
Trackarr categories are automatically mapped to Newznab standard IDs:
| Newznab ID | Category | Trackarr Slugs |
|---|---|---|
| 2000 | Movies | movies |
| 2040 | Movies/HD | movies-hd |
| 2045 | Movies/UHD | movies-uhd, movies-4k |
| 5000 | TV | tv |
| 5040 | TV/HD | tv-hd |
| 5045 | TV/UHD | tv-uhd, tv-4k |
| 5070 | TV/Anime | anime, tv-anime |
| 3000 | Audio | audio, music |
| 4050 | PC/Games | games, games-pc |
| 7020 | Books/Ebook | ebooks, books |
Quick Setup: Seed Torznab Categories
For new installations, Trackarr provides a one-click solution to create Torznab-compatible categories:
- Go to Admin Panel → Categories
- If no categories exist, click Seed Torznab Categories
- This creates the following structure:
| Category | Newznab ID | Subcategories |
|---|---|---|
| Movies | 2000 | HD (2040), UHD/4K (2045), SD (2030), Blu-Ray (2050) |
| TV | 5000 | HD (5040), UHD/4K (5045), SD (5030), Anime (5070), Documentary (5080) |
| Audio | 3000 | MP3 (3010), Lossless (3040) |
| Games | 4050 | PC (4050), Console (1000), PlayStation (1180), Xbox (1040) |
| Software | 4000 | Windows (4020), Mac (4030) |
| Books | 7000 | Ebooks (7020), Comics (7030), Magazines (7010) |
| XXX | 6000 | — |
| Other | 8000 | — |
TIP
All seeded categories include proper Newznab IDs, ensuring immediate compatibility with Prowlarr, Sonarr, Radarr, and Lidarr without any additional configuration.
WARNING
The seed button only appears when no categories exist. To re-seed, delete all existing categories first.
Response Format
Search results are returned as RSS 2.0 with Torznab namespace extensions:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:torznab="http://torznab.com/schemas/2015/feed">
<channel>
<title>Trackarr</title>
<item>
<title>Example.Movie.2024.1080p.BluRay</title>
<guid>abc123...</guid>
<pubDate>Wed, 08 Jan 2025 10:00:00 +0000</pubDate>
<size>4500000000</size>
<torznab:attr name="category" value="2000"/>
<torznab:attr name="size" value="4500000000"/>
<torznab:attr name="seeders" value="25"/>
<torznab:attr name="peers" value="5"/>
<torznab:attr name="grabs" value="112"/>
<torznab:attr name="downloadvolumefactor" value="0"/>
<torznab:attr name="uploadvolumefactor" value="1"/>
<torznab:attr name="infohash" value="abc123..."/>
<torznab:attr name="minimumratio" value="0.6"/>
<torznab:attr name="minimumseedtime" value="86400"/>
<torznab:attr name="imdbid" value="tt1234567"/>
<enclosure url="https://..." type="application/x-bittorrent"/>
</item>
</channel>
</rss>Attributes
| Attribute | Source | Notes |
|---|---|---|
category | mapped Newznab id | 8000 (Other) when nothing maps |
size, seeders, peers, grabs | catalogue + live swarm | — |
downloadvolumefactor | the running bonus event | 0 during a freeleech, 0.5 during a silverleech, 1 otherwise |
uploadvolumefactor | the running bonus event | 1 normally |
infohash | torrents.info_hash | v1 hash, hex. Lets a consumer match a release against torrents it already holds without fetching the .torrent |
minimumratio | min_ratio setting | Omitted when the site sets no minimum |
minimumseedtime | hnr_required_seed_time setting | Seconds. Omitted unless hit-and-run is enabled |
imdbid, tmdbid, tvdbid | stored external ids | TMDb is emitted bare (no tv/ or movie/ prefix) |
The two obligation attributes are the same numbers the tracker already enforces — a minimum ratio at announce time, a required seed time as a hit-and-run sanction. Sending them in the feed lets a client honour them by itself instead of finding out when the gate closes.
NOTE
Both are site-wide settings, so every item on a page carries the same pair. Per-torrent multipliers and per-torrent seeding requirements do not exist yet; when they do, these attributes are already the right channel.
Volume factors reflect what the site is doing at the moment of the request. A client that grabbed during a freeleech and re-reads the feed afterwards will see 1 — the attribute describes the site's current rates, not a promise attached to the release.
Mirrored (federated) items carry infohash but no obligations and neutral volume factors: those belong to the instance that actually holds the release, and this instance does not mirror them.
Error Handling
Errors are returned as XML:
<?xml version="1.0" encoding="UTF-8"?>
<error code="100" description="Incorrect user credentials"/>| Code | Description |
|---|---|
| 100 | Incorrect user credentials |
| 101 | Account suspended |
| 200 | Missing parameter |
| 201 | Incorrect parameter |
| 300 | No such function |
Security Notes
- HTTPS Only: Always use HTTPS to protect your passkey
- Passkey = Identity: Treat your passkey as a secret; anyone with it can download as you
- Rate Limits: API is rate limited to prevent abuse (see below)
Rate Limits
Torznab endpoints are protected by a configurable rate limiting system. Default limits:
| Endpoint | Limit | Window |
|---|---|---|
| Search | 30 requests | 1 minute |
| Download | 20 requests | 1 minute |
Exceeding these limits will result in a 429 Too Many Requests error. Repeated violations may result in temporary IP blacklisting with progressive penalties (5 min → 10 min → 20 min → up to 24h).
Admin Configuration
Rate limits can be configured from the Admin Panel → Torznab API page:
- Time Window: Duration for rate limit calculations (10-3600 seconds)
- Search Limit: Max search requests per window per user
- Download Limit: Max download requests per window per user
Admins can also:
- Enable/disable the Torznab API entirely
- Enable/disable request logging
- View real-time API statistics and usage
- Block specific users from API access
- Reset user passkeys
- View blocked IPs and users
Admin Panel Features
The Torznab API admin panel (/admin/torznab) provides comprehensive management:
API Statistics
- Total requests, last 24h requests
- Unique API users
- Average response time
- Breakdown by function type (search, tvsearch, movie, download)
- Error count tracking
Configuration
- Enable/disable API globally
- Toggle request logging
- Copy API endpoint URL
Rate Limiting
- Adjustable time window (10s - 1h)
- Configurable search/download limits per user
- Quick presets (Strict, Default, Relaxed, Generous)
User Management
- View all users with API access
- See per-user request counts and rate limit violations
- Reset user passkeys
- Block users from API access
- View per-user request logs
A block is recorded against the member, not against the key they happen to be holding. It is stored under a hash of their announce passkey, and every route that rotates that passkey — the member's own settings page included — moves the block onto the replacement, keeping the original reason and date. So resetting a leaked passkey does not quietly lift a restriction, and a blocked member cannot lift it themselves by minting a new key. Unblocking is its own action, under Blacklist Management.
If Redis is unreachable, a rotation is refused rather than performed without the block following it: the member is told to try again, and their passkey is unchanged.
Request Logs
- Real-time log of recent API requests
- Function type, query, results, response time
- Error tracking
Blacklist Management
- View currently rate-limited IPs
- View manually blocked users
- Unblock users as needed
Troubleshooting
"Incorrect user credentials" error
- Verify your passkey is correct (40 hex characters)
- Check that your account is not banned
- Ensure you're using the correct tracker URL
No results returned
- Try a broader search query
- Check that the category filter matches available content
- Verify torrents exist in the requested categories
Connection timeout
- Confirm the tracker URL is accessible
- Check firewall rules allow outbound HTTPS
- Try the capabilities endpoint first to test connectivity
Prowlarr: a ready-made indexer definition
GET /api/torznab/cardigann.yml returns a Cardigann definition for this instance, with its name, its URL and its own categories already filled in.
curl -O https://tracker.example/api/torznab/cardigann.yml
# then drop it in Prowlarr's Definitions/Custom folder:
# Docker /config/Definitions/Custom/
# Linux/macOS ~/.config/Prowlarr/Definitions/Custom/
# Windows C:\ProgramData\Prowlarr\Definitions\Custom\Restart Prowlarr, add the tracker by name, and paste your RSS key (see Keys — not the announce passkey).
Members can download it straight from their profile page, beside the key itself.
Why it is generated rather than shipped in the repo
The categories. They are operator-configured — names, slugs and Newznab mappings all live in the database — so a static file could describe every instance's categories except the one the member is actually joining.
Two things operators should know
Reloading is unreliable offline. Prowlarr's IndexerDefinitionUpdate command downloads the official definition pack first and only clears its cache afterwards, inside the same try. On a host with no egress to indexers.prowlarr.com the exception is swallowed and the cache is never cleared — restart Prowlarr instead. There is also a five-minute rolling cache on the request generator.
Renaming the instance means renaming the file. Prowlarr keys a custom definition on its filename, and refuses to load one whose filename or name collides with a built-in — the built-in wins and yours is dropped with nothing but a line in the log. The generated file is named after your site, so if you rename the site, re-download it and remove the old file.
What the definition maps
Every <torznab:attr> this feed emits, including infohash, both volume factors and — where the site imposes them — minimumratio and minimumseedtime. Note that the selectors address attributes rather than elements ([name=seeders] + attribute: value): a namespace-prefixed element cannot be cleanly addressed in CSS, which is why every Cardigann definition that consumes a Torznab feed is written this way.