Captivate Shows API
Read and update a show's metadata (title, description, categories, author, language, links), upload show artwork, and retrieve the show's public RSS feed URL.
Read and update a show's metadata (title, description, categories, author, language, links), upload show artwork, and retrieve the show's public RSS feed URL.
openapi: 3.1.0
info:
title: Captivate API
version: '1.0'
description: >-
Public REST API for the Captivate podcast hosting, distribution, and
analytics platform. Authenticate a user with their user ID and API token to
obtain a Bearer token, then manage shows, episodes, and media and read
detailed listening analytics (insights). Endpoints, paths, methods, and
request fields in this document are transcribed from Captivate's public
Postman documentation at https://docs.captivate.fm. Response schemas are
modeled honestly - Captivate's public docs describe the requests and fields
but do not publish full JSON response schemas, so response bodies below are
generic objects and marked as modeled.
contact:
name: Captivate API Support
email: api@captivate.fm
url: https://docs.captivate.fm/
x-endpoints-source: >-
Paths and request fields confirmed from the public Captivate API Postman
collection (docs.captivate.fm). Response bodies are modeled.
servers:
- url: https://api.captivate.fm
description: Captivate production API
tags:
- name: Authentication
description: Exchange a user ID and API token for a Bearer token.
- name: Users
description: Read a user and list the shows they can access or manage.
- name: Shows
description: Read and update shows, upload artwork, get the RSS feed URL.
- name: Episodes
description: List, read, create, and update episodes.
- name: Media
description: Upload, read, list, and search a show's audio media.
- name: Analytics
description: Podcast and episode listening analytics (insights).
paths:
/authenticate/token:
post:
operationId: authenticateUser
tags:
- Authentication
summary: Authenticate User
description: >-
All requests must be authenticated using a Bearer token for the user.
Obtain the token by sending the user's ID and their API token (both
found in the API section of the Captivate account). Returns a Bearer
token used in the Authorization header for all other requests.
security: []
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- username
- token
properties:
username:
type: string
description: The Captivate user ID (UUID).
example: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
token:
type: string
description: The user's API token from their Captivate account.
responses:
'200':
description: Authentication succeeded; a Bearer token is returned (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/AuthToken'
'401':
$ref: '#/components/responses/Unauthorized'
/users/{id}:
get:
operationId: getUser
tags:
- Users
summary: Get User
description: Get a user record by user ID.
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'200':
description: The user record (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/users/{id}/shows:
get:
operationId: getUserShows
tags:
- Users
summary: Get Users Shows
description: The shows that this user can access regardless of their role.
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'200':
description: A list of shows the user can access (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/users/{id}/shows/manager:
get:
operationId: getUserManagedShows
tags:
- Users
summary: Get Users Managed Shows
description: >-
The shows that the user is manager or owner of; they can create and
invite new users to these shows.
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'200':
description: A list of shows the user manages or owns (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/shows/{id}/:
get:
operationId: getShow
tags:
- Shows
summary: Get Show
description: Get the show information by the show ID.
parameters:
- $ref: '#/components/parameters/ShowId'
responses:
'200':
description: The show record (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/shows/{id}:
put:
operationId: updateShow
tags:
- Shows
summary: Update Show
description: Update the show's metadata.
parameters:
- $ref: '#/components/parameters/ShowId'
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
title:
type: string
example: My Demo Show
description:
type: string
summary:
type: string
subtitle:
type: string
author:
type: string
name:
type: string
'categories[0]':
type: string
description: Apple Podcasts category code, e.g. 01.00.
itunes_email:
type: string
copyright:
type: string
explicit:
type: string
description: e.g. clean, explicit.
order:
type: string
example: DESC
limit:
type: string
type:
type: string
description: e.g. episodic or serial.
language:
type: string
example: en
donation_link:
type: string
link:
type: string
third_party_analytics:
type: string
description: Third-party analytics prefix, e.g. a Chartable tracking URL.
responses:
'200':
description: The updated show (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/shows/{id}/artwork:
post:
operationId: createShowArtwork
tags:
- Shows
summary: Create Show Artwork
description: >-
Upload the show's artwork. The file must be a JPG or PNG in the RGB
colorspace (not CMYK), completely square, with a minimum of 1400px
height.
parameters:
- $ref: '#/components/parameters/ShowId'
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- file
properties:
file:
type: string
format: binary
description: Square JPG or PNG artwork, RGB, minimum 1400px.
responses:
'200':
description: Artwork accepted (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/shows/{id}/feed:
get:
operationId: getShowFeedUrl
tags:
- Shows
summary: Get Show Feed URL
description: Get the public RSS feed URL for this show.
parameters:
- $ref: '#/components/parameters/ShowId'
responses:
'200':
description: The RSS feed URL (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/shows/{id}/episodes:
get:
operationId: getShowEpisodes
tags:
- Episodes
summary: Get Show Episodes
description: >-
A full breakdown of all the episodes for this show plus a count of the
total number of episodes.
parameters:
- $ref: '#/components/parameters/ShowId'
responses:
'200':
description: The show's episodes and a count (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/shows/{id}/episodes/scheduled:
get:
operationId: getShowScheduledEpisodes
tags:
- Episodes
summary: Get Show Scheduled Episodes
description: All scheduled (future) episodes for this show plus a count.
parameters:
- $ref: '#/components/parameters/ShowId'
responses:
'200':
description: The show's scheduled episodes and a count (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/episodes/{id}:
get:
operationId: getEpisode
tags:
- Episodes
summary: Get Episode
description: Get the full information for an episode by episode ID.
parameters:
- $ref: '#/components/parameters/EpisodeId'
responses:
'200':
description: The episode record (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
put:
operationId: updateEpisode
tags:
- Episodes
summary: Update Episode
description: Update an existing episode.
parameters:
- $ref: '#/components/parameters/EpisodeId'
requestBody:
required: true
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/EpisodeInput'
responses:
'200':
description: The updated episode (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/episodes:
post:
operationId: createEpisode
tags:
- Episodes
summary: Create Episode
description: Create an episode with the following parameters.
requestBody:
required: true
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/EpisodeInput'
responses:
'200':
description: The created episode (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/media/{id}:
get:
operationId: getMedia
tags:
- Media
summary: Get Media
description: Get the information for this media ID.
parameters:
- $ref: '#/components/parameters/MediaId'
responses:
'200':
description: The media record (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/shows/{id}/media:
post:
operationId: uploadMedia
tags:
- Media
summary: Upload Media
description: >-
Upload a media (audio) file and assign it to the given show ID.
Captivate processes the file server-side.
parameters:
- $ref: '#/components/parameters/ShowId'
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- file
properties:
file:
type: string
format: binary
description: The audio media file to upload.
responses:
'200':
description: The uploaded media record (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
get:
operationId: getShowMedia
tags:
- Media
summary: Get Show Media
description: >-
Get all media for the given show ID. Media cannot be shared across
shows, so this is scoped to a single show.
parameters:
- $ref: '#/components/parameters/ShowId'
- name: offset
in: query
schema:
type: integer
default: 0
- name: order
in: query
schema:
type: string
default: created_at
- name: sort
in: query
schema:
type: string
enum:
- ASC
- DESC
default: DESC
responses:
'200':
description: The show's media list (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/shows/{id}/media/search:
get:
operationId: searchShowMedia
tags:
- Media
summary: Search Show Media
description: Search a show's media by media name.
parameters:
- $ref: '#/components/parameters/ShowId'
- name: search
in: query
required: true
schema:
type: string
description: The media name search query.
- name: offset
in: query
schema:
type: integer
default: 0
- name: order
in: query
schema:
type: string
default: created_at
- name: sort
in: query
schema:
type: string
enum:
- ASC
- DESC
default: DESC
responses:
'200':
description: Matching media (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/overview:
get:
operationId: getPodcastOverviewAnalytics
tags:
- Analytics
summary: Get Overview Analytics for Podcast
description: Overview analytics for a podcast over a date range.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
- $ref: '#/components/parameters/StartQuery'
- $ref: '#/components/parameters/EndQuery'
- name: includeTopEpisodes
in: query
schema:
type: boolean
default: true
responses:
'200':
description: Podcast overview analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/overview/{episodeId}:
get:
operationId: getEpisodeOverviewAnalytics
tags:
- Analytics
summary: Get Overview Analytics for a specific Episode
description: Overview analytics for a specific episode over a date range.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
- $ref: '#/components/parameters/InsightsEpisodeId'
- $ref: '#/components/parameters/StartQuery'
- $ref: '#/components/parameters/EndQuery'
responses:
'200':
description: Episode overview analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/averages:
get:
operationId: getPodcastAverageAnalytics
tags:
- Analytics
summary: Get Average Analytics for Podcast
description: Average analytics for a podcast over an interval window.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
- name: intervalDays
in: query
schema:
type: integer
default: 28
responses:
'200':
description: Podcast average analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/total:
get:
operationId: getPodcastAllTimeTotal
tags:
- Analytics
summary: Get All-Time Total for Podcast
description: All-time total analytics for a podcast.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
responses:
'200':
description: Podcast all-time total (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/total/{episodeId}:
get:
operationId: getEpisodeAllTimeTotal
tags:
- Analytics
summary: Get All-Time Total for Episode
description: All-time total analytics for a specific episode.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
- $ref: '#/components/parameters/InsightsEpisodeId'
responses:
'200':
description: Episode all-time total (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/monthly:
get:
operationId: getPodcastMonthlyAnalytics
tags:
- Analytics
summary: Get Month-by-Month Analytics for Podcast
description: Month-by-month analytics series for a podcast.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
responses:
'200':
description: Podcast monthly analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/monthly/{episodeId}:
get:
operationId: getEpisodeMonthlyAnalytics
tags:
- Analytics
summary: Get Month-by-Month Analytics for Episode
description: Month-by-month analytics series for a specific episode.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
- $ref: '#/components/parameters/InsightsEpisodeId'
responses:
'200':
description: Episode monthly analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/range:
post:
operationId: getPodcastRangeAnalytics
tags:
- Analytics
summary: Get Analytics in Range for Podcast
description: >-
Analytics for a podcast over an arbitrary date range, broken down by the
requested dimension types.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RangeRequest'
responses:
'200':
description: Podcast range analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/range/{episodeId}:
post:
operationId: getEpisodeRangeAnalytics
tags:
- Analytics
summary: Get Analytics in Range for Episode
description: >-
Analytics for a specific episode over an arbitrary date range, broken
down by the requested dimension types.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
- $ref: '#/components/parameters/InsightsEpisodeId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RangeRequest'
responses:
'200':
description: Episode range analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/compare:
post:
operationId: compareEpisodeAnalytics
tags:
- Analytics
summary: Get Analytics Comparison between Episodes
description: Compare analytics across a set of episodes.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
requestBody:
required: true
content:
application/json:
schema:
type: array
items:
type: object
properties:
id:
type: string
title:
type: string
published_date:
type: string
format: date-time
responses:
'200':
description: Episode comparison analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
/insights/{showId}/web-player/{episodeId}:
post:
operationId: getWebPlayerAnalytics
tags:
- Analytics
summary: Get Web Player Analytics for Podcast
description: Web-player analytics for a podcast, scoped to an episode context.
parameters:
- $ref: '#/components/parameters/InsightsShowId'
- $ref: '#/components/parameters/InsightsEpisodeId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
dateRange:
type: object
properties:
gte:
type: string
format: date-time
lte:
type: string
format: date-time
duration:
type: string
timezone:
type: string
example: America/New_York
responses:
'200':
description: Web-player analytics (modeled).
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
'401':
$ref: '#/components/responses/Unauthorized'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: >-
Bearer token obtained from POST /authenticate/token. Sent as
Authorization: Bearer {token}.
parameters:
UserId:
name: id
in: path
required: true
description: The Captivate user ID (UUID).
schema:
type: string
ShowId:
name: id
in: path
required: true
description: The show ID (UUID).
schema:
type: string
EpisodeId:
name: id
in: path
required: true
description: The episode ID (UUID).
schema:
type: string
MediaId:
name: id
in: path
required: true
description: The media ID (UUID).
schema:
type: string
InsightsShowId:
name: showId
in: path
required: true
description: The show ID (UUID) for insights.
schema:
type: string
InsightsEpisodeId:
name: episodeId
in: path
required: true
description: The episode ID (UUID) for insights.
schema:
type: string
StartQuery:
name: start
in: query
schema:
type: string
format: date-time
example: '2022-09-01T00:00:00.000Z'
EndQuery:
name: end
in: query
schema:
type: string
format: date-time
example: '2022-09-01T00:00:00.000Z'
responses:
Unauthorized:
description: Missing or invalid Bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/GenericObject'
schemas:
AuthToken:
type: object
description: >-
Modeled authentication response. Captivate returns a Bearer token used
for all subsequent requests; the exact envelope is not published.
properties:
success:
type: boolean
user:
type: object
token:
type: string
EpisodeInput:
type: object
description: Fields for creating or updating an episode (multipart form-data).
required:
- shows_id
- title
properties:
shows_id:
type: string
description: The show ID (UUID) the episode belongs to.
title:
type: string
example: My Demo Episode
itunes_title:
type: string
media_id:
type: string
description: The uploaded media ID (UUID) to attach as the episode audio.
date:
type: string
description: Publish date, format YYYY-MM-DD HH:mm:ss.
status:
type: string
description: e.g. Draft, Published.
example: Draft
shownotes:
type: string
summary:
type: string
itunes_subtitle:
type: string
author:
type: string
episode_art:
type: string
description: URL to episode artwork.
explicit:
type: string
episode_type:
type: string
description: e.g. full, trailer, bonus.
episode_season:
type: string
episode_number:
type: string
donation_link:
type: string
donation_text:
type: string
link:
type: string
itunes_block:
type: string
description: 'true or false: whether to block the episode from Apple Podcasts.'
RangeRequest:
type: object
description: Request body for range analytics.
properties:
start:
type: string
format: date-time
end:
type: string
format: date-time
interval:
type: string
example: 1d
timezone:
type: string
example: America/New_York
countryCode:
type:
- string
- 'null'
types:
type: array
items:
type: string
enum:
- byLocation
- byUserAgentBrowser
- byUserAgentOs
- byUserAgentDevice
- byEpisode
- byPrivateSubscriber
GenericObject:
type: object
description: >-
Modeled response object. Captivate's public documentation describes
requests and fields but does not publish full JSON response schemas, so
response bodies are represented generically.
additionalProperties: true
security:
- bearerAuth: []