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:
When a user claims a site, they can create/sign in to Podpage and then fully manage that podcast page in the Podpage dashboard.
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" \
...Creates a podcast website from an RSS feed. The site is immediately public and episodes begin syncing.
Required fields
rss_feed_url — RSS feed URLpartner_podcast_id (string) — Your unique podcast ID in your system. Always send as a string (for example: "abc123" or "98765"). If an integer is sent, it will be converted to a string automatically, but we recommend always using strings for consistency. Maximum 128 characters. Lookups are case-insensitive.Optional fields
slug — Preferred website slug (for example: https://websites.partner.com/[slug]/). Maximum 128 characters; we recommend keeping slugs under 20 characters. The value is run through Django's slugify, which lowercases the input and replaces spaces/special characters with hyphens. Certain reserved slugs (for example: episodes, blog, about) are rejected. No profanity filter is applied. 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 objectgoogle_analytics_id — Google Analytics ID like G-XXXXXXXXXXprimary_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/falseColor values: Use hex strings, for example #112233.
Example request
curl -X POST https://www.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).
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 siteExample request
curl -X POST https://www.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.
Fetches the current partner site summary for one podcast.
Path params
partner_podcast_idExample request
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://www.podpage.com/api/partners/sites/abc123/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).
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 changes, we provide a limited update endpoint.
Path params
partner_podcast_id (string) — Your podcast ID in your system. Always send as a string. Lookups are case-insensitive.Optional fields
slug — New website slug. Maximum 128 characters; we recommend keeping slugs under 20 characters. The value is lowercased and special characters are replaced with hyphens. Reserved slugs (for example: episodes, blog, about) are rejected. No profanity filter is applied. Must be unique across all Podpage sites. If the slug is already taken, the API returns a 409 error with "field": "slug" instead of silently renaming. When the slug is updated successfully, the response includes the new slug and site_url.primary_colortext_colorbackground_colordark_mode — true/falseExample request
curl -X POST https://www.podpage.com/api/partners/sites/abc123/update/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"slug": "my-new-slug", "primary_color": "#112233", "dark_mode": true}'Example response (200)
{
"partner_podcast_id": "abc123",
"status": "updated",
"slug": "my-new-slug",
"site_url": "https://websites.partner.com/my-new-slug/",
"primary_color": "#112233",
"text_color": null,
"background_color": null,
"dark_mode": true
}slug and site_url are only included when the slug was actually changed. The four appearance fields are always returned.
Slug errors
400 — "Slug cannot be empty."400 — "The slug '...' is reserved and cannot be used." (e.g. episodes, blog, about)409 — "The slug '...' is already taken."All slug errors include "field": "slug" in the JSON response.
Errors: 400 (missing fields/invalid payload/reserved slug), 401 (invalid API key), 404 (no matching site), 409 (slug already taken), 429 (rate limit).
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_idExample request
curl -X POST https://www.podpage.com/api/partners/sites/abc123/detach/ \
-H "Authorization: Bearer YOUR_API_KEY"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).
Returns a short aggregate summary for the requesting partner.
Example request
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://www.podpage.com/api/partners/sites/Example response (200)
{
"total_partner_sites": 42,
"with_user_account": 30,
"upgraded_basic": 10,
"upgraded_pro": 5,
"upgraded_elite": 1
}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 request
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://www.podpage.com/api/partners/sites/list/?page=1&page_size=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).
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:
claim_url from the API response.claim_url.Path params
partner_podcast_idExample request
curl -X POST https://www.podpage.com/api/partners/sites/abc123/claim-link/ \
-H "Authorization: Bearer YOUR_API_KEY"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.