Skip to main content

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

CodeMeaningWhen you'll see it
200OKSuccessful read or update
201CreatedSuccessful resource creation (episode, show)
204No ContentSuccessful deletion (no response body)

Client error codes

CodeMeaningWhat to do
400Bad RequestCheck your request body — a required field is missing or a value is invalid
401UnauthorizedInclude the X-API-Key header
403ForbiddenCheck your API key is valid and has the right permissions
404Not FoundThe resource doesn't exist or doesn't belong to your stream
409ConflictA resource with that identifier already exists, or a dependency prevents the action
413Payload Too LargeRequest body exceeds 1 MB (JSON) or 200 MB (file upload)
429Too Many RequestsYou've exceeded the rate limit — wait and retry

Server error codes

CodeMeaningWhat to do
500Internal Server ErrorSomething went wrong on our end — retry after a moment
503Service UnavailableA 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:

FieldRule
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_urlMust be a valid HTTP or HTTPS URL, max 2,000 characters
image_urlMust be a valid HTTP or HTTPS URL if provided, max 2,000 characters
show_idMust exist and belong to your stream
datetimeUnix timestamp, between 2000-01-01 and 1 year from now
presenterOptional, max 200 characters
File uploadMust be .mp3, max 200 MB, non-empty
Schedule dayMust be mon, tue, wed, thu, fri, sat, or sun
Schedule time0–1440 (minutes from midnight)
Schedule week1 to your stream's number_of_weeks