On this pageShow
Addon Developer Guide
Build addons that extend Auddio with new audiobook sources, indexers, and debrid streaming providers. An addon is a lightweight HTTP microservice that provides search results, cache checking, catalog browsing, and stream URLs. Auddio handles the rest — playback, chapter navigation, lock screen controls, offline downloads, and library sync.
How It Works
Auddio addons operate over a decentralized, open JSON-over-HTTP protocol. You can write your addon in any backend runtime — TypeScript/Bun, Node.js, Python, Go, or Rust. The client communicates with your server using standard REST endpoints:
| Endpoint | Method | Required | Purpose |
|---|---|---|---|
/manifest.json |
GET | Yes | Declares addon identity, version, capabilities, and dynamic settings form. |
/search |
POST | Yes* | Searches trackers for candidate audiobooks matching title, author, or IDs. |
/check-cache |
POST | No | Verifies instant availability of torrent infoHashes on the user's Debrid provider. |
/resolve |
POST | Yes* | Resolves infoHashes into streamable audio URLs via our 2-step selection flow. |
/progress/:torrentId |
GET | No | Monitors active background downloading on debrid for uncached torrents. |
/info |
POST | No | Returns raw internal file layout and chapter groupings from public torrent caches. |
/airlock |
POST | No | Toggles permanent cloud caching on TorBox debrid to prevent inactivity expiry. |
/catalog/filters |
GET / POST | No | Discovers available categories (e.g. Fiction) and genres (e.g. Sci-Fi) for browsing. |
/catalog |
POST / GET | No | Returns paginated book collections filtered by category, genre, and sorting. |
* Required depending on addon type: SCRAPER requires /search; DEBRID requires /check-cache and /resolve; UNIFIED implements both.
config.fields declaration. When users install your addon URL, the mobile app creates the input UI, collects their API keys or custom proxy hosts, and includes those values in subsequent API requests automatically.
Quick Start
Developing an addon involves building an HTTP server that answers requests according to the protocol specification.
1. Create the Manifest (GET /manifest.json)
Your server must expose a manifest at /manifest.json describing its identity, capabilities, and settings requirements:
{
"id": "com.example.my-audiobook-source",
"name": "My Audiobook Source",
"version": "1.0.0",
"description": "Searches public audiobook trackers and streams via debrid",
"type": "UNIFIED",
"capabilities": ["SEARCH", "CHECK_CACHE", "RESOLVE", "PROGRESS", "CATALOG"],
"icon": "https://example.com/icon.png",
"config": {
"fields": [
{
"id": "debrid_provider",
"label": "Debrid Provider",
"type": "dropdown",
"required": true,
"default": "realdebrid",
"options": [
{ "value": "realdebrid", "label": "Real-Debrid" },
{ "value": "alldebrid", "label": "AllDebrid" }
]
},
{
"id": "debrid_api_key",
"label": "Debrid API Key",
"type": "password",
"required": true,
"placeholder": "Enter your debrid token...",
"help": "Acquire from your provider account settings"
}
]
}
}
Manifest Fields Reference
| Field | Type | Required | Description |
|---|---|---|---|
id |
String | Yes | Unique reverse-domain identifier (e.g. com.yourname.addon). |
name |
String | Yes | Display name shown in Auddio search dropdowns and addon manager. |
version |
String | Yes | Semver version string (e.g. 1.0.0). |
type |
String | Yes | Operational mode: "UNIFIED", "SCRAPER", or "DEBRID". |
capabilities |
Array | Yes | Declared features: "SEARCH", "CHECK_CACHE", "RESOLVE", "PROGRESS", "INFO", "CATALOG". |
icon |
String | No | Direct HTTPS URL to a square PNG/JPEG (recommended 128×128). |
config |
Object | No | Declares dynamic form inputs collected by client apps upon installation. |
2. Implement Search (POST /search)
Called when the user searches for an audiobook or when Auddio searches candidate sources for a book detail page:
{
"title": "Dune",
"author": "Frank Herbert",
"limit": 10
}
Respond with a list of candidate results matching the query:
{
"results": [
{
"infoHash": "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
"title": "Dune (Frank Herbert) [MP3@64kbps]",
"author": "Frank Herbert",
"narrator": "George Guidall",
"size": 322485640,
"sizeFormatted": "307.54 MiB",
"seeders": 42,
"leechers": 3,
"source": "AudioBookBay",
"format": "MP3",
"bitrate": "64kbps"
}
],
"total": 1,
"query": { "title": "Dune" }
}
3. Implement Cache Checking (POST /check-cache)
Before initiating streams, Auddio asks your addon if any candidate hashes are already cached on the user's debrid cloud for instant playback with zero waiting:
{
"provider": "realdebrid",
"apiKey": "USER_DEBRID_TOKEN",
"infoHashes": [
"a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
"b8c321e1a49c23b8fca8e4f5a112f45c99182b8a"
]
}
{
"a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f": {
"cached": true,
"torrentId": "rd_torrent_9821a"
},
"b8c321e1a49c23b8fca8e4f5a112f45c99182b8a": {
"cached": false
}
}
4. Stream Resolution & Two-Step Selection Flow (POST /resolve)
Audiobooks frequently contain dozens of individual chapter MP3s alongside PDF digital booklets and artwork. Downloading all files wastes bandwidth. Auddio implements a clean Two-Step Selection Flow:
Step 4A: Probe Request (infoHash Only)
When the user taps an audiobook, Auddio sends only the infoHash. Your addon contacts the debrid provider and inspects the files:
{
"torrentId": "rd_torrent_9821a",
"infoHash": "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
"status": "selection_required",
"files": [
{ "id": 1, "filename": "01_Dune_Chapter_1.mp3", "size": 15240291 },
{ "id": 2, "filename": "02_Dune_Chapter_2.mp3", "size": 16892010 },
{ "id": 3, "filename": "Dune_Artwork.pdf", "size": 2401822 }
]
}
Step 4B: Resolution Request (torrentId + fileIds)
Auddio auto-selects all audio tracks (or lets the user pick), and posts back with torrentId and fileIds:
{
"provider": "realdebrid",
"apiKey": "USER_DEBRID_TOKEN",
"infoHash": "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
"torrentId": "rd_torrent_9821a",
"fileIds": [1, 2]
}
{
"torrentId": "rd_torrent_9821a",
"infoHash": "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
"status": "ready",
"files": [
{
"id": 1,
"filename": "01_Dune_Chapter_1.mp3",
"url": "https://real-debrid.com/d/direct-stream-link-1",
"size": 15240291,
"status": "ready",
"mimeType": "audio/mpeg"
},
{
"id": 2,
"filename": "02_Dune_Chapter_2.mp3",
"url": "https://real-debrid.com/d/direct-stream-link-2",
"size": 16892010,
"status": "ready",
"mimeType": "audio/mpeg"
}
],
"totalSize": 32132301
}
torrentId and fileIds in its local database. When resuming listening hours or days later, Auddio executes Step 4B directly, instantly fetching fresh stream links without prompting the user.
5. Download Progress Polling (GET /progress/:torrentId)
If an audiobook was not cached, the debrid service begins downloading the torrent. Auddio polls this endpoint every 3 seconds to display download percentage and ETA:
{
"infoHash": "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
"status": "downloading",
"progress": 68.4,
"filename": "Dune Complete Audio",
"files": [
{
"id": "1",
"filename": "01_Dune_Chapter_1.mp3",
"size": 15240291,
"status": "ready"
},
{
"id": "2",
"filename": "02_Dune_Chapter_2.mp3",
"size": 16892010,
"status": "downloading"
}
]
}
6. Torrent Metadata & Layout (POST /info)
Fetches the internal flat file layout and groupings from public torrent caches without calling debrid servers:
{
"infoHash": "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
"name": "Dune Frank Herbert Complete",
"files": [
{
"fileId": 1,
"name": "01_Chapter1.mp3",
"path": "Dune/01_Chapter1.mp3",
"bookName": "Dune",
"size": 15240291,
"sizeFormatted": "14.53 MiB",
"isAudio": true
}
],
"totalSize": 15240291,
"totalSizeFormatted": "14.53 MiB"
}
7. Permanent Caching with TorBox Airlock (POST /airlock)
For addons integrating with the TorBox debrid provider, cached torrents may be automatically deleted after 30 days of inactivity. The AIRLOCK capability allows client apps to toggle permanent retention:
{
"provider": "torbox",
"apiKey": "USER_TORBOX_API_KEY",
"torrentId": "tb_torrent_49182",
"airlocked": true
}
{
"success": true,
"airlocked": true,
"torrentId": "tb_torrent_49182"
}
8. Books Catalogs & Genre Discovery
Addons supporting the CATALOG capability expose categorized collections of audiobooks for the Home, Discover, and Browse screens.
A. Discover Categories & Genres (GET /catalog/filters)
{
"categories": [
{ "id": "fiction", "name": "Fiction", "description": "Fictional audiobooks" },
{ "id": "non-fiction", "name": "Non-Fiction", "description": "Educational and biographies" },
{ "id": "bestsellers", "name": "Bestsellers", "description": "Top trending titles" }
],
"genres": [
{ "id": "sci-fi", "name": "Science Fiction" },
{ "id": "fantasy", "name": "Fantasy" },
{ "id": "mystery", "name": "Mystery & Thriller" },
{ "id": "biography", "name": "Biography & Memoir" }
]
}
B. Fetch Filtered Books (POST /catalog or GET /catalog)
Accepts category, genre, page (1-indexed), limit (default 20, max 100), and sortBy (popular, latest, title):
{
"books": [
{
"id": "B002V1OF70",
"asin": "B002V1OF70",
"title": "Dune",
"author": "Frank Herbert",
"coverUrl": "https://m.media-amazon.com/images/I/91dSMhdIzTL._SL500_.jpg"
}
],
"page": 1,
"limit": 20,
"hasMore": true,
"category": "fiction",
"genre": "sci-fi"
}
9. One-Click Install Deeplinks (auddio:///)
Auddio supports 1-click addon installation directly from web pages and GitHub readmes via custom URL schemes:
auddio:///addon/install?url=https%3A%2F%2Fmy-addon.railway.app%2Fmanifest.json&debrid_provider=realdebrid
Using the TypeScript SDK helper:
import { getInstallDeeplink } from "auddio-addon-sdk";
const installUrl = getInstallDeeplink("https://my-addon.railway.app/manifest.json", {
debrid_provider: "realdebrid"
});
// => "auddio:///addon/install?url=https%3A%2F%2Fmy-addon.railway.app%2Fmanifest.json&debrid_provider=realdebrid"
10. Dynamic Configuration Form
Declare fields in your manifest under config.fields. Auddio builds native settings screens automatically:
"config": {
"fields": [
{
"id": "debrid_provider",
"label": "Provider",
"type": "dropdown",
"required": true,
"default": "realdebrid",
"options": [
{ "value": "realdebrid", "label": "Real-Debrid" },
{ "value": "alldebrid", "label": "AllDebrid" }
]
},
{
"id": "debrid_api_key",
"label": "API Key",
"type": "password",
"required": true,
"placeholder": "Enter token...",
"help": "Your private token remains encrypted on your device"
},
{
"id": "require_cached",
"label": "Instant Availability Only",
"type": "checkbox",
"default": true,
"help": "Hide torrents not already cached on debrid"
}
]
}
Complete Example: TypeScript SDK (Bun)
Our official TypeScript framework runs natively on Bun with built-in Zod schema validation, type safety, and automatic HTTP handling.
bun add auddio-addon-sdk
1. Scraper Addon
import { AddonServer } from "auddio-addon-sdk";
const addon = new AddonServer({
id: "com.example.audiobookbay-scraper",
name: "AudioBookBay Scraper",
version: "1.0.0",
type: "SCRAPER",
capabilities: ["SEARCH"],
});
addon.onSearch(async ({ title, author }) => {
// Replace with tracker scraper or database lookup
return {
results: [
{
infoHash: "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
title: `${title} - Unabridged`,
author: author || "Unknown Author",
narrator: "Full Cast",
size: 322485640,
sizeFormatted: "307.54 MiB",
seeders: 50,
leechers: 2,
source: "AudioBookBay",
format: "MP3",
bitrate: "64kbps",
}
],
total: 1,
query: { title }
};
});
addon.listen(3000);
console.log("Scraper addon running on http://localhost:3000");
2. Unified Addon (Search + Debrid Cache + Resolution)
import { AddonServer } from "auddio-addon-sdk";
const addon = new AddonServer({
id: "com.example.unified-source",
name: "Unified Audiobook Source",
version: "1.0.0",
type: "UNIFIED",
capabilities: ["SEARCH", "CHECK_CACHE", "RESOLVE", "PROGRESS"],
config: {
fields: [
{
id: "debrid_provider",
label: "Debrid Provider",
type: "dropdown",
required: true,
default: "realdebrid",
options: [
{ value: "realdebrid", label: "Real-Debrid" },
{ value: "alldebrid", label: "AllDebrid" }
]
},
{
id: "debrid_api_key",
label: "Debrid API Key",
type: "password",
required: true,
help: "Your token from your debrid account settings"
}
]
}
});
// 1. Search candidates
addon.onSearch(async (query) => {
return {
results: [
{
infoHash: "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
title: query.title,
author: query.author,
size: 322485640,
sizeFormatted: "307.54 MiB",
seeders: 32,
leechers: 1,
source: "Public Tracker",
format: "MP3"
}
],
total: 1,
query: { title: query.title }
};
});
// 2. Check instant cache on provider
addon.onCheckCache(async ({ provider, apiKey, infoHashes }) => {
return {
"a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f": {
cached: true,
torrentId: "rd_9821a"
}
};
});
// 3. Resolve streams with two-step flow
addon.onResolve(async ({ provider, apiKey, infoHash, torrentId, fileIds }) => {
if (!fileIds || fileIds.length === 0) {
return {
torrentId: "rd_9821a",
infoHash,
status: "selection_required",
files: [
{ id: 1, filename: "Part_01.mp3", size: 161242820 },
{ id: 2, filename: "Part_02.mp3", size: 161242820 }
]
};
}
return {
torrentId: "rd_9821a",
infoHash,
status: "ready",
files: [
{
id: 1,
filename: "Part_01.mp3",
url: "https://real-debrid.com/d/streamable-link-1",
size: 161242820,
status: "ready",
mimeType: "audio/mpeg"
}
],
totalSize: 161242820
};
});
// 4. Poll progress for uncached torrents
addon.onProgress(async ({ torrentId, apiKey }) => {
return {
infoHash: "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
status: "downloading",
progress: 85.0,
filename: "Audiobook Collection",
files: [
{ id: "1", filename: "Part_01.mp3", size: 161242820, status: "ready" }
]
};
});
addon.listen(3000);
3. Books Catalog Addon
import { AddonServer } from "auddio-addon-sdk";
const addon = new AddonServer({
id: "com.example.curated-catalog",
name: "Curated Audiobooks",
version: "1.0.0",
capabilities: ["CATALOG", "SEARCH"],
endpoints: {
catalog: "/catalog",
catalogFilters: "/catalog/filters",
}
});
addon.onCatalogFilters(async () => {
return {
categories: [
{ id: "fiction", name: "Fiction" },
{ id: "non-fiction", name: "Non-Fiction" }
],
genres: [
{ id: "sci-fi", name: "Science Fiction" },
{ id: "fantasy", name: "Fantasy" },
{ id: "mystery", name: "Mystery & Thriller" }
]
};
});
addon.onCatalog(async ({ category, genre, page = 1, limit = 20, sortBy }) => {
return {
books: [
{
id: "dune-1",
asin: "B002V1OF70",
title: "Dune",
author: "Frank Herbert",
coverUrl: "https://m.media-amazon.com/images/I/91dSMhdIzTL._SL500_.jpg"
}
],
page,
limit,
hasMore: false,
category,
genre
};
});
addon.listen(3000);
Complete Example: Node.js & Express
If you prefer vanilla Node.js, you can build an addon with Express and CORS in less than 70 lines:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
app.use(express.json());
// Manifest
app.get('/manifest.json', (req, res) => {
res.json({
id: "com.example.express-addon",
name: "Express Audiobook Addon",
version: "1.0.0",
type: "UNIFIED",
capabilities: ["SEARCH", "CHECK_CACHE", "RESOLVE"],
config: {
fields: [
{
id: "debrid_api_key",
label: "Debrid API Key",
type: "password",
required: true
}
]
}
});
});
// Search
app.post('/search', (req, res) => {
const { title } = req.body;
res.json({
results: [
{
infoHash: "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
title: title || "Demo Audiobook",
author: "Demo Author",
size: 322485640,
sizeFormatted: "307.54 MiB",
seeders: 25,
leechers: 1,
source: "Public Tracker",
format: "MP3"
}
],
total: 1,
query: { title }
});
});
// Check Cache
app.post('/check-cache', (req, res) => {
const { infoHashes } = req.body;
const result = {};
(infoHashes || []).forEach(hash => {
result[hash] = { cached: true, torrentId: "rd_demo_1" };
});
res.json(result);
});
// Resolve
app.post('/resolve', (req, res) => {
const { infoHash, fileIds } = req.body;
if (!fileIds || fileIds.length === 0) {
return res.json({
torrentId: "rd_demo_1",
infoHash,
status: "selection_required",
files: [
{ id: 1, filename: "Chapter_1.mp3", size: 15240291 }
]
});
}
res.json({
torrentId: "rd_demo_1",
infoHash,
status: "ready",
files: [
{
id: 1,
filename: "Chapter_1.mp3",
url: "https://your-debrid.com/stream/file_1.mp3",
size: 15240291,
status: "ready",
mimeType: "audio/mpeg"
}
]
});
});
app.listen(3000, () => console.log('Addon listening on port 3000'));
npm init -y
npm install express cors
node server.js
Complete Example: Python & Flask
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route('/manifest.json', methods=['GET'])
def manifest():
return jsonify({
"id": "com.example.python-addon",
"name": "Python Audiobook Addon",
"version": "1.0.0",
"type": "UNIFIED",
"capabilities": ["SEARCH", "CHECK_CACHE", "RESOLVE"]
})
@app.route('/search', methods=['POST'])
def search():
data = request.get_json() or {}
title = data.get('title', 'Unknown')
return jsonify({
"results": [{
"infoHash": "a5f822e1b12b23a9dcb8e4f5a112f45c22881a5f",
"title": title,
"author": data.get('author', 'Author'),
"size": 322485640,
"sizeFormatted": "307.54 MiB",
"seeders": 40,
"format": "MP3"
}],
"total": 1,
"query": {"title": title}
})
@app.route('/check-cache', methods=['POST'])
def check_cache():
data = request.get_json() or {}
hashes = data.get('infoHashes', [])
return jsonify({h: {"cached": True, "torrentId": "rd_py_1"} for h in hashes})
@app.route('/resolve', methods=['POST'])
def resolve():
data = request.get_json() or {}
file_ids = data.get('fileIds', [])
if not file_ids:
return jsonify({
"torrentId": "rd_py_1",
"infoHash": data.get('infoHash'),
"status": "selection_required",
"files": [{"id": 1, "filename": "Chapter_01.mp3", "size": 15000000}]
})
return jsonify({
"torrentId": "rd_py_1",
"infoHash": data.get('infoHash'),
"status": "ready",
"files": [{
"id": 1,
"filename": "Chapter_01.mp3",
"url": "https://your-debrid.com/py/stream.mp3",
"size": 15000000,
"status": "ready"
}]
})
if __name__ == '__main__':
app.run(port=3000)
TypeScript SDK API Reference (Generated from Code)
The following API reference is generated automatically from the official auddio-addon-sdk TypeScript source code and JSDoc docstrings using TypeDoc.
AddonServer
class AddonServer(manifest: Manifest)Methods
| Method | Signature & Parameters | Description (from JSDoc) |
|---|---|---|
constructor() |
constructor(manifest: object): AddonServer |
Handler registration method. |
onSearch() |
onSearch(handler: (req: object) => Promise<SearchResponse>): this |
Define the search capability handler |
onCheckCache() |
onCheckCache(handler: (req: object) => Promise<CheckCacheResponse>): this |
Define the check cache capability handler |
onResolve() |
onResolve(handler: (req: object) => Promise<ResolveResponse>): this |
Define the resolve capability handler |
onProgress() |
onProgress(handler: (req: object) => Promise<object>): this |
Define the progress capability handler |
onTorrentFiles() |
onTorrentFiles(handler: (req: object) => Promise<object>): this |
Define the torrent files handler (POST /info) |
onAirlock() |
onAirlock(handler: (req: object) => Promise<AirlockResponse>): this |
Define the airlock handler (POST /airlock). Called when the app wants to toggle permanent caching on a TorBox torrent. Only relevant for addons that use the TorBox debrid provider. |
onCatalogFilters() |
onCatalogFilters(handler: (req: object) => Promise<object>): this |
Define the catalog filters capability handler (returns categories and genres list) |
onCatalog() |
onCatalog(handler: (req: object) => Promise<object>): this |
Define the catalog books capability handler (returns books by category / genre) |
listen() |
listen(port: number): Server<undefined> |
Start the Bun.serve server |
getInstallDeeplink
getInstallDeeplink(manifestUrl: string, configValues: Record<string, string | number | boolean>): stringCapabilities Reference
Every addon advertises its supported operations inside the capabilities array in its manifest. The mobile client inspects these flags to selectively enable search indexing, instant cloud playback, catalog screens, or airlock caching.
Search & Scraping
Enables title, author, and book ID matching across external trackers, private indexers, and public audiobook sources.
Instant Cloud Cache
Checks whether candidate torrent infoHashes are cached on Real-Debrid, TorBox, or AllDebrid for instantaneous zero-wait playback.
Stream Resolution
Unlocks our 2-step chapter selection flow to extract and deliver playable, seekable audio streaming links for each track.
Download Polling
Tracks background download percentages and file completion when a user chooses to cache an uncached torrent to debrid.
Torrent Metadata
Inspects full file layouts, track numbers, and chapter names from public torrent cache engines without hitting debrid API quotas.
TorBox Airlock
Toggles permanent storage retention on TorBox debrid servers to safeguard frequently played audiobooks from automatic 30-day eviction.
Books Catalogs
Populates Auddio's Discover, Category, and Genre tabs with rich audiobook shelves, covers, and curated recommendations.
| Capability | Required Endpoint | Description & App Behavior |
|---|---|---|
"SEARCH" |
POST /search |
Enables search integration across torrent trackers and providers. |
"CHECK_CACHE" |
POST /check-cache |
Allows client to query instant cache status of torrent infoHashes on Debrid clouds. |
"RESOLVE" |
POST /resolve |
Resolves infoHashes into direct playable audio stream URLs via 2-step selection. |
"PROGRESS" |
GET /progress/:torrentId |
Monitors debrid download status for uncached torrents being fetched to cloud storage. |
"INFO" |
POST /info |
Returns raw internal file layout and groupings from public torrent caches without Debrid API calls. |
"AIRLOCK" |
POST /airlock |
Toggles permanent torrent retention on TorBox providers to prevent 30-day inactivity deletion. |
"CATALOG" |
/catalog & /catalog/filters |
Populates Home, Discover, and Browse shelves with curated audiobook categories and genres. |
Config Field Schema Reference
Every element in manifest.config.fields supports the following attributes:
| Property | Type | Required | Description |
|---|---|---|---|
id |
String | Yes | Unique key transmitted in request payloads (e.g. debrid_api_key). |
label |
String | Yes | Human-readable title displayed next to the widget in the app settings. |
type |
String | Yes | Widget control type: "text", "password", "number", "textarea", "dropdown", or "checkbox". |
required |
Boolean | Yes | If true, client blocks installation until the user supplies a value. |
default |
Any | No | Fallback initial value populated before the user edits the field. |
placeholder |
String | No | Faint prompt text rendered inside text input controls. |
help |
String | No | Explaining hint rendered beneath the field in small font. |
options |
Array | Dropdown only | Array of { "value": string, "label": string } options for dropdown pickers. |
Protocol Error Specifications
When handling requests, addons return JSON error responses with descriptive error codes and standard HTTP statuses:
| Error Code | HTTP Status | Description & App Behavior |
|---|---|---|
INVALID_INPUT |
400 Bad Request | Missing required parameters or malformed infoHash. |
INVALID_API_KEY |
401 Unauthorized | The user's private debrid API token was rejected by the provider. |
NOT_FOUND |
404 Not Found | Requested audiobook or scraper query returned no matches. |
NOT_CACHED |
412 Precondition Failed | Torrent is not cached on debrid, and the user requested instant cache only. |
RATE_LIMIT_EXCEEDED |
429 Too Many Requests | Addon or downstream provider rate limits exceeded. |
PROVIDER_ERROR |
502 Bad Gateway | The downstream debrid service returned an internal error or timed out. |
Hosting & Deployment
Your production addon must be accessible over HTTPS. Popular hosting options:
| Platform | Free Tier | Best For |
|---|---|---|
| Railway | $5/mo credit | Full Node.js/Bun servers, persistent Docker containers. |
| Fly.io | 3 shared VMs | Global edge Docker microservices with fast cold starts. |
| Cloudflare Workers | 100k requests/day | Ultra-fast serverless scrapers running at the edge. |
| Custom VPS | - | Any standard Linux VPS running Nginx/Caddy with SSL. |
0.0.0.0 and enter your Mac's LAN IP address (e.g. http://192.168.1.100:3000/manifest.json). Auddio accepts unencrypted HTTP on local network subnets!
Installing Your Addon in Auddio
- Open the Auddio app on iOS, iPadOS, or Android.
- Navigate to Settings → Addons → Add Custom Addon.
- Paste your addon's manifest URL (e.g.
https://my-addon.railway.app/manifest.json). - Auddio fetches the manifest, renders the dynamic config form, and displays a preview.
- Fill in any required settings (like your Debrid API key) and tap Install.
- Your addon is now active across Search, Cloud Streaming, and Catalog browsing!
Frequently Asked Questions
Can I build an addon in any programming language?
Yes — any backend language that can serve JSON responses over HTTP works seamlessly. We provide an official TypeScript framework for Bun, but you can build in Node.js, Python, Go, Rust, Java, or C#.
Does my addon need to store user database records?
No. Auddio addons are typically stateless microservices. All user configuration parameters (API tokens, mirrors, filters) are stored locally on the user's client device and sent with each request.
How does Auddio prevent downloading the entire torrent?
Through our Two-Step Selection Flow. When an infoHash contains multiple chapter files, the addon returns status: "selection_required". Auddio then requests stream links only for the specific audio file the listener is playing.
Can an addon provide audiobook catalogs?
Yes! Declare "CATALOG" in your manifest's capabilities and implement /catalog/filters and /catalog. Your categorized rows (Bestsellers, Sci-Fi, Non-Fiction) will display directly in Auddio's Discover tab.
What audio formats are supported?
Auddio supports MP3, M4B, AAC, FLAC, OPUS, and WAV. For M4B and MP3 files, embedded chapter markers and titles are parsed automatically by the player.
Is my Debrid API Key safe?
Yes. Keys are stored in the device's secure enclave and transmitted directly over HTTPS to your addon server.