Partner API documentation

Create and manage podcast websites via the Partner API.

Use this API to spin up podcast websites for your users. Sites are created and published immediately, but they are not tied to a Podpage user account until someone claims them.

Think of it as two parts:

  • Auto-provision: create the site from RSS and basic appearance/content inputs.
  • Claim flow: let your user attach their own Podpage account later when they want editing access.

When a user claims a site, they can create/sign in to Podpage and then fully manage that podcast page in the Podpage dashboard.

Authentication

All requests require an Authorization: Bearer <api_key> header. Your API key is provided during partner onboarding.

All partner APIs are strictly scoped to the authenticated partner. A partner can only read/update/create data for podcasts whose partner matches the authenticated partner key.

curl -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  ...

Site Endpoints

Create site

POST/api/partners/create/

Creates a podcast website from an RSS feed. The site is immediately public and episodes begin syncing.

Required fields

  • rss_feed_url — RSS feed URL
  • partner_podcast_id — Your podcast ID in your system

Optional fields

  • slug — Preferred website slug (for example: https://websites.partner.com/[slug]/). If taken, Podpage auto-increments safely.
  • social_links — Social links as an object.Send the Podpage social key as the name (for example: facebook, instagram, twitter, threads, youtube).Matching is case-insensitive and ignores punctuation.
  • player_links — Player links as an object.Send the Podpage player key as the name (for example: spotify, applepodcasts, amazonmusic, iheartradio).Matching is case-insensitive and ignores punctuation.
  • external_links — Arbitrary footer links as objects. These are only added in the site footer.
  • donate_link — Single donate URL, or donate_links object
  • google_analytics_id — Google Analytics ID like G-XXXXXXXXXX
  • primary_color — Hex color used for primary brand accents.
  • text_color — Hex color used for page text.
  • background_color — Hex color used for page background.
  • dark_mode — true/false

Color values: Use hex strings, for example #112233.

Example request

curl -X POST https://podpage.com/api/partners/create/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"rss_feed_url": "https://example.com/feed.xml", "partner_podcast_id": "abc123", "slug": "myshow", "social_links": {"facebook": "https://facebook.com/show", "instagram": "https://instagram.com/show"}, "player_links": {"applepodcasts": "https://podcasts.apple.com/show", "spotify": "https://open.spotify.com/show"}, "primary_color": "#112233", "dark_mode": true}'

Example response (200)

{
  "partner_podcast_id": "abc123",
  "site_url": "https://websites.partner.com/my-podcast/"
}

Errors: 400 (missing fields, malformed payload, invalid RSS), 401 (invalid API key), 429 (rate limit).

Bulk create sites

POST/api/partners/create/bulk/

Creates up to 50 podcast websites in a single request. Each item uses the same fields as Create site. Results are returned per-item; individual failures do not block other items.

Required fields

  • sites — An array of site objects (max 50), each containing rss_feed_url and partner_podcast_id plus any optional fields from Create site

Example request

curl -X POST https://podpage.com/api/partners/create/bulk/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sites": [{"rss_feed_url": "https://example.com/feed1.xml", "partner_podcast_id": "show-1"}, {"rss_feed_url": "https://example.com/feed2.xml", "partner_podcast_id": "show-2"}]}'

Example response (200)

{
  "results": [
    {"partner_podcast_id": "show-1", "site_url": "https://websites.partner.com/show-1/"},
    {"partner_podcast_id": "show-2", "site_url": "https://websites.partner.com/show-2/"}
  ]
}

Errors: 400 (invalid JSON, empty or oversized array), 401 (invalid API key), 429 (rate limit). Per-item errors appear inline in the results array.

Site detail

GET/api/partners/sites/<partner_podcast_id>/

Fetches the current partner site summary for one podcast.

Path params

  • partner_podcast_id

Response (200)

{
  "partner_podcast_id": "abc123",
  "website_url": "https://websites.partner.com/my-podcast/",
  "claimed": true,
  "plan": "free"
}

Errors: 401 (invalid API key), 404 (no matching site).

Update site

POST/api/partners/sites/<partner_podcast_id>/update/

If a user wants to fully customize their website, they should go through the claim process. However, if they just want to make some simple color changes, we provide a limited update endpoint.

Path params

  • partner_podcast_id — Your podcast ID in your system

Optional fields

  • primary_color
  • text_color
  • background_color
  • dark_mode — true/false

Example response (200)

{"partner_podcast_id":"abc123","status":"updated","primary_color":"#112233","dark_mode":true}

Errors: 400 (missing fields/invalid payload), 401 (invalid API key), 404 (no matching site), 429 (rate limit).

Detach site

POST/api/partners/sites/<partner_podcast_id>/detach/

Removes the partner association from a site. Unclaimed sites are deleted immediately. Claimed sites are unlinked from the partner and remain in place.

Claimed users receive an email explaining that their partnership has ended and that they can still manage the site by signing in to Podpage.

Path params

  • partner_podcast_id

Example response (200)

{"partner_podcast_id": "abc123", "status": "detached", "action": "unlinked"}

Errors: 401 (invalid API key), 404 (no matching site for this partner), 429 (rate limit).

Aggregate Stats

Partner sites summary

GET/api/partners/sites/

Returns a short aggregate summary for the requesting partner.

Example response (200)

{
  "total_partner_sites": 42,
  "with_user_account": 30,
  "upgraded_basic": 10,
  "upgraded_pro": 5,
  "upgraded_elite": 1
}

List all sites

GET/api/partners/sites/list/

Returns a paginated list of all sites belonging to the requesting partner.

Query params

  • page — Page number (default: 1)
  • page_size — Results per page, 1–100 (default: 50)

Example response (200)

{
  "sites": [
    {"partner_podcast_id": "abc123", "site_url": "https://websites.partner.com/my-podcast/", "claimed": true},
    {"partner_podcast_id": "def456", "site_url": "https://websites.partner.com/other-show/", "claimed": false}
  ],
  "total": 42,
  "page": 1,
  "page_size": 50
}

Errors: 401 (invalid API key), 429 (rate limit).

Let your users claim their website

Sites created by this API are live immediately, but they are not yet tied to a Podpage user account. If a user wants to make edits, change templates, or fully own the site as a Podpage account, they need to claim it and create/sign in to Podpage.

Here's how that works:

  1. User clicks “Claim this website” in your dashboard.
  2. Your backend calls Generate claim link.
  3. Read claim_url from the API response.
  4. Immediately redirect the user to claim_url.
  5. User completes sign-in/sign-up in Podpage and claims the site.
  6. Once claimed, they gain full editing rights in Podpage for that podcast page.
POST/api/partners/sites/<partner_podcast_id>/claim-link/

Path params

  • partner_podcast_id

Response (200)

{
  "partner_podcast_id": "abc123",
  "claim_url": "https://websites.partner.com/setup/my-podcast/complete/?partner_claim=eyJ0b2tlbiI6...",
  "expires_in_seconds": 60
}

Errors: 401 (invalid API key), 404 (no matching site), 409 (already claimed), 429 (rate limit).

The claim URL expires in 60 seconds; generate it only when the user clicks the button.