Podbean Podcasts API

Read the authorized podcast's profile and settings, and - via the Multiple Podcasts token flow - enumerate the podcasts an agency or network app is authorized to manage. The entry point for building podcast-aware apps on top of Podbean.

OpenAPI Specification

podbean-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Podbean API
  description: >-
    The Podbean API lets third-party apps and integrations manage a user's
    podcast on the Podbean hosting, distribution, and monetization platform.
    It is a REST API over HTTPS authenticated with OAuth 2.0. Apps register at
    developers.podbean.com to obtain a Client ID and Secret, then acquire an
    access token via the Authorization Code flow (to act on behalf of another
    user's podcast), the Client Credentials flow (to manage their own podcast),
    or the Multiple Podcasts token flow (for agencies and networks managing many
    podcasts). Documented resources cover Podcasts, Episodes, media file upload
    authorization, oEmbed embedding, and Analytics reports. Write operations use
    POST with form-encoded bodies. This description is grounded in Podbean's
    public developer documentation; some request/response schemas are
    represented generically and should be reconciled against the live docs.
  version: '1.0'
  contact:
    name: Podbean Developer Platform
    url: https://developers.podbean.com
  license:
    name: Proprietary
    url: https://www.podbean.com/terms
servers:
  - url: https://api.podbean.com/v1
    description: Podbean API v1
security:
  - oauth2: []
tags:
  - name: Authentication
    description: OAuth 2.0 login dialog, token exchange, inspection, and multi-podcast tokens.
  - name: Podcast
    description: Read the authorized podcast profile and settings.
  - name: Episode
    description: List, read, publish, update, and delete podcast episodes.
  - name: File Upload
    description: Authorize a media/image upload and list uploaded media files.
  - name: oEmbed
    description: Embeddable player markup and metadata for a podcast or episode URL.
  - name: Analytics
    description: Download, engagement, and advertising reports.
paths:
  /dialog/oauth:
    get:
      operationId: loginDialog
      tags:
        - Authentication
      summary: OAuth 2.0 login dialog
      description: >-
        Redirect the user here to authorize a third-party app. On approval,
        Podbean redirects back to the app's redirect_uri with an authorization
        code to exchange at /oauth/token.
      security: []
      parameters:
        - name: client_id
          in: query
          required: true
          schema:
            type: string
        - name: redirect_uri
          in: query
          required: true
          schema:
            type: string
        - name: response_type
          in: query
          required: true
          schema:
            type: string
            enum:
              - code
        - name: scope
          in: query
          required: false
          schema:
            type: string
        - name: state
          in: query
          required: false
          schema:
            type: string
      responses:
        '302':
          description: Redirect back to redirect_uri with an authorization code.
  /oauth/token:
    post:
      operationId: getAccessToken
      tags:
        - Authentication
      summary: Exchange for an access token
      description: >-
        Exchange an authorization code, client credentials, or a refresh token
        for an OAuth 2.0 access token. Supports grant_type values
        authorization_code, client_credentials, and refresh_token.
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                grant_type:
                  type: string
                  enum:
                    - authorization_code
                    - client_credentials
                    - refresh_token
                client_id:
                  type: string
                client_secret:
                  type: string
                code:
                  type: string
                redirect_uri:
                  type: string
                refresh_token:
                  type: string
              required:
                - grant_type
      responses:
        '200':
          description: An access token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccessToken'
        '400':
          $ref: '#/components/responses/BadRequest'
  /oauth/debugToken:
    post:
      operationId: debugToken
      tags:
        - Authentication
      summary: Inspect an access token
      description: Returns metadata about an access token - the podcast it is bound to, scopes, and expiry.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                access_token:
                  type: string
              required:
                - access_token
      responses:
        '200':
          description: Token metadata.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
  /oauth/multiplePodcastsToken:
    post:
      operationId: getMultiplePodcastsToken
      tags:
        - Authentication
      summary: Get Multiple Podcasts tokens
      description: >-
        For agencies and networks - exchange client credentials for per-podcast
        access tokens covering all podcasts the app is authorized to manage.
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                grant_type:
                  type: string
                  enum:
                    - client_credentials
                client_id:
                  type: string
                client_secret:
                  type: string
              required:
                - grant_type
                - client_id
                - client_secret
      responses:
        '200':
          description: Per-podcast access tokens.
          content:
            application/json:
              schema:
                type: object
                properties:
                  podcasts:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
  /podcast:
    get:
      operationId: getPodcast
      tags:
        - Podcast
      summary: Get the authorized podcast
      description: Returns the profile and settings of the podcast the access token is bound to.
      responses:
        '200':
          description: The podcast.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Podcast'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /episodes:
    get:
      operationId: listEpisodes
      tags:
        - Episode
      summary: List episodes
      description: Lists episodes for the authorized podcast, with paging via offset and limit.
      parameters:
        - name: access_token
          in: query
          required: false
          schema:
            type: string
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            default: 0
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            default: 20
            maximum: 100
      responses:
        '200':
          description: A list of episodes.
          content:
            application/json:
              schema:
                type: object
                properties:
                  episodes:
                    type: array
                    items:
                      $ref: '#/components/schemas/Episode'
                  offset:
                    type: integer
                  limit:
                    type: integer
                  count:
                    type: integer
                  has_more:
                    type: boolean
        '401':
          $ref: '#/components/responses/Unauthorized'
    post:
      operationId: publishEpisode
      tags:
        - Episode
      summary: Publish a new episode
      description: >-
        Publishes a new episode. Reference a media_key (and optional logo_key)
        obtained from /files/uploadAuthorize.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/EpisodeInput'
      responses:
        '200':
          description: The published episode.
          content:
            application/json:
              schema:
                type: object
                properties:
                  episode:
                    $ref: '#/components/schemas/Episode'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /episodes/{id}:
    get:
      operationId: getEpisode
      tags:
        - Episode
      summary: Read an episode
      description: Returns a single episode by its ID.
      parameters:
        - $ref: '#/components/parameters/EpisodeId'
      responses:
        '200':
          description: The episode.
          content:
            application/json:
              schema:
                type: object
                properties:
                  episode:
                    $ref: '#/components/schemas/Episode'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    post:
      operationId: updateEpisode
      tags:
        - Episode
      summary: Update an episode
      description: Updates an existing episode by ID. Fields are submitted as a form-encoded body.
      parameters:
        - $ref: '#/components/parameters/EpisodeId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/EpisodeInput'
      responses:
        '200':
          description: The updated episode.
          content:
            application/json:
              schema:
                type: object
                properties:
                  episode:
                    $ref: '#/components/schemas/Episode'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /episodes/{id}/delete:
    post:
      operationId: deleteEpisode
      tags:
        - Episode
      summary: Delete an episode
      description: Deletes an episode by ID. Podbean models deletion as a POST action.
      parameters:
        - $ref: '#/components/parameters/EpisodeId'
      requestBody:
        required: false
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                access_token:
                  type: string
      responses:
        '200':
          description: Deletion result.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /files/uploadAuthorize:
    get:
      operationId: authorizeFileUpload
      tags:
        - File Upload
      summary: Authorize a file upload
      description: >-
        Requests authorization to upload a media or image file. Returns a
        presigned URL to PUT the file bytes to, and a file_key to pass to the
        Episodes API when publishing.
      parameters:
        - name: access_token
          in: query
          required: false
          schema:
            type: string
        - name: filename
          in: query
          required: true
          schema:
            type: string
        - name: filesize
          in: query
          required: true
          schema:
            type: integer
        - name: content_type
          in: query
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Presigned upload details.
          content:
            application/json:
              schema:
                type: object
                properties:
                  presigned_url:
                    type: string
                    format: uri
                  expire_at:
                    type: integer
                  file_key:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
  /medias:
    get:
      operationId: listMedia
      tags:
        - File Upload
      summary: List media files
      description: Lists media files previously uploaded to the authorized podcast.
      parameters:
        - name: access_token
          in: query
          required: false
          schema:
            type: string
        - name: offset
          in: query
          required: false
          schema:
            type: integer
        - name: limit
          in: query
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: A list of media files.
          content:
            application/json:
              schema:
                type: object
                properties:
                  medias:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
  /oembed:
    get:
      operationId: oembed
      tags:
        - oEmbed
      summary: oEmbed
      description: >-
        Returns embeddable player markup and metadata for a Podbean podcast or
        episode URL, following the oEmbed spec. No authentication required.
      security: []
      parameters:
        - name: url
          in: query
          required: true
          schema:
            type: string
            format: uri
        - name: format
          in: query
          required: false
          schema:
            type: string
            enum:
              - json
              - xml
            default: json
        - name: maxwidth
          in: query
          required: false
          schema:
            type: integer
        - name: maxheight
          in: query
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: An oEmbed response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OEmbed'
  /analytics/podcastReports:
    get:
      operationId: getPodcastDownloadReports
      tags:
        - Analytics
      summary: Podcast download reports
      description: Returns download/listen counts for the authorized podcast over a date range.
      parameters:
        - $ref: '#/components/parameters/AccessTokenQuery'
        - name: start
          in: query
          required: false
          schema:
            type: string
            format: date
        - name: end
          in: query
          required: false
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Download report data.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '401':
          $ref: '#/components/responses/Unauthorized'
  /analytics/podcastEngagementReports:
    get:
      operationId: getPodcastEngagementReports
      tags:
        - Analytics
      summary: Podcast engagement reports
      description: Returns listener engagement data for the authorized podcast over a date range.
      parameters:
        - $ref: '#/components/parameters/AccessTokenQuery'
        - name: start
          in: query
          required: false
          schema:
            type: string
            format: date
        - name: end
          in: query
          required: false
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Engagement report data.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '401':
          $ref: '#/components/responses/Unauthorized'
  /analytics/advertiseReports:
    get:
      operationId: getAdvertiseReports
      tags:
        - Analytics
      summary: Advertising reports
      description: Returns advertising/monetization report data for the authorized podcast.
      parameters:
        - $ref: '#/components/parameters/AccessTokenQuery'
        - name: start
          in: query
          required: false
          schema:
            type: string
            format: date
        - name: end
          in: query
          required: false
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Advertising report data.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  securitySchemes:
    oauth2:
      type: oauth2
      description: OAuth 2.0. Register an app at developers.podbean.com to obtain a Client ID and Secret.
      flows:
        authorizationCode:
          authorizationUrl: https://api.podbean.com/v1/dialog/oauth
          tokenUrl: https://api.podbean.com/v1/oauth/token
          refreshUrl: https://api.podbean.com/v1/oauth/token
          scopes:
            episode_publish: Publish and manage episodes.
            episode_read: Read episodes.
            podcast_read: Read podcast profile and settings.
        clientCredentials:
          tokenUrl: https://api.podbean.com/v1/oauth/token
          scopes:
            episode_publish: Publish and manage episodes.
            podcast_read: Read podcast profile and settings.
  parameters:
    EpisodeId:
      name: id
      in: path
      required: true
      description: The episode ID.
      schema:
        type: string
    AccessTokenQuery:
      name: access_token
      in: query
      required: false
      schema:
        type: string
  responses:
    BadRequest:
      description: The request was malformed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing or invalid access token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: The requested resource was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    AccessToken:
      type: object
      properties:
        access_token:
          type: string
        token_type:
          type: string
          example: bearer
        expires_in:
          type: integer
        refresh_token:
          type: string
        scope:
          type: string
    Podcast:
      type: object
      properties:
        id:
          type: string
        title:
          type: string
        desc:
          type: string
        logo:
          type: string
          format: uri
        website:
          type: string
          format: uri
        category_name:
          type: string
        allow_episode_type:
          type: array
          items:
            type: string
        object:
          type: string
          example: Podcast
    Episode:
      type: object
      properties:
        id:
          type: string
        podcast_id:
          type: string
        title:
          type: string
        content:
          type: string
        logo:
          type: string
          format: uri
        media_url:
          type: string
          format: uri
        player_url:
          type: string
          format: uri
        permalink_url:
          type: string
          format: uri
        publish_time:
          type: integer
        duration:
          type: integer
        status:
          type: string
          enum:
            - publish
            - draft
            - future
        type:
          type: string
          enum:
            - public
            - premium
            - private
        object:
          type: string
          example: Episode
    EpisodeInput:
      type: object
      properties:
        access_token:
          type: string
        title:
          type: string
        content:
          type: string
        status:
          type: string
          enum:
            - publish
            - draft
            - future
        type:
          type: string
          enum:
            - public
            - premium
            - private
        media_key:
          type: string
          description: File key returned by /files/uploadAuthorize for the audio/video media.
        logo_key:
          type: string
          description: Optional file key for the episode cover image.
        season_number:
          type: integer
        episode_number:
          type: integer
        apple_episode_type:
          type: string
          enum:
            - full
            - trailer
            - bonus
      required:
        - title
    OEmbed:
      type: object
      properties:
        type:
          type: string
        version:
          type: string
        title:
          type: string
        provider_name:
          type: string
          example: Podbean
        provider_url:
          type: string
          format: uri
        html:
          type: string
        width:
          type: integer
        height:
          type: integer
        thumbnail_url:
          type: string
          format: uri
    Error:
      type: object
      properties:
        error:
          type: string
        error_description:
          type: string