Error Handling
How to interpret error responses from the AutoPod API and handle them in your application.
Error response format
All errors return a JSON object with a message field:
{
"message": "Description of what went wrong"
}
The HTTP status code tells you the category of error. The message gives you the specific reason.
HTTP status codes
Success codes
| Code | Meaning | When you'll see it |
|---|---|---|
| 200 | OK | Successful read or update |
| 201 | Created | Successful resource creation (episode, show) |
| 204 | No Content | Successful deletion (no response body) |
Client error codes
| Code | Meaning | What to do |
|---|---|---|
| 400 | Bad Request | Check your request body — a required field is missing or a value is invalid |
| 401 | Unauthorized | Include the X-API-Key header |
| 403 | Forbidden | Check your API key is valid and has the right permissions |
| 404 | Not Found | The resource doesn't exist or doesn't belong to your stream |
| 409 | Conflict | A resource with that identifier already exists, or a dependency prevents the action |
| 413 | Payload Too Large | Request body exceeds 1 MB (JSON) or 200 MB (file upload) |
| 429 | Too Many Requests | You've exceeded the rate limit — wait and retry |
Server error codes
| Code | Meaning | What to do |
|---|---|---|
| 500 | Internal Server Error | Something went wrong on our end — retry after a moment |
| 503 | Service Unavailable | A backing service (database, cache) is temporarily down — retry shortly |
Common error messages
Authentication errors
// Missing API key
{"message": "Missing X-API-Key header"}
// Invalid or disabled key
{"message": "Invalid or disabled API key"}
// Read-only key trying to write
{"message": "Write access is not enabled for this API key. Enable 'Read & Write' mode in Stream Settings."}
Validation errors
// Missing required field
{"message": "title is required"}
// Field too long
{"message": "title must be 499 characters or fewer"}
// Invalid URL
{"message": "audio_url must be a valid HTTP/HTTPS URL"}
// Invalid file type
{"message": "File must be an MP3 file"}
// Value out of range
{"message": "datetime cannot be more than 1 year in the future"}
Resource errors
// Resource not found
{"message": "Episode not found"}
{"message": "Show not found"}
// Dependency conflict
{"message": "Cannot delete show with existing episodes. Archive the episodes first."}
// Duplicate
{"message": "RSS filename already exists"}
Rate limit errors
{"message": "Rate limit exceeded (60 requests per minute)"}
Size limit errors
{"message": "Request body too large (max 1 MB for JSON requests)"}
Handling errors in your code
Basic pattern
Check the HTTP status code first, then read the message for details:
const response = await fetch('https://api.autopod.xyz/v1/episodes', {
headers: { 'X-API-Key': apiKey }
});
if (!response.ok) {
const error = await response.json();
switch (response.status) {
case 401:
case 403:
console.error('Authentication problem:', error.message);
break;
case 404:
console.error('Not found:', error.message);
break;
case 429:
console.error('Rate limited — slow down and retry');
break;
default:
console.error('API error:', error.message);
}
return;
}
const data = await response.json();
Retry strategy
For transient errors (429, 500, 503), a simple retry with backoff works well:
async function apiRequest(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.ok) return response.json();
// Don't retry client errors (except rate limits)
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
const error = await response.json();
throw new Error(error.message);
}
// Wait before retrying (1s, 2s, 4s)
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
}
throw new Error('Request failed after retries');
}
tip
For 429 Too Many Requests, wait at least a few seconds before retrying. The rate limit window is 60 seconds, so spacing out your requests is more effective than rapid retries.
Validation rules
Here's a summary of the validation rules that can trigger 400 Bad Request errors:
| Field | Rule |
|---|---|
title (episode) | Required, 1–499 characters |
title (show) | Required, 1–200 characters |
description (episode) | Optional, max 10,000 characters |
description (show) | Optional, max 5,000 characters |
audio_url | Must be a valid HTTP or HTTPS URL, max 2,000 characters |
image_url | Must be a valid HTTP or HTTPS URL if provided, max 2,000 characters |
show_id | Must exist and belong to your stream |
datetime | Unix timestamp, between 2000-01-01 and 1 year from now |
presenter | Optional, max 200 characters |
| File upload | Must be .mp3, max 200 MB, non-empty |
Schedule day | Must be mon, tue, wed, thu, fri, sat, or sun |
Schedule time | 0–1440 (minutes from midnight) |
Schedule week | 1 to your stream's number_of_weeks |