Skip to content

LibexHQ/Libex

Repository files navigation

Libex

License: MIT Tests GHCR Docker Hub

Books Authors Narrators Series

Open, unrestricted Audible metadata API for the audiobook automation community.


Public Instance

A free public instance of Libex is available at Libex

This instance is maintained by the Libex project and is free for community use. No API key required. No rate limits beyond what Audible naturally enforces.

If you rely on Libex for a project or tool, we recommend self-hosting your own instance for reliability and control.


Why Libex?

The audiobook automation community has long depended on metadata services to power tools like Readarr, Audiobookshelf, and custom managers. When those services disappear or restrict usage, every project depending on them breaks.

Libex exists to be a permanent, community-owned alternative:

  • MIT licensed — no restrictions, fork it, build on it, use it however you want
  • No usage restrictions — works with any software, any workflow
  • Drop-in replacement — compatible with AudiMeta's API endpoints
  • Audible-first — always fetches fresh data, the local database is a fallback not a crutch
  • Persistent local library — every book, author, and series ever requested is stored and queryable
  • All regions — full support for all Audible markets without language restrictions
  • Self-hostable — one docker compose up and you're running

Quick Start

Pull the image:

# GHCR
docker pull ghcr.io/libexhq/libex:latest

# Docker Hub
docker pull sunbrolynk/libex:latest

Deploy:

# 1. Create a directory
mkdir libex && cd libex

# 2. Download the compose file
curl -O https://raw.githubusercontent.com/LibexHQ/Libex/main/docker-compose.yml

# 3. Create your environment file
cp .env.example .env
# Edit .env — DB_PASSWORD is required, all other values have sensible defaults

# 4. Start Libex
docker compose up -d

# 5. Verify
curl http://localhost:3333/health

Or copy the compose file directly:

services:
  libex:
    image: ghcr.io/libexhq/libex:latest
    container_name: libex
    restart: unless-stopped
    ports:
      - "${PORT:-3333}:3333"
    environment:
      - DATABASE_URL=postgresql+asyncpg://${DB_USER:-libex}:${DB_PASSWORD}@postgres:5432/${DB_NAME:-libex}
      - CACHE_ENABLED=${CACHE_ENABLED:-true}
      - CACHE_TTL=${CACHE_TTL:-86400}
      - DEFAULT_REGION=${DEFAULT_REGION:-us}
      - PORT=${PORT:-3333}
      - LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-7}
      - AXIOM_TOKEN=${AXIOM_TOKEN}
      - AXIOM_DATASET=${AXIOM_DATASET:-libex}
      - SEEDER_ENABLED=${SEEDER_ENABLED:-false}
      - SEEDER_INTERVAL_HOURS=${SEEDER_INTERVAL_HOURS:-24}
      - SEEDER_REQUEST_DELAY=${SEEDER_REQUEST_DELAY:-1.0}
      - SEEDER_REGIONS=${SEEDER_REGIONS:-us}
      - AUDIBLE_PROXY_URL=${AUDIBLE_PROXY_URL}
    volumes:
      - ./logs:/app/logs
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - default
      - libex-proxy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3333/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  postgres:
    image: postgres:16-alpine
    container_name: libex-postgres
    restart: unless-stopped
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: ${DB_NAME:-libex}
      POSTGRES_USER: ${DB_USER:-libex}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-libex}"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  libex-proxy:
    name: libex-proxy
    driver: bridge

Logging & Privacy

The public instance uses Axiom for structured request logging. This is disclosed transparently.

What is logged:

  • Request path and parameters (e.g. which ASIN was requested, which region)
  • Response time and status code
  • IP address
  • User agent
  • Cache hit/miss
  • Errors and exceptions

What is NOT logged:

  • Any personally identifiable information beyond the above

Why we log: Logging helps us understand how Libex is being used, identify broken endpoints, debug errors, and improve the service. Without visibility into what's failing, we can't fix it.

Who can see the logs: Only the instance maintainer has access to the Axiom dataset. Logs are retained for 30 days and then automatically deleted by Axiom. No logs are shared with third parties.

If you self-host: Logging is completely optional. Leave AXIOM_TOKEN empty and Libex logs to stdout only. Nothing leaves your server.


API Behavior

HTML content: description and summary fields on book responses, description on author responses, and description on series responses are returned as plain text with HTML stripped.

Image URLs: Cover image URLs are returned with Audible size suffixes stripped, giving you the base high-resolution image URL.

ASIN validation: All ASIN parameters are validated against Audible's 10-character alphanumeric format. Invalid ASINs return a 404 with a clear error message.

