Appearance
List episodes of one of your podcasts
- Method:
GET - Path:
/v1/me/podcasts/{podcast_id}/episodes - Operation ID:
listMyEpisodes - Tags: Episodes
Every episode when you have permission to see every episode (episodes.view_all); otherwise only episodes you are on. Newest first. Drafts and scheduled episodes are included; media URLs never are in this list.
Scope: episodes:read.
Make a request
Set these environment variables before running a sample. Each language reads the same values; no identifier needs replacing inside the code.
| Variable | Value to supply |
|---|---|
SHOWFM_API_KEY | Your API key. Keep it on your server. |
PODCAST_ID | A podcast UUID returned by List your podcasts. |
Samples run on your server: curl 7.76+, Node.js 22+ (TypeScript via your TypeScript runner), Python 3, or PHP 8 with the cURL extension. Never put your API key in browser code.
bash
: "${SHOWFM_API_KEY:?Set SHOWFM_API_KEY in your environment}"
: "${PODCAST_ID:?Set PODCAST_ID in your environment}"
curl --fail-with-body --silent --show-error --get \
"https://api.show.fm/v1/me/podcasts/${PODCAST_ID}/episodes" \
--header "Authorization: Bearer ${SHOWFM_API_KEY}" \
--data-urlencode "status=published" \
--data-urlencode "limit=20"ts
function env(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name} in your environment`);
return value;
}
async function main() {
const url = new URL(`https://api.show.fm/v1/me/podcasts/${encodeURIComponent(env("PODCAST_ID"))}/episodes`);
url.searchParams.set("status", "published");
url.searchParams.set("limit", "20");
const response = await fetch(url, {
headers: { Authorization: `Bearer ${env("SHOWFM_API_KEY")}` },
signal: AbortSignal.timeout(30_000)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
console.log(JSON.stringify(await response.json(), null, 2));
}
main().catch(error => {
console.error(error);
process.exitCode = 1;
});js
function env(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name} in your environment`);
return value;
}
async function main() {
const url = new URL(`https://api.show.fm/v1/me/podcasts/${encodeURIComponent(env("PODCAST_ID"))}/episodes`);
url.searchParams.set("status", "published");
url.searchParams.set("limit", "20");
const response = await fetch(url, {
headers: { Authorization: `Bearer ${env("SHOWFM_API_KEY")}` },
signal: AbortSignal.timeout(30_000)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
console.log(JSON.stringify(await response.json(), null, 2));
}
main().catch(error => {
console.error(error);
process.exitCode = 1;
});python
import os
import json
from urllib.parse import quote, urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError
url = f'https://api.show.fm/v1/me/podcasts/{quote(os.environ["PODCAST_ID"], safe="")}/episodes'
url += "?" + urlencode({
"status": "published",
"limit": "20",
})
request = Request(url, headers={
"Authorization": "Bearer " + os.environ["SHOWFM_API_KEY"]
})
try:
with urlopen(request, timeout=30) as response:
print(json.dumps(json.load(response), indent=2))
except HTTPError as error:
raise RuntimeError(f"HTTP {error.code}: {error.read().decode()}") from errorphp
<?php
function requiredEnv(string $name): string {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Set $name in your environment");
}
return $value;
}
$url = "https://api.show.fm" . "/v1/me/podcasts/" . rawurlencode(requiredEnv("PODCAST_ID")) . "/episodes";
$url .= '?' . http_build_query([
"status" => "published",
"limit" => "20",
], '', '&', PHP_QUERY_RFC3986);
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . requiredEnv("SHOWFM_API_KEY")],
]);
$body = curl_exec($curl);
if ($body === false) {
throw new RuntimeException(curl_error($curl));
}
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status < 200 || $status >= 300) {
throw new RuntimeException("HTTP $status: $body");
}
echo json_encode(json_decode($body, false, 512, JSON_THROW_ON_ERROR), JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . PHP_EOL;Base URL
https://api.show.fm
Authentication
apiKey: HTTP bearer
An API key from Settings → API keys.
showfm_live_in production.
Path parameters
podcast_id(required):string, format:uuidThe podcast id (UUID).
Query parameters
status:string, possible values:"pending_confirmation", "draft", "scheduled", "published", "archived"limit:integer, default:20, minimum:1, maximum:100Page size, 1 to 100. Default 20.
cursor:stringThe
pagination.next_cursorvalue from the previous page.
Responses
Browse the documented response statuses, headers and body fields.
200 OK
Response headers
RateLimit-PolicyThe bucket that applied, e.g.
"account";q=60;w=60.stringRateLimitRequests left and seconds to reset, e.g.
"account";r=59;t=42.stringETagstring
Response body
Content type: application/json
no additional properties
data(required): array of KeyedEpisodeListItempagination(required): PaginationOpaque keyset cursor; pass it back as
cursor.
Example response
Illustrative data; your identifiers and figures will differ.
json
{
"data": [
{
"source": {
"guid_sha256": "a63d444752e29186486f5553550234207f95ad7fded202773838253ec42c4449",
"enclosure_sha256": "5095f4b767798692ff5c6251bb7e32be378c2a2ab98de0e0a8ebc25f5eeca537"
},
"rss_guid": "old-host-episode-42",
"id": "223e4567-e89b-12d3-a456-426614174001",
"podcast_id": "123e4567-e89b-12d3-a456-426614174000",
"slug": "first-episode",
"title": "First episode",
"status": "published",
"episode_number": 1,
"season_number": null,
"episode_type": "full",
"published_at": "2026-09-01T10:00:00Z",
"scheduled_for": null,
"duration_seconds": 1800,
"subtitle": null,
"created_at": "2026-08-31T10:00:00Z"
}
],
"pagination": {
"next_cursor": null
}
}304 Not modified (matching If-None-Match).
If-None-Match). This response has no body.
400, 401, 403, 404, 500, 503
400invalid_request: a bad parameter, or a key sent in the URL.401unauthorized(no Bearer key) orinvalid_api_key.403insufficient_scope,forbidden(role or team-key setting) orplan_upgrade_required.404not_found: the key cannot reach this resource.500internal_error. Retry; quoteX-Request-Idif it persists.503service_unavailable. Retry shortly.
Response body
Content type: application/json
schema: Error, no additional properties
error(required):object, no additional propertiescode(required):string, possible values:"invalid_request", "not_found", "unavailable", "unauthorized", "invalid_api_key", "insufficient_scope", "forbidden", "plan_upgrade_required", "rate_limited", "service_unavailable", "internal_error", "not_implemented"message(required):stringdetails:arrayItems:
no additional properties
field(required):stringmessage(required):stringreason:stringA stable reason a client may branch on, for example
outside_retention.
docs_url:stringrequest_id:string
429 rate_limited. Wait for Retry-After seconds.
rate_limited. Wait for Retry-After seconds. Response headers
Retry-AfterintegerRateLimit-PolicyThe bucket that applied, e.g.
"account";q=60;w=60.stringRateLimitRequests left and seconds to reset, e.g.
"account";r=59;t=42.string
Response body
Content type: application/json
Uses the shared Error schema. View response fields.