Errors
The API uses standard HTTP status codes and returns detailed error information.
Error Response Format
All errors follow this format:
{
"error": {
"code": "ERROR_CODE",
"message": "Human readable error message",
"request_id": "uuid"
}
}Validation errors also include a details array:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [...],
"request_id": "uuid"
}
}Rate limit errors (429) use a simpler format:
{
"error": "Rate limit exceeded: 10 per 1 day"
}The Retry-After header may be present on 429 responses, indicating when you can retry.
HTTP Status Codes
| Code | Meaning |
|---|---|
| `200` | Success |
| `201` | Created |
| `204` | No Content |
| `400` | Bad Request |
| `401` | Unauthorized |
| `403` | Forbidden |
| `404` | Not Found |
| `409` | Conflict |
| `422` | Validation Error |
| `429` | Rate Limited |
| `500` | Internal Error |
Error Codes
Authentication Errors
| Code | HTTP | Description |
|---|---|---|
| `UNAUTHORIZED` | 401 | Missing or invalid authentication |
| `AUTH_ERROR` | 401 | Authentication failed |
| `INVALID_TOKEN` | 401 | Token is invalid or expired |
| `FORBIDDEN` | 403 | Insufficient permissions |
Resource Errors
| Code | HTTP | Description |
|---|---|---|
| `NOT_FOUND` | 404 | Resource not found |
| `CONFLICT` | 409 | Resource already exists |
| `INVALID_STATE` | 409 | Resource in invalid state for operation |
Billing Errors
| Code | HTTP | Description |
|---|---|---|
| `INSUFFICIENT_CREDITS` | 402 | Not enough credits |
| `INVALID_PLAN` | 400 | Plan does not exist |
| `PAYMENT_FAILED` | 400 | Payment verification failed |
Validation Errors
| Code | HTTP | Description |
|---|---|---|
| `VALIDATION_ERROR` | 422 | Request validation failed |
| `BAD_REQUEST` | 400 | Invalid request format |
Rate Limiting
| Code | HTTP | Description |
|---|---|---|
| `RATE_LIMITED` | 429 | Too many requests. Check the Retry-After header for when to retry. |
Concurrency Limits
| Code | HTTP | Description |
|---|---|---|
| `MAX_CONCURRENT_VIDEOS` | 429 | You have 3 videos processing. Wait for one to finish before creating more. |
Videos with status pending, scripting, refining, visualising, narrating, curating, or rendering count as "in progress".
Server Errors
| Code | HTTP | Description |
|---|---|---|
| `INTERNAL_ERROR` | 500 | Internal server error |
| `DATABASE_ERROR` | 500 | Database operation failed |
Examples
Unauthorized
{
"error": {
"code": "UNAUTHORIZED",
"message": "Missing authentication credentials",
"request_id": "abc-123"
}
}Not Found
{
"error": {
"code": "NOT_FOUND",
"message": "Video not found",
"request_id": "abc-123"
}
}Validation Error
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{"loc": ["body", "prompt"], "msg": "Field required"}
],
"request_id": "abc-123"
}
}Insufficient Credits
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits. Required: 5, Available: 2",
"request_id": "abc-123"
}
}Invalid State
{
"error": {
"code": "INVALID_STATE",
"message": "Cannot modify scenes for a completed video",
"request_id": "abc-123"
}
}This error occurs when you try to:
- Approve a video that's already completed or failed
- Modify scenes on a completed or failed video
- Delete a video that's currently being processed
Rate Limited
{
"error": "Rate limit exceeded: 10 per 1 day"
}Max Concurrent Videos
{
"error": {
"code": "MAX_CONCURRENT_VIDEOS",
"message": "You have 3 videos processing. Wait for one to finish.",
"request_id": "abc-123"
}
}Handling Errors
In JavaScript
async function createVideo(data) {
const response = await fetch('/videos', {
method: 'POST',
headers: {
'X-Api-Key': apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
if (!response.ok) {
const error = await response.json()
const message = error.error || error.detail || response.statusText
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After')
console.log(`Rate limited. Retry after ${retryAfter} seconds.`)
}
throw new Error(message)
}
return response.json()
}In Python
import requests
def create_video(data, api_key):
response = requests.post(
"https://api.sketchpen.app/api/v1/videos",
json=data,
headers={"X-Api-Key": api_key}
)
if not response.ok:
error = response.json()
message = error.get("error") or error.get("detail") or response.status_text
if response.status_code == 429:
retry_after = response.headers.get("Retry-After")
print(f"Rate limited. Retry after {retry_after} seconds.")
response.raise_for_status()
return response.json()โน๏ธ Request ID
Always include the request_id when contacting support. It helps us debug issues quickly.
Troubleshooting
Video Status: failed
When a video fails, the status field changes to failed. Common causes:
| Cause | Solution |
|-------|----------|
| AI service timeout | Retry via POST /videos/{id}/approve. Temporary failures usually succeed on retry. |
| Image generation error | Retry. If persistent, try a simpler visual_description. |
| Audio generation error | Retry. Very long narration text may cause issues. |
| Render timeout | Rare. Contact support with your request_id. |
Retrying Failed Videos
Use the approve endpoint to retry generation:
curl -X POST https://api.sketchpen.app/api/v1/videos/uuid/approve \ -H "X-Api-Key: sk_live_..."
If the video has no scenes yet (failed during scripting), regenerate the script first:
curl -X POST https://api.sketchpen.app/api/v1/videos/uuid/regenerate \
-H "X-Api-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{"feedback": ""}'Credit Refunds
Credits are automatically refunded if generation fails:
- Image generation fails: 1 credit refunded per failed scene
- Audio generation fails: Audio credits refunded
Successfully generated assets are not refunded โ only complete failures.
Common Error Messages
| Error | Meaning | Action | |-------|---------|--------| | "Insufficient credits" | Not enough credits for this operation | Upgrade plan or wait for next billing cycle | | "You have 3 videos processing" | Concurrent video limit reached | Wait for a video to complete | | "Video not found" | Invalid video ID or video was deleted | Check the video ID | | "Cannot modify scenes for a completed or failed video" | Video is in terminal state | Create a new video instead |