Region validation: All region parameters are validated against supported Audible regions. Invalid regions return a 400 error.

Local database: Every successful Audible response is written to a persistent relational database. This powers the DB query endpoints and serves as a fallback when Audible is unavailable.

Virtual Voice Audiobooks: Book responses include isVvab (boolean indicating whether the book is a Virtual Voice Audiobook — AI-narrated rather than human-narrated).

Audible plans: Book responses include plans (list of Audible plan names such as "US Minerva" or "AccessViaMusic"), letting clients determine subscription availability programmatically.

Narrator profiles: Narrator responses from /db/narrator include enrichment data sourced from NarratorList.com and AussieNarrator.com where available. When profile data is present, the response includes source, sourceUrl (link to the narrator's full profile), sourceUpdatedAt, and an attribution string (e.g. "Profile data provided by NarratorList.com, retrieved May 2026"). Consumers displaying narrator data should include this attribution where practical.


Audiobookshelf Configuration

Audiobookshelf's custom metadata provider calls /{region}/search, not /search. When configuring ABS, set your base URL to include the region:

http://YOUR-IP:3333/us

ABS will then call /us/search?title=...&author=... which returns the {"matches": [...]} format ABS expects. The flat /search endpoint returns a different format that ABS cannot parse.


API Endpoints

Method Endpoint Description
GET /book/{asin} Get book by ASIN
GET /book Get multiple books by ASIN (comma-separated, max 1000)
GET /book/{asin}/chapters Get chapter information
GET /book/sku/{sku} Get all region variants of a book by SKU group
GET /author/{asin} Get author profile
GET /author/{asin}/books Get all books by author ASIN
GET /author/books/{asin} Get all books by author ASIN (legacy)
GET /author/books Get books by author name
GET /author Search authors by name
GET /series/{asin} Get series metadata
GET /series/{asin}/books Get all books in a series
GET /series/books/{asin} Get all books in a series (legacy)
GET /series Search series by name
GET /narrator/books Get books by narrator name
GET /search Search Audible catalog
GET /quick-search Quick search via suggestions
GET /{region}/search Regional search for Audiobookshelf compatibility
GET /{region}/quick-search/search Regional quick search for Audiobookshelf compatibility
GET /db/book Query the local indexed book library
GET /db/book/{asin} Get a single book from local DB
GET /db/book/{asin}/chapters Get chapter data from local DB
GET /db/book/sku/{sku} Get books by SKU group from local DB
GET /db/plans Get all distinct Audible plan names from local DB
GET /db/plans/{plan_name} Get all books under a specific plan from local DB
GET /db/vvab Get all virtual voice audiobooks (AI-narrated) from local DB
GET /db/stats Get counts of books, authors, narrators, and series in local DB
GET /db/author/{asin} Get author from local DB
GET /db/author/{asin}/books Get author's books from local DB
GET /db/narrator Search narrators by name from local DB
GET /db/narrator/books Get books by narrator name from local DB
GET /db/series/{asin} Get series from local DB
GET /db/series/{asin}/books Get series books from local DB
GET /health Health check

Full interactive documentation available at /docs when running.


DB Query Endpoint

GET /db/book queries books that have been fetched and stored locally without hitting Audible. Useful for searching your indexed library by metadata.

All parameters are optional but at least one filter must be provided. Supports pagination via limit (default 20, max 100) and page (default 1).

Parameter Type Match
title string ILIKE
subtitle string ILIKE
author_name string ILIKE (join)
series_name string ILIKE (join)
description string ILIKE
summary string ILIKE
publisher string ILIKE
copyright string ILIKE
isbn string ILIKE
region string exact
language string exact
book_format string exact
content_type string exact
content_delivery_type string exact
rating_better_than float >=
rating_worse_than float <=
longer_than int >= (minutes)
shorter_than int <= (minutes)
explicit bool exact
whisper_sync bool exact
has_pdf bool exact
is_listenable bool exact
is_buyable bool exact
is_vvab bool exact
plan_name string JSONB contains

Supported Regions

Code Region
us United States
uk United Kingdom
ca Canada
au Australia
de Germany
fr France
it Italy
es Spain
jp Japan
in India
br Brazil

Configuration

Copy .env.example to .env and configure:

Variable Default Description
DB_PASSWORD Required. PostgreSQL password
DB_NAME libex PostgreSQL database name
DB_USER libex PostgreSQL username
PORT 3333 Host port the API is exposed on
DEFAULT_REGION us Default Audible region
CACHE_ENABLED true Enable or disable the cache
CACHE_TTL 86400 Cache TTL in seconds (default 24 hours)
LOG_RETENTION_DAYS 7 Days of rotated logs to keep. 0 = infinite, no rotation
AXIOM_TOKEN Axiom API token (optional — leave blank for stdout only)
AXIOM_DATASET libex Axiom dataset name
SEEDER_ENABLED false Enable background DB seeder
SEEDER_INTERVAL_HOURS 24 Hours between seeder cycles
SEEDER_REQUEST_DELAY 1.0 Seconds between Audible requests during seeding
SEEDER_REGIONS us Comma-separated regions to seed (e.g. us,uk,de)
AUDIBLE_PROXY_URL Proxy URL for outbound Audible requests only. Supports http://, https://, socks5://. API serving is unaffected
SEED_SECRET PBKDF2 hash for the internal seed endpoint. Empty = endpoint disabled. Generate with python -m app.api.routes.internal.router

DATABASE_URL is constructed automatically by docker-compose from DB_NAME, DB_USER, and DB_PASSWORD. Only set it manually if running outside of Docker.


Migrating from AudiMeta

Libex is API-compatible with AudiMeta. To migrate:

  1. Deploy Libex using the quick start above
  2. Update your base URL from your AudiMeta instance to your Libex instance
  3. That's it — no other changes required

Self-Hosting Notes

  • Libex uses PostgreSQL as both a persistent library and a cache — no Redis required
  • Every book, author, series, narrator, and genre ever requested is stored in a full relational schema and survives cache expiry indefinitely
  • The local library powers the /db/book and /book/sku/{sku} endpoints and serves as an automatic fallback when Audible is unavailable
  • Cache entries expire after CACHE_TTL seconds (default 24 hours); expired entries are purged automatically
  • Logs directory: ./logs (relative to your compose file) — Libex writes a rotating log file to ./logs/libex.log on the host
  • Log rotation is daily. LOG_RETENTION_DAYS=7 keeps 7 days of backups. Set to 0 for infinite retention with no rotation
  • Database seeder: Set SEEDER_ENABLED=true to activate the background seeder. It expands the local DB by walking author relationships (discovers books you haven't requested yet) and scanning for new Audible releases. Each cycle compounds — a single book fetch can seed hundreds of related books over time. The seeder runs every SEEDER_INTERVAL_HOURS (default 24) and rate-limits itself to one Audible request per SEEDER_REQUEST_DELAY seconds (default 1.0). Configure SEEDER_REGIONS to seed multiple markets (e.g. us,uk,de)
  • VPN proxy: Set AUDIBLE_PROXY_URL to route outbound Audible API requests through a proxy. Only Audible requests are affected — API serving, database connections, and logging are completely unaffected. This is especially useful when running the seeder to avoid IP-based rate limiting. Any HTTP, HTTPS, or SOCKS5 proxy works. The compose file creates a libex-proxy Docker network automatically — connect your VPN proxy container to it, then set AUDIBLE_PROXY_URL to point at the proxy. Leave AUDIBLE_PROXY_URL blank to disable

Contributing

Contributions are welcome. See CONTRIBUTING.md for branch naming, commit conventions, and PR requirements.


Disclaimer

Libex is a metadata tool that fetches publicly available information from Audible's API. It does not host, distribute, or provide access to copyrighted audio content. Users are responsible for ensuring their use complies with applicable laws and Audible's terms of service.


Acknowledgements

Audible — All metadata is sourced from Audible's public API. Libex is an independent project and is not affiliated with, endorsed by, or sponsored by Audible or Amazon.

NarratorList.com — Narrator profile data including biographies, images, languages, and accent ratings is sourced from NarratorList.com. NarratorList is a community-built database where audiobook narrators curate their own profiles. Maintained by Amy Soakes.

AussieNarrator.com — Additional narrator profile data for Australian and New Zealand narrators. A sister site to NarratorList.com, also maintained by Amy Soakes.

Axiom — Structured logging for the public instance. Axiom provides the observability layer that helps us monitor and improve Libex.

AudiMeta — The original Audible metadata service that inspired Libex and demonstrated the community need for this tooling. Credit to Vito0912 for pioneering this space.

FastAPI — The modern Python web framework powering Libex.

SQLAlchemy — Async database toolkit for Python powering Libex's full relational schema across books, authors, series, narrators, genres, and their relationships.


License

MIT — see LICENSE for details.

About

Open, unrestricted Audible metadata API for the audiobook automation community

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages