Use the Listenbox podcast hosting API
Published · Updated
How do I automate podcast publishing with Listenbox?
Use the Listenbox public API to connect your publishing workflow to your podcast host. You can create podcasts, read your catalog, update podcast details, and upload audio or video episodes as drafts or for publication. Start with the OpenAPI specification and authorize access to your Listenbox team. This guide covers direct HTTP integration. For a ready-made command-line workflow, follow the CLI guide. To connect an AI agent from a chat app, use the MCP guide. For occasional uploads, the dashboard workflow may be all you need.
API behavior and specification reviewed as of October 26, 2026.
Get the OpenAPI specification
The API base URL is https://v1.listenbox.app. Opening its root returns the
OpenAPI document itself. YAML in your browser is expected.
The same URL serves YAML or JSON according to the Accept header:
curl --fail-with-body https://v1.listenbox.app/ \
-H 'Accept: application/json' \
-o listenbox-openapi.json
For YAML, request Accept: text/yaml. Reading the specification does not
require an API key.
The document describes endpoints, request and response schemas, API key scopes,
status codes, and event streams. Use it with an OpenAPI viewer, API client, or
client generator that supports OpenAPI 3.2. Set the server URL to
https://v1.listenbox.app if your tool asks for one. Check your tool's
supported OpenAPI version before generating a client; the specification is the
reference for the current API contract.
Authorize API access
API access uses a bearer credential and browser approval. You need a Listenbox account with Owner or Manager access to the team you authorize. A Viewer cannot approve client access. Requested scopes also remain subject to your current team and podcast permissions.
For a direct integration, use the authorization flow shared with the Listenbox CLI:
-
Create an authorization request. This example asks only to read podcasts:
curl --fail-with-body https://v1.listenbox.app/cli/authorizations \ -H 'Content-Type: application/json' \ -d '{"client":"cli","scopes":["show:read"]}' -
Keep the returned
credentialprivate and open the returnedverification_urlin your browser. Sign in, select the intended team, review the requested permissions, and approve access. -
Your integration can follow
GET /cli/authorizations/{code}/eventsfor the approval, denial, or expiry event. The credential remains inactive until approval. Start a new authorization request if it is denied or expires.
Choose scopes for the work your integration performs: show:create to create
podcasts, show:update to edit podcast details, and episode:create to upload
episodes. Publishing also requires episode:publish. Request only what you
need; a scope does not grant access beyond the approving user's permissions.
Store the approved credential in your application's secret storage. The
following examples read it from a LISTENBOX_API_KEY environment variable. Keep
it out of browser-side code and public repositories.
Make your first API request
Check the approved credential and its scopes:
curl --fail-with-body https://v1.listenbox.app/s/whoami \
-H "Authorization: Bearer $LISTENBOX_API_KEY"
Then list the podcasts accessible to the credential's creator:
curl --fail-with-body https://v1.listenbox.app/s/shows \
-H "Authorization: Bearer $LISTENBOX_API_KEY"
Use a returned podcast slug with GET /s/shows/{show_slug}/episodes to read
its episodes. Follow next_cursor when it is returned, passing it as the next
request's cursor, until there are no more pages.
For a new podcast, use POST /s/shows. Read its schema for the required fields,
including the destination team and source type. Choose an audio-source podcast
for audio recordings or a video-source podcast for video recordings.
Upload audio or video episodes
Use the resumable source-upload flow when your integration has an original recording. Prepare the file's name, content type, byte length, and SHA-256 value using the schema in the OpenAPI document.
- Call
POST /s/episode-upload-sessionswith the podcast slug, episode title, and file details. Save the returnedupload_session_id. Admission creates an upload session; it does not create a published episode. - Request signed part URLs through
POST /s/episode-upload-sessions/{upload_session_id}/parts/presign. Upload file parts to those URLs using the session'spart_sizeandmax_parallelism. The file bytes go to the signed storage URLs. - Call
POST /s/episode-upload-sessions/{upload_session_id}/completewith{"publication":"draft"}for review in the dashboard, or{"publication":"publish"}for publication when processing commits. The latter requiresepisode:publish. - Follow
GET /s/episode-upload-sessions/{upload_session_id}/eventsfor processing progress and its success or failure milestone. A completed file transfer alone does not establish that the episode is ready.
Use GET /s/episode-upload-sessions/{upload_session_id} to inspect an existing
session after an interruption. Use its DELETE operation to cancel an abandoned
upload. Follow the documented response codes for conflicts and expired sessions
instead of creating duplicate releases.
The API also exposes episode packages for clients that prepare media before uploading. Start with source-upload sessions unless your integration implements the package contract. Hosted video requires a video plan with available capacity; see pricing for the current allowances.
Handle errors and processing events
Read the response status and the endpoint's documented error body before retrying. Common cases include:
- 400: Check the request fields and validation details.
- 401: Check that the bearer credential is present, approved, and valid.
- 403: Check the requested scopes and the user's current access.
- 404: Check the resource identifier and whether this credential can access it.
- 409: Inspect the conflict before retrying; an upload or podcast may already exist.
- 410: An upload session has expired. Start a new upload attempt.
Processing endpoints use Server-Sent Events (SSE) with
Content-Type: text/event-stream. Handle both episode.processing.safe_handoff
and episode.processing.failed, alongside progress events. If processing fails,
read its error_code and error_message before deciding what to correct. Treat
a disconnected stream as a lost connection, then inspect the session's current
state.
Check publication and podcast distribution
For a review-first workflow, complete the upload as a draft, check its recording and details in the dashboard, and publish there. For automated publication, confirm the processing outcome and the episode's publication state through the API before marking your job complete.
Your podcast also needs a public RSS feed for podcast apps to receive published episodes. Set up and check the feed, then complete each directory's submission or approval process. Publishing through the API does not automatically submit the podcast to directories. Directory update timing and any separate video-destination setup still apply.
Use the live OpenAPI specification for exact fields and endpoint behavior as you build your integration.