Python SDK
The official Python SDK for WackyPod. Transform any content into professional-quality podcasts with a few lines of code.
pip install wackypod
Requirements: Python 3.8+ and requests >= 2.28.0
Quick start
from wackypod import WackyPod
# Initialize with your API key
client = WackyPod(api_key="wp_your_api_key")
# Create a podcast from a URL
episode = client.episodes.create(
input_type="url",
input_source="https://example.com/article",
preset="standard"
)
print(f"Episode created: {episode.id}")
# Wait for completion (polls automatically)
episode = client.episodes.wait_for_completion(episode.id)
print(f"Title: {episode.title}")
print(f"Audio: {episode.audio_url}")
print(f"Duration: {episode.audio_duration_seconds}s")
Client initialization
client = WackyPod(
api_key="wp_your_api_key", # Required
base_url="https://api.wackypod.com", # Optional, default shown
timeout=30 # Optional, request timeout in seconds
)
Get your API key from wackypod.com/settings/api. Requires Creator tier or higher.
Episodes
Create an episode
# From a URL
episode = client.episodes.create(
input_type="url",
input_source="https://example.com/article",
preset="standard", # quick, standard, deep, extended
host_mode="multi", # single, multi
voice_style="casual" # professional, casual, educational, enthusiastic
)
# From text
episode = client.episodes.create(
input_type="text",
input_source="Your article content goes here...",
preset="quick"
)
Get an episode
episode = client.episodes.get("ep_abc123")
print(f"Status: {episode.status}")
print(f"Title: {episode.title}")
List episodes
episodes = client.episodes.list(
status="ready", # Optional filter
limit=10, # Default: 50
offset=0 # Default: 0
)
for ep in episodes:
print(f"{ep.title} - {ep.audio_duration_seconds}s")
Wait for completion
# Polls until episode is ready (or timeout)
episode = client.episodes.wait_for_completion(
"ep_abc123",
timeout=300, # Max wait time in seconds (default: 300)
poll_interval=5 # Seconds between polls (default: 5)
)
Delete an episode
client.episodes.delete("ep_abc123")
Webhooks
Create a webhook
webhook = client.webhooks.create(
url="https://your-server.com/webhooks/wackypod",
events=["episode.completed", "episode.failed"],
description="Production webhook"
)
print(f"Webhook ID: {webhook.id}")
print(f"Secret: {webhook.secret}") # Save this!
List webhooks
webhooks = client.webhooks.list()
for wh in webhooks:
print(f"{wh.id}: {wh.url} ({', '.join(wh.events)})")
Update a webhook
client.webhooks.update(
"wh_abc123",
events=["episode.completed"],
is_active=True
)
Test a webhook
result = client.webhooks.test("wh_abc123")
print(f"Status code: {result.status_code}")
View delivery history
deliveries = client.webhooks.get_deliveries("wh_abc123")
for d in deliveries:
status = "OK" if d.success else "FAILED"
print(f"{d.event}: {status} ({d.duration}ms)")
Delete a webhook
client.webhooks.delete("wh_abc123")
Users
Get profile
profile = client.users.get_profile()
print(f"Name: {profile.name}")
print(f"Tier: {profile.tier}")
print(f"Email: {profile.email}")
Get quota
quota = client.users.get_quota()
print(f"Used: {quota.episodes_used}/{quota.episodes_limit}")
print(f"Remaining: {quota.episodes_remaining}")
print(f"Usage: {quota.quota_percentage}%")
Error handling
The SDK raises typed exceptions for different error categories:
from wackypod import (
WackyPodError, # Base exception
AuthenticationError, # Invalid API key (401)
ValidationError, # Bad request data (400)
NotFoundError, # Resource not found (404)
RateLimitError, # Rate limit exceeded (429)
ServerError, # Server error (5xx)
)
try:
episode = client.episodes.create(
input_type="url",
input_source="https://example.com/article"
)
except AuthenticationError:
print("Invalid API key. Check your credentials.")
except RateLimitError as e:
print(f"Rate limited. Try again later.")
except ValidationError as e:
print(f"Invalid request: {e.message}")
except ServerError:
print("Server error. Try again later.")
except WackyPodError as e:
print(f"Unexpected error: {e}")
Response models
The SDK returns typed dataclass objects for IDE autocompletion:
Episode
episode.id # str
episode.title # str
episode.description # str
episode.status # str: queued, ingesting, generating_script, etc.
episode.preset # str: quick, standard, deep, extended
episode.host_mode # str: single, multi
episode.audio_url # str (when ready)
episode.audio_duration_seconds # int (when ready)
episode.created_at # str (ISO 8601)
Webhook
webhook.id # str
webhook.url # str
webhook.events # list[str]
webhook.secret # str (only on creation)
webhook.is_active # bool
webhook.created_at # str
User
user.id # str
user.email # str
user.name # str
user.tier # str: free, creator, professional, enterprise
user.email_verified # bool
Complete example
from wackypod import WackyPod, RateLimitError
import time
client = WackyPod(api_key="wp_your_key")
# Check quota first
quota = client.users.get_quota()
if quota.episodes_remaining <= 0:
print("No episodes remaining this month")
exit()
# Create episode
try:
episode = client.episodes.create(
input_type="url",
input_source="https://example.com/interesting-article",
preset="standard",
host_mode="multi",
voice_style="casual"
)
print(f"Created: {episode.id}")
# Wait for it to finish
episode = client.episodes.wait_for_completion(episode.id, timeout=600)
print(f"Title: {episode.title}")
print(f"Audio: {episode.audio_url}")
print(f"Duration: {episode.audio_duration_seconds}s")
except RateLimitError:
print("Rate limited -- waiting and retrying...")
time.sleep(60)
# List all ready episodes
episodes = client.episodes.list(status="ready")
print(f"\nYou have {len(episodes)} ready episodes:")
for ep in episodes:
print(f" - {ep.title} ({ep.audio_duration_seconds}s)")
PyPI
- Package: wackypod on PyPI
- Source: GitHub
- License: MIT