Skip to main content

Episodes API

Create, retrieve, and manage podcast episodes.

POST /api/episodes

Create a new episode from text or URL.

Headers: Authorization: Bearer TOKEN

Request:

{
"content": "string (text content)",
"url": "string (URL to fetch content from)",
"preset": "quick | standard | deep | extended",
"hostMode": "single | multi",
"voiceStyle": "professional | casual | educational | enthusiastic",
"voicePair": "expert-curious | debate | interview",
"ttsEngine": "kokoro | chatterbox | auto",
"reviewScript": false
}

Either content or url is required (not both).

Parameters:

FieldTypeRequiredDefaultDescription
contentstringconditional--Plain text content to convert
urlstringconditional--URL to fetch content from
presetstringnostandardDuration preset
hostModestringnosingleSingle or multi-speaker
voiceStylestringnoprofessionalVoice personality
voicePairstringnoexpert-curiousMulti-speaker dynamic
ttsEnginestringnoautoTTS engine selection
reviewScriptbooleannofalsePause for script review

Preset availability by tier:

PresetDurationFreeCreatorProfessionalEnterprise
quick~3 minYesYesYesYes
standard~7 minNoYesYesYes
deep~15 minNoYesYesYes
extended~30 minNoNoYesYes

Response: 202 Accepted

{
"success": true,
"episode": {
"id": "ep_abc123",
"status": "queued",
"preset": "standard",
"hostMode": "multi",
"createdAt": "2026-03-29T10:00:00Z"
},
"quota": {
"used": 5,
"limit": 25,
"remaining": 20
}
}

Example:

curl -X POST https://api.wackypod.com/api/episodes \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/article",
"preset": "standard",
"hostMode": "multi",
"voiceStyle": "casual"
}'
from wackypod import WackyPod

client = WackyPod(api_key="wp_your_key")
episode = client.episodes.create(
input_type="url",
input_source="https://example.com/article",
preset="standard"
)

POST /api/episodes/upload

Create an episode from a file upload (PDF, DOCX, TXT, MD).

Headers: Authorization: Bearer TOKEN, Content-Type: multipart/form-data

Form Data:

FieldTypeRequiredDescription
filefileyesPDF, DOCX, DOC, TXT, or MD file
presetstringnoDuration preset (default: standard)
hostModestringnosingle or multi (default: single)
voiceStylestringnoVoice style
voicePairstringnoMulti-speaker dynamic

File size limits:

TierMax Size
Free5 MB
Creator20 MB
Professional50 MB
Enterprise100 MB

Response: 202 Accepted (same format as POST /api/episodes)

Example:

curl -X POST https://api.wackypod.com/api/episodes/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@document.pdf" \
-F "preset=standard" \
-F "hostMode=multi"

GET /api/episodes

List all episodes for the authenticated user.

Headers: Authorization: Bearer TOKEN

Query Parameters:

ParameterTypeDefaultDescription
statusstring--Filter by status
limitnumber50Results per page (max 100)
offsetnumber0Pagination offset

Status values: queued, ingesting, generating_script, review_script, generating_audio, ready, error

Response: 200 OK

{
"success": true,
"episodes": [
{
"id": "ep_abc123",
"title": "The Future of AI",
"status": "ready",
"preset": "standard",
"hostMode": "multi",
"sourceType": "url",
"audioUrl": "/episodes/ep_abc123.mp3",
"audioDuration": 420,
"createdAt": "2026-03-29T10:00:00Z"
}
],
"pagination": {
"total": 42,
"limit": 50,
"offset": 0
}
}

Example:

curl "https://api.wackypod.com/api/episodes?status=ready&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN"
episodes = client.episodes.list(status="ready", limit=10)
for ep in episodes:
print(f"{ep.title} ({ep.audio_duration_seconds}s)")

GET /api/episodes/:id

Get a specific episode by ID.

Headers: Authorization: Bearer TOKEN (optional for public episodes)

Response: 200 OK

{
"success": true,
"episode": {
"id": "ep_abc123",
"title": "The Future of AI",
"description": "An exploration of artificial intelligence and its impact on society.",
"status": "ready",
"progressPercent": 100,
"preset": "standard",
"hostMode": "multi",
"scriptText": "[Host 1]: Welcome to today's episode...",
"audioUrl": "/episodes/ep_abc123.mp3",
"audioDuration": 420,
"createdAt": "2026-03-29T10:00:00Z"
}
}

Example:

curl https://api.wackypod.com/api/episodes/ep_abc123 \
-H "Authorization: Bearer YOUR_TOKEN"
episode = client.episodes.get("ep_abc123")
print(f"Status: {episode.status}")
print(f"Audio: {episode.audio_url}")

GET /api/episodes/:id/stream

Subscribe to real-time progress updates via Server-Sent Events (SSE).

Headers: Authorization: Bearer TOKEN

Response: 200 OK (text/event-stream)

Events are sent as the episode progresses through each stage:

data: {"status":"ingesting","progressPercent":10}

data: {"status":"generating_script","progressPercent":30}

data: {"status":"generating_audio","progressPercent":70}

data: {"status":"ready","progressPercent":100,"audioUrl":"/episodes/ep_abc123.mp3"}

Example (JavaScript):

const eventSource = new EventSource(
'https://api.wackypod.com/api/episodes/ep_abc123/stream'
);

eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(`${data.status}: ${data.progressPercent}%`);

if (data.status === 'ready' || data.status === 'error') {
eventSource.close();
}
};

DELETE /api/episodes/:id

Delete an episode. Must be the episode owner.

Headers: Authorization: Bearer TOKEN

Response: 200 OK

{
"success": true,
"message": "Episode deleted successfully"
}

Errors:

StatusErrorDescription
403ForbiddenNot the episode owner
404Not foundEpisode does not exist

Example:

curl -X DELETE https://api.wackypod.com/api/episodes/ep_abc123 \
-H "Authorization: Bearer YOUR_TOKEN"
client.episodes.delete("ep_abc123")

GET /api/episodes/:id/transcript

Get the full transcript with timed segments.

Headers: Authorization: Bearer TOKEN (optional for public episodes)

Response: 200 OK

{
"episodeId": "ep_abc123",
"segments": [
{
"id": "seg_001",
"speaker": "Host 1",
"text": "Welcome to today's episode...",
"startTimeMs": 0,
"endTimeMs": 3500,
"confidence": 0.95
}
],
"stats": {
"totalSegments": 45,
"totalWords": 1250,
"totalDurationMs": 420000,
"speakers": ["Host 1", "Host 2"]
}
}

GET /api/episodes/:id/show-notes

Get AI-generated show notes including summary, key points, chapters, and topics.

Headers: Authorization: Bearer TOKEN (optional)

Response: 200 OK

{
"episodeId": "ep_abc123",
"summary": "A deep dive into how AI is transforming content creation...",
"keyPoints": [
"AI-powered tools can generate studio-quality podcasts",
"Text-to-speech technology has reached human parity",
"Content accessibility is improving through audio formats"
],
"chapters": [
{ "title": "Introduction", "timestamp": "00:00", "timestampMs": 0 },
{ "title": "Main Discussion", "timestamp": "02:30", "timestampMs": 150000 },
{ "title": "Conclusion", "timestamp": "06:00", "timestampMs": 360000 }
],
"topics": ["AI", "Technology", "Podcasting"]
}

GET /api/episodes/:id/transcript/search

Search within an episode transcript.

Headers: Authorization: Bearer TOKEN (optional)

Query Parameters:

  • q (required): Search query (1-200 characters)

Response: 200 OK

{
"episodeId": "ep_abc123",
"query": "artificial intelligence",
"matches": [
{
"segmentId": "seg_005",
"speaker": "Host 1",
"text": "...discussing artificial intelligence and its implications...",
"timestampMs": 45000,
"timestamp": "00:45",
"matchPositions": [[12, 35]]
}
],
"totalMatches": 3
}