openapi: 3.2.0
info:
title: Reference Podcasts API
version: 1.0.0
servers:
- url: https://api.beehiiv.com/v2
description: Default
tags:
- name: podcasts
paths:
/publications/{publicationId}/podcasts:
get:
operationId: list-podcasts
summary: 'List podcasts OAuth Scope: podcasts:read'
description: Retrieve all podcasts belonging to a specific publication.
tags:
- podcasts
parameters:
- name: publicationId
in: path
description: The prefixed ID of the publication object
required: true
schema:
$ref: '#/components/schemas/type_ids_PublicationId'
- name: limit
in: query
description: A limit on the number of objects to be returned. The limit can range between 1 and 100, and the default is 10.
required: false
schema:
type: integer
- name: cursor
in: query
description: Use this opaque cursor token to fetch the next page of results. Obtain the value from `next_cursor` in a previous response.
required: false
schema:
type: string
- name: status
in: query
description: Optionally filter the results by the status of the podcast.
`draft` - No episodes have been published.
`live` - Published and active.
`archived` - The podcast is no longer active.
required: false
schema:
$ref: '#/components/schemas/type_podcasts_PodcastShowStatus'
- name: Authorization
in: header
description: Bearer authentication
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/type_podcasts_PodcastShowsListResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'401':
description: Unauthorized. The API key or OAuth access token is missing, invalid, or expired.
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'404':
description: Resource Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'429':
description: Rate Limit Exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
/publications/{publicationId}/podcasts/{podcastShowId}:
get:
operationId: get-podcast
summary: 'Get podcast OAuth Scope: podcasts:read'
description: Retrieve a single podcast belonging to a specific publication.
tags:
- podcasts
parameters:
- name: publicationId
in: path
description: The prefixed ID of the publication object
required: true
schema:
$ref: '#/components/schemas/type_ids_PublicationId'
- name: podcastShowId
in: path
description: The prefixed ID of the podcast
required: true
schema:
$ref: '#/components/schemas/type_ids_PodcastShowId'
- name: Authorization
in: header
description: Bearer authentication
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/type_podcasts_PodcastShowGetResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'401':
description: Unauthorized. The API key or OAuth access token is missing, invalid, or expired.
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'404':
description: Resource Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'429':
description: Rate Limit Exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
/publications/{publicationId}/podcasts/{podcastShowId}/episodes:
get:
operationId: list-episodes
summary: 'List podcast episodes OAuth Scope: podcasts:read'
description: Retrieve all episodes belonging to a specific podcast.
tags:
- podcasts
parameters:
- name: publicationId
in: path
description: The prefixed ID of the publication object
required: true
schema:
$ref: '#/components/schemas/type_ids_PublicationId'
- name: podcastShowId
in: path
description: The prefixed ID of the podcast
required: true
schema:
$ref: '#/components/schemas/type_ids_PodcastShowId'
- name: limit
in: query
description: A limit on the number of objects to be returned. The limit can range between 1 and 100, and the default is 10.
required: false
schema:
type: integer
- name: cursor
in: query
description: Use this opaque cursor token to fetch the next page of results. Obtain the value from `next_cursor` in a previous response.
required: false
schema:
type: string
- name: status
in: query
description: Optionally filter the results by the status of the episode.
`draft` - Not yet published.
`scheduled` - Scheduled for future publication.
`published` - Available via web and RSS.
`archived` - No longer available via web or RSS.
required: false
schema:
$ref: '#/components/schemas/type_podcasts_PodcastEpisodeStatus'
- name: order_by
in: query
description: The field that the results are sorted by. Defaults to `displayed_date`
`created` - The time in which the episode was first created.
`updated` - The time the episode was last updated.
`publish_date` - The exact time the system published the episode (when it went live), not the scheduled time the user set.
`displayed_date` - The time displayed in place of the `publish_date`. Uses a custom display date if set, otherwise the scheduled time the user set for publication, otherwise the `publish_date`, otherwise the creation date. For imported episodes, the original feed's `pubDate` is stored as the custom display date. This is the same field used to order episodes in the podcast's RSS feed.
required: false
schema:
$ref: '#/components/schemas/type_podcasts_PodcastEpisodeOrderBy'
- name: direction
in: query
description: The direction that the results are sorted in. Defaults to desc
`asc` - Ascending, sorts from smallest to largest.
`desc` - Descending, sorts from largest to smallest.
required: false
schema:
$ref: '#/components/schemas/type__RequestDirection'
- name: Authorization
in: header
description: Bearer authentication
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/type_podcasts_PodcastEpisodesListResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'401':
description: Unauthorized. The API key or OAuth access token is missing, invalid, or expired.
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'404':
description: Resource Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'429':
description: Rate Limit Exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
/publications/{publicationId}/podcasts/{podcastShowId}/episodes/{podcastEpisodeId}:
get:
operationId: get-episode
summary: 'Get podcast episode OAuth Scope: podcasts:read'
description: Retrieve a single episode belonging to a specific podcast.
tags:
- podcasts
parameters:
- name: publicationId
in: path
description: The prefixed ID of the publication object
required: true
schema:
$ref: '#/components/schemas/type_ids_PublicationId'
- name: podcastShowId
in: path
description: The prefixed ID of the podcast
required: true
schema:
$ref: '#/components/schemas/type_ids_PodcastShowId'
- name: podcastEpisodeId
in: path
description: The prefixed ID of the episode
required: true
schema:
$ref: '#/components/schemas/type_ids_PodcastEpisodeId'
- name: Authorization
in: header
description: Bearer authentication
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/type_podcasts_PodcastEpisodeGetResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'401':
description: Unauthorized. The API key or OAuth access token is missing, invalid, or expired.
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'404':
description: Resource Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'429':
description: Rate Limit Exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/type__Error'
components:
schemas:
type_podcasts_PodcastEpisodesListResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/type_podcasts_PodcastEpisode'
description: A list of episodes for this podcast.
limit:
type: integer
description: The limit placed on the results. If no limit was specified in the request, this defaults to 10.
has_more:
type: boolean
description: Indicates whether there are more results available after the current page.
next_cursor:
type: string
description: The cursor token to use for fetching the next page of results. Null when has_more is false.
total_results:
type: integer
description: The total number of results from all pages.
required:
- data
- limit
- has_more
title: PodcastEpisodesListResponse
type_ids_PublicationId:
type: string
description: The prefixed ID of the publication.
title: PublicationId
type_podcasts_PodcastShow:
type: object
properties:
id:
$ref: '#/components/schemas/type_ids_PodcastShowId'
description: The prefixed ID of the podcast.
created:
type: integer
description: The time the podcast was created. Measured in seconds since the Unix epoch.
slug:
type: string
description: The URL slug of the podcast.
description:
type: string
description: The description of the podcast.
categories:
type: array
items:
type: string
description: Selected categories for the podcast, ordered by display position. Subcategories include the parent name (e.g. `News-Politics`).
artwork_url:
type: string
description: The URL of the podcast artwork. Empty string when no artwork is set.
status:
$ref: '#/components/schemas/type_podcasts_PodcastShowStatus'
description: The status of the podcast.
`draft` - No episodes have been published.
`live` - Published and active.
`archived` - The podcast is no longer active.
language:
type: string
description: The ISO 639-1 two-letter language code for the podcast (e.g. `en`, `es`).
title:
type: string
description: The title of the podcast.
author:
type: string
description: The author of the podcast. Defaults to the publication name.
type:
$ref: '#/components/schemas/type_podcasts_PodcastShowType'
description: The type of the podcast.
`episodic` - Episodes can be consumed in any order.
`serial` - Episodes are intended to be consumed in order.
imported:
type: boolean
description: Whether the podcast was created via an import.
copyright:
type: string
description: The copyright text for the podcast. Defaults to the publication name.
publishing_frequency:
type: integer
description: The most common interval, in whole days, between consecutive published episodes (the statistical mode of day gaps). Gaps are measured using each episode's display date — the custom display date if set, otherwise the scheduled time, otherwise the publish date, otherwise the creation date. Null when fewer than two published episodes exist or a frequency has not been calculated yet.
website_url:
type: string
description: The website URL associated with the podcast.
explicit:
type: boolean
description: Whether the podcast is marked as explicit.
platform_links:
type: object
additionalProperties:
type: string
description: Platform distribution URLs keyed by platform name (e.g. `apple`, `spotify`, `youtube`). Present only for public podcasts. Platforms without a URL are null. Omitted for premium podcasts (limited to paid tiers), which use a private RSS feed with a unique URL per eligible subscriber.
required:
- id
- created
- slug
- description
- categories
- artwork_url
- status
- language
- title
- author
- type
- imported
- copyright
- explicit
title: PodcastShow
type_podcasts_PodcastEpisodeGetResponse:
type: object
properties:
data:
$ref: '#/components/schemas/type_podcasts_PodcastEpisode'
required:
- data
title: PodcastEpisodeGetResponse
type__Error:
type: object
properties:
status:
type: integer
statusText:
type: string
errors:
type: array
items:
$ref: '#/components/schemas/type__ErrorDetail'
required:
- status
- statusText
- errors
description: The top level error response.
title: Error
type_podcasts_PodcastShowStatus:
type: string
enum:
- draft
- live
- archived
description: The status of the podcast.
`draft` - No episodes have been published.
`live` - Published and active.
`archived` - The podcast is no longer active.
title: PodcastShowStatus
type__RequestDirection:
type: string
enum:
- asc
- desc
default: asc
description: The direction of the request. Defaults to `asc`.
title: RequestDirection
type_podcasts_PodcastShowType:
type: string
enum:
- episodic
- serial
description: The type of the podcast.
`episodic` - Episodes can be consumed in any order.
`serial` - Episodes are intended to be consumed in order.
title: PodcastShowType
type_podcasts_PodcastShowGetResponse:
type: object
properties:
data:
$ref: '#/components/schemas/type_podcasts_PodcastShow'
required:
- data
title: PodcastShowGetResponse
type_podcasts_PodcastEpisode:
type: object
properties:
id:
$ref: '#/components/schemas/type_ids_PodcastEpisodeId'
description: The prefixed ID of the episode.
created:
type: integer
description: The time the episode was created. Measured in seconds since the Unix epoch.
updated:
type: integer
description: The time the episode was last updated. Measured in seconds since the Unix epoch.
title:
type: string
description: The title of the episode.
slug:
type: string
description: The web slug where this episode can be accessed.
publish_date:
type: integer
description: The exact time the system published the episode (when it went live), not the scheduled time the user set for publication. Measured in seconds since the Unix epoch. Null when the episode has not been published.
displayed_date:
type: integer
description: The time displayed in place of the `publish_date`. Measured in seconds since the Unix epoch. Uses a custom display date if set, otherwise the scheduled time the user set for publication, otherwise the `publish_date`, otherwise the creation date. For imported episodes, the original feed's `pubDate` is stored as the custom display date so the episode keeps its original date in feeds even though `publish_date` reflects when it was published in beehiiv. This is the same field used to order episodes in the podcast's RSS feed.
duration:
type: integer
description: The duration of the episode audio in seconds. Null when no completed audio file is available.
description:
type: string
description: A plain-text, truncated version of the episode show notes (max 255 characters). Derived from the same content as `show_notes`.
show_notes:
type: string
description: The full HTML show notes for the episode. `description` is a truncated plain-text version of this content.
artwork_url:
type: string
description: The URL of the episode artwork. Falls back to the podcast artwork when the episode has none. Empty string when no artwork is set.
status:
$ref: '#/components/schemas/type_podcasts_PodcastEpisodeStatus'
description: The status of the episode.
`draft` - Not yet published.
`scheduled` - Scheduled for future publication.
`published` - Available via web and RSS.
`archived` - No longer available via web or RSS.
season_number:
type: integer
description: The season number for the episode, if set.
episode_number:
type: integer
description: The episode number within the season, if set.
audio_url:
type: string
description: The public streaming URL for the episode audio. Null when no completed audio file is available.
transcript_url:
type: string
description: The WebVTT transcript URL for the episode. Null when transcripts are disabled or no completed transcript is available.
show:
$ref: '#/components/schemas/type_podcasts_PodcastShow'
description: The podcast this episode belongs to.
required:
- id
- created
- updated
- title
- slug
- displayed_date
- description
- show_notes
- artwork_url
- status
- show
title: PodcastEpisode
type_ids_PodcastEpisodeId:
type: string
description: The prefixed ID of the podcast episode.
title: PodcastEpisodeId
type__ErrorDetail:
type: object
properties:
message:
type: string
code:
type: string
required:
- message
- code
title: ErrorDetail
type_podcasts_PodcastEpisodeOrderBy:
type: string
enum:
- created
- updated
- publish_date
- displayed_date
default: displayed_date
description: The field that episode list results are sorted by. Defaults to `displayed_date`
`created` - The time in which the episode was first created.
`updated` - The time the episode was last updated.
`publish_date` - The exact time the system published the episode (when it went live), not the scheduled time the user set.
`displayed_date` - The time displayed in place of the `publish_date`. Uses a custom display date if set, otherwise the scheduled time the user set for publication, otherwise the `publish_date`, otherwise the creation date. For imported episodes, the original feed's `pubDate` is stored as the custom display date. This is the same field used to order episodes in the podcast's RSS feed.
title: PodcastEpisodeOrderBy
type_podcasts_PodcastEpisodeStatus:
type: string
enum:
- draft
- scheduled
- published
- archived
description: The status of the episode.
`draft` - Not yet published.
`scheduled` - Scheduled for future publication.
`published` - Available via web and RSS.
`archived` - No longer available via web or RSS.
title: PodcastEpisodeStatus
type_ids_PodcastShowId:
type: string
description: The prefixed ID of the podcast.
title: PodcastShowId
type_podcasts_PodcastShowsListResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/type_podcasts_PodcastShow'
description: A list of podcasts for this publication.
limit:
type: integer
description: The limit placed on the results. If no limit was specified in the request, this defaults to 10.
has_more:
type: boolean
description: Indicates whether there are more results available after the current page.
next_cursor:
type: string
description: The cursor token to use for fetching the next page of results. Null when has_more is false.
total_results:
type: integer
description: The total number of results from all pages.
required:
- data
- limit
- has_more
title: PodcastShowsListResponse
securitySchemes:
BearerAuthScheme:
type: http
scheme: bearer