pocketcasts-api
v1.0.0
Published
Unofficial TypeScript client for the Pocket Casts API
Maintainers
Readme
pocketcasts-api
Unofficial TypeScript client for the Pocket Casts API.
Note: This is an unofficial client. Not affiliated with Pocket Casts or Automattic.
Requirements
- Node.js 20 or later
Installation
npm install pocketcasts-apiQuick Start
import { PocketCasts } from 'pocketcasts-api';
const client = new PocketCasts();
// Authenticate
await client.login('[email protected]', 'yourpassword');
// Read your subscriptions
const { podcasts } = await client.getSubscriptions();
console.log(podcasts.map((p) => p.title));
// Star an episode
const { episodes } = await client.getInProgress();
const episode = episodes[0];
await client.starEpisode(episode.podcastUuid, episode.uuid);API Reference
Authentication
| Method | Description |
| ------------------------ | ------------------------------------------------------------------------------------------- |
| login(email, password) | Authenticate and store the session token. Must be called before any authenticated endpoint. |
Read Operations (require login)
| Method | Returns | Description |
| ----------------------- | ------------------------------ | ------------------------------------------------------------------- |
| getSubscriptions() | { podcasts: Podcast[] } | List all subscribed podcasts. |
| getNewReleases() | { episodes: Episode[] } | Episodes from subscribed podcasts released recently. |
| getInProgress() | { episodes: Episode[] } | Episodes currently in progress (partially played). |
| getStarred() | { episodes: Episode[] } | All starred episodes. |
| getHistory() | { episodes: Episode[] } | Listening history. |
| getStats() | ListeningStats | Aggregate listening statistics (total time, silence removal, etc.). |
| getPodcast(uuid) | Podcast | Details for a single podcast by UUID. |
| getEpisode(uuid) | Episode | Details for a single episode by UUID. |
| getEpisodeNotes(uuid) | string | HTML show notes for an episode. |
| search(term) | { podcasts: SearchResult[] } | Search the Pocket Casts directory. |
Write Operations (require login)
| Method | Description |
| ---------------------------------------------------------------------- | ------------------------------------------------------------- |
| subscribe(podcastUuid) | Subscribe to a podcast. |
| unsubscribe(podcastUuid) | Unsubscribe from a podcast. |
| starEpisode(podcastUuid, episodeUuid) | Star an episode. |
| unstarEpisode(podcastUuid, episodeUuid) | Remove a star from an episode. |
| updatePlayingStatus(podcastUuid, episodeUuid, status) | Set playing status: 'unplayed', 'playing', or 'played'. |
| updatePlaybackPosition(podcastUuid, episodeUuid, position, duration) | Update the playback position (seconds) for an episode. |
Discovery Operations (no login required)
| Method | Returns | Description |
| --------------- | ------------------------------ | ------------------------------ |
| getTrending() | { podcasts: SearchResult[] } | Currently trending podcasts. |
| getPopular() | { podcasts: SearchResult[] } | Most popular podcasts. |
| getFeatured() | { podcasts: SearchResult[] } | Editorially featured podcasts. |
Error Handling
import {
PocketCasts,
PocketCastsAuthError,
PocketCastsAPIError,
} from 'pocketcasts-api';
const client = new PocketCasts();
try {
await client.login('[email protected]', 'wrongpassword');
} catch (e) {
if (e instanceof PocketCastsAuthError) {
console.error('Authentication failed:', e.message);
}
}
try {
await client.getPodcast('invalid-uuid');
} catch (e) {
if (e instanceof PocketCastsAPIError) {
console.error(`API error ${e.statusCode}:`, e.message);
}
}Error Classes
| Class | Extends | Description |
| ---------------------- | ------------------ | ------------------------------------------------------------------------------------ |
| PocketCastsError | Error | Base class for all errors from this library. |
| PocketCastsAuthError | PocketCastsError | Thrown when authentication fails or a request is made before calling login(). |
| PocketCastsAPIError | PocketCastsError | Thrown when the API returns a non-2xx response. Has a statusCode: number property. |
Limitations
No automatic retries or backoff. Each method makes a single
fetchcall. If you need resilience against transient failures or rate limiting, supply your ownfetchvia the constructor option and handle retries there:import { PocketCasts } from 'pocketcasts-api'; const retryingFetch: typeof fetch = async (input, init) => { // your retry/backoff logic wrapping globalThis.fetch }; const client = new PocketCasts({ fetch: retryingFetch });Unofficial and unstable. Endpoints are reverse-engineered from the Pocket Casts web player and may change without notice.
Contributing
Issues and pull requests are welcome. To work on the library:
npm install
npm test # unit tests (mocked, no network)
npm run lint # eslint + type check
npm run format # prettierIntegration tests hit the real API and are skipped unless you opt in with credentials:
[email protected] POCKETCASTS_PASSWORD=secret npm run test:integrationSecurity
See SECURITY.md for how to report a vulnerability.
License
MIT
