Skip to content

Library & Wishlist

import { library } from 'audible-api-ts'
const { items, credentials } = await library(credentials)

This fetches all audiobooks in the user’s library. Pagination is handled automatically (50 items per page).

import { wishlist } from 'audible-api-ts'
const { items, credentials } = await wishlist(credentials)

Same API, same response shape — just a different data source.

Every function returns AudibleItem objects with the full data from the API:

type AudibleItem = {
// Identity
asin: string // "B08G9PRS1K"
title: string // "Primal Hunter"
subtitle?: string // "Primal Hunter, Tome 4"
isbn?: string // "9791036645624"
// People
authors: string[] // ["Zogarth", "Astrid Vallet - traducteur"]
narrators: string[] // ["Sébastien Mortamet"]
// Content
durationMinutes: number // 1770
publisher?: string // "Lizzie"
language?: string // "french"
releaseDate?: Date // 2026-03-12
coverUrl?: string // "https://m.media-amazon.com/images/..."
summary?: string // Full HTML description
copyright?: string // "©2026 Zogarth..."
formatType?: string // "unabridged"
// Classification
series?: { name: string; position?: number }
categories: CategoryLadder[] // Genre hierarchy
keywords: string[] // ["Science_Fiction_Fantasy", ...]
// Ratings (3 dimensions)
rating?: AudibleRating
// Listening progress (library only)
listeningStatus?: ListeningStatus
purchaseDate?: Date
dateAdded?: Date
// Relationships
relationships: AudibleRelationship[]
// Images
productImages: Record<string, string> // { "500": "https://..." }
socialMediaImages: Record<string, string>
// Flags
isAdultProduct: boolean
}
const { items } = await library(credentials)
items.map((book) => {
const rating = book.rating?.overallDistribution
const hours = Math.floor(book.durationMinutes / 60)
const mins = book.durationMinutes % 60
console.log(`${book.title}${book.subtitle ? `${book.subtitle}` : ''}`)
console.log(` By ${book.authors.join(', ')}`)
console.log(` Narrated by ${book.narrators.join(', ')}`)
console.log(` ${hours}h ${mins}min | ${book.publisher} | ${book.language}`)
if (rating) {
console.log(` Rating: ${rating.averageRating.toFixed(1)}/5 (${rating.numRatings} votes)`)
}
if (book.series) {
console.log(` Series: ${book.series.name} #${book.series.position}`)
}
})

Output:

Primal Hunter — Primal Hunter, Tome 4
By Zogarth, Astrid Vallet - traducteur
Narrated by Sébastien Mortamet
29h 30min | Lizzie | french
Rating: 4.8/5 (156 votes)
Series: Primal Hunter #4
import { orderBy } from 'lodash-es'
const { items } = await library(credentials)
const topRated = orderBy(
items.filter((book) => book.rating?.overallDistribution),
[({ rating }) => rating!.overallDistribution!.averageRating],
['desc'],
).slice(0, 10)
topRated.map((book, i) => {
const r = book.rating!.overallDistribution!
console.log(`${i + 1}. ${book.title}${r.averageRating.toFixed(1)}/5 (${r.numRatings} votes)`)
})

Output:

1. Dungeon Crawler Carl — 4.9/5 (759 votes)
2. Primal Hunter — 4.9/5 (529 votes)
3. Fondation — 4.8/5 (2830 votes)
4. Hypérion — 4.8/5 (1625 votes)
const { items } = await library(credentials)
const finished = items.filter((book) => book.listeningStatus?.finishedAt)
const inProgress = items.filter(
(book) =>
book.listeningStatus?.percentComplete &&
book.listeningStatus.percentComplete > 0 &&
!book.listeningStatus.finishedAt,
)
const totalMinutes = items.reduce((sum, book) => sum + book.durationMinutes, 0)
console.log(`Library: ${items.length} audiobooks`)
console.log(`Finished: ${finished.length}`)
console.log(`In progress: ${inProgress.length}`)
console.log(`Total duration: ${Math.floor(totalMinutes / 60)} hours`)
inProgress.map((book) =>
console.log(
` ${book.title}${book.listeningStatus!.percentComplete}% ` +
`(${Math.floor(book.listeningStatus!.timeRemainingSeconds! / 3600)}h remaining)`
)
)

Output:

Library: 142 audiobooks
Finished: 118
In progress: 3
Total duration: 2156 hours
Primal Hunter — 5% (28h remaining)
Les Guerriers du silence — 12% (21h remaining)
const { items } = await library(credentials)
const sciFi = items.filter((book) =>
book.categories.some((ladder) =>
ladder.categories.some((cat) => cat.name.includes('Science-Fiction')),
),
)
console.log(`${sciFi.length} sci-fi books in library`)
sciFi.map((book) => console.log(` ${book.title}${book.authors.join(', ')}`))

Output:

98 sci-fi books in library
Dune — Frank Herbert
Hypérion — Dan Simmons
Le problème à trois corps — Liu Cixin
Fondation — Isaac Asimov
const bySeries = Map.groupBy(
items.filter((book) => book.series),
(book) => book.series!.name,
)
Array.from(bySeries.entries())
.filter(([, books]) => books.length > 1)
.map(([series, books]) =>
console.log(`${series}: ${books.length} books`)
)

Output:

L'Assassin Royal: 12 books
Primal Hunter: 4 books
Dungeon Crawler Carl: 6 books
Dans la toile du temps: 3 books
Fondation: 7 books

Before fetching data, you can verify that credentials are still valid:

import { verify } from 'audible-api-ts'
try {
await verify(credentials)
console.log('Credentials are valid')
} catch {
console.log('Credentials are invalid or expired')
}