Episodes
List, create, update, and archive episodes for your station.
List episodes
GET /v1/episodes
Returns a paginated list of active episodes from your station, newest first.
Query parameters
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
limit | integer | 20 | 100 | Number of episodes per page |
offset | integer | 0 | — | Pagination offset (use cursor instead for large datasets) |
cursor | string | — | — | Cursor from a previous response for efficient pagination |
show_id | integer | — | — | Filter to a specific show |
Response
{
"episodes": [
{
"id": 1234,
"title": "Morning Show - Interview with Jane",
"description": "This week we chat with Jane about community radio",
"image": "https://cdn.example.com/episodes/1234.png",
"datetime": 1707472800,
"audio_url": "https://cdn.example.com/audio/episode-1234.mp3",
"audio_length": 48000000,
"show": "Morning Show",
"show_id": 15
}
],
"total": 142,
"limit": 20,
"offset": 0,
"next_cursor": "MTcwNzQ3MjgwMF8xMjM0"
}
Episode fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique episode ID |
title | string | Episode title |
description | string | Episode description |
image | string | Artwork URL (empty string if none) |
datetime | integer | Unix timestamp (seconds) |
audio_url | string | MP3 file URL |
audio_length | integer | File size in bytes |
show | string | Show name |
show_id | integer | Show ID |
Pagination fields
| Field | Type | Description |
|---|---|---|
total | integer | Total matching episodes |
limit | integer | Requested page size |
offset | integer | Current offset |
next_cursor | string | Cursor for next page (null if no more results) |
Pagination
The API supports two pagination styles:
Offset-based (simpler but slower for large datasets):
# Page 1
curl -H "X-API-Key: key" "https://api.autopod.xyz/v1/episodes?limit=20&offset=0"
# Page 2
curl -H "X-API-Key: key" "https://api.autopod.xyz/v1/episodes?limit=20&offset=20"
Cursor-based (recommended for large datasets):
# Page 1
curl -H "X-API-Key: key" "https://api.autopod.xyz/v1/episodes?limit=20"
# Page 2 (use next_cursor from previous response)
curl -H "X-API-Key: key" "https://api.autopod.xyz/v1/episodes?limit=20&cursor=MTcwNzQ3MjgwMF8xMjM0"
Cursor pagination is more efficient because it doesn't need to count skipped rows. Use it when fetching large numbers of episodes.
Filtering
Only active, non-archived episodes from published shows are returned. Future-dated episodes (not yet published) are excluded.
Example
# Get the 5 most recent episodes from show 15
curl -H "X-API-Key: your-key" \
"https://api.autopod.xyz/v1/episodes?limit=5&show_id=15"
Get a single episode
GET /v1/episodes/{id}
Returns a single episode by ID.
Response
Returns the same episode object format as the list endpoint.
Errors
404 Not Found— Episode doesn't exist or doesn't belong to your stream
Example
curl -H "X-API-Key: your-key" \
https://api.autopod.xyz/v1/episodes/1234
Create an episode from URL
POST /v1/episodes
Creates a new episode using an audio file hosted elsewhere. Requires the episodes:write scope.
Request body
{
"title": "Morning Show - Interview with Jane",
"show_id": 15,
"audio_url": "https://example.com/audio/interview.mp3",
"description": "This week we chat with Jane about community radio",
"image_url": "https://example.com/artwork/interview.png",
"datetime": 1707472800
}
| Field | Type | Required | Max length | Description |
|---|---|---|---|---|
title | string | Yes | 499 | Episode title |
show_id | integer | Yes | — | Show this episode belongs to |
audio_url | string | Yes | 2000 | Public HTTP/HTTPS URL of the audio file |
description | string | No | 10000 | Episode description |
image_url | string | No | 2000 | Episode artwork URL |
datetime | integer | No | — | Unix timestamp (defaults to current time) |
Response
HTTP 201 Created
Returns the created episode object.
Errors
400 Bad Request— Validation error (missing title, invalid URL, etc.)403 Forbidden— Missing required scope404 Not Found— Show doesn't exist or doesn't belong to your stream
Idempotency
Include X-Idempotency-Key header to prevent duplicate episodes on retry:
curl -X POST \
-H "X-API-Key: your-key" \
-H "X-Idempotency-Key: import-episode-42" \
-H "Content-Type: application/json" \
-d '{"title": "My Episode", "show_id": 15, "audio_url": "https://example.com/audio.mp3"}' \
https://api.autopod.xyz/v1/episodes
Upload an episode
POST /v1/episodes/upload
Uploads an MP3 file directly as a new episode. Requires the episodes:write scope.
Request
Send as multipart/form-data:
| Field | Type | Required | Description |
|---|---|---|---|
file | binary | Yes | MP3 file (max 200 MB) |
title | string | Yes | Episode title (max 499 characters) |
show_id | integer | Yes | Show ID |
description | string | No | Episode description (max 10,000 characters) |
datetime | integer | No | Unix timestamp (defaults to current time) |
Response
HTTP 201 Created
Returns the created episode object. The audio_url field contains the URL where the file was stored.
Errors
400 Bad Request— File is not an MP3, file is empty, file exceeds 200 MB, or validation error403 Forbidden— Missing required scope
Example
curl -X POST \
-H "X-API-Key: your-key" \
-F "file=@/path/to/episode.mp3" \
-F "title=My Episode" \
-F "show_id=15" \
-F "description=A great episode" \
https://api.autopod.xyz/v1/episodes/upload
Update an episode
PUT /v1/episodes/{id}
Updates an existing episode. Only include the fields you want to change. Requires the episodes:write scope.
Request body
All fields are optional — only include what you want to update:
{
"title": "Updated Episode Title",
"description": "Updated description",
"image_url": "https://example.com/new-artwork.png",
"datetime": 1707472900
}
| Field | Type | Max length | Description |
|---|---|---|---|
title | string | 499 | Episode title |
description | string | 10000 | Episode description |
image_url | string | 2000 | Episode artwork URL |
datetime | integer | — | Unix timestamp |
Response
Returns the updated episode object.
Errors
400 Bad Request— Validation error403 Forbidden— Missing required scope404 Not Found— Episode doesn't exist or doesn't belong to your stream
Sending an empty update (no fields) returns the episode unchanged.
Example
curl -X PUT \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"title": "Better Title", "description": "Updated description"}' \
https://api.autopod.xyz/v1/episodes/1234
Archive an episode
DELETE /v1/episodes/{id}
Archives an episode (soft delete). The episode no longer appears in listings, the player, or widgets, but it isn't permanently deleted — it can be restored from the dashboard. Requires the episodes:write scope.
Response
HTTP 204 No Content
No response body.
Errors
403 Forbidden— Missing required scope404 Not Found— Episode doesn't exist or doesn't belong to your stream
Example
curl -X DELETE \
-H "X-API-Key: your-key" \
https://api.autopod.xyz/v1/episodes/1234
Archiving is reversible. Archived episodes can be restored from the episode list in the dashboard (look in the Archived tab).