API Reference
Error Codes
API error handling reference
Overview
The Sora 2 Video API uses standard HTTP status codes along with custom error codes to indicate the status of requests. All error responses include a code field with a specific error code and a msg field with a human-readable description.
Error Response Format
{
"code": 1001,
"msg": "Invalid API key"
}| Field | Type | Description |
|---|---|---|
code | number | Numeric error code |
msg | string | Human-readable error message |
HTTP Status Codes
| Status Code | Description |
|---|---|
200 OK | Request succeeded |
400 Bad Request | Invalid request parameters |
401 Unauthorized | Authentication failed |
403 Forbidden | Access denied |
404 Not Found | Resource not found |
429 Too Many Requests | Rate limit exceeded |
500 Internal Server Error | Server error |
503 Service Unavailable | Service temporarily unavailable |
Error Code Reference
Authentication Errors (1xxx)
| Code | Message | Description | Resolution |
|---|---|---|---|
| 1001 | Invalid API key | The API key is not valid | Verify your API key is correct |
| 1002 | API key revoked | The key has been revoked | Create a new API key |
| 1003 | Missing authorization | No Authorization header | Include Bearer token in header |
| 1004 | Invalid token format | Authorization header malformed | Use format: Bearer sk_xxx |
{
"code": 1001,
"msg": "Invalid API key"
}Rate Limiting Errors (2xxx)
| Code | Message | Description | Resolution |
|---|---|---|---|
| 2001 | Rate limit exceeded | Too many requests | Wait and retry with backoff |
| 2002 | Concurrent limit exceeded | Too many active tasks | Wait for tasks to complete |
| 2003 | Daily limit exceeded | Daily quota reached | Wait until midnight UTC |
{
"code": 2001,
"msg": "Rate limit exceeded. Please slow down.",
"retryAfter": 15
}Rate limit errors (429) may also come from the upstream video generation service. These are separate from our API limits and indicate the underlying service is temporarily throttling requests. Wait 10-30 seconds before retrying.
Credit Errors (3xxx)
| Code | Message | Description | Resolution |
|---|---|---|---|
| 3001 | Insufficient credits | Not enough credits | Purchase more credits |
| 3002 | Credit deduction failed | Failed to process credits | Retry the request |
{
"code": 3001,
"msg": "Insufficient credits. Required: 100, Available: 50"
}Validation Errors (4xxx)
| Code | Message | Description | Resolution |
|---|---|---|---|
| 4001 | Invalid request body | JSON parsing failed | Check JSON syntax |
| 4002 | Missing required field | Required parameter missing | Include all required fields |
| 4003 | Invalid field value | Parameter value invalid | Check parameter constraints |
| 4004 | Prompt too long | Prompt exceeds limit | Shorten the prompt |
| 4005 | Invalid image URL | Image URL not accessible | Use valid HTTPS URL |
| 4006 | Invalid video URL | Video URL not from Sora | Use sora.chatgpt.com URL |
| 4007 | Invalid file type | Unsupported file format | Use JPEG, PNG, WebP, or GIF |
| 4008 | File too large | File exceeds size limit | Reduce file size (max 10MB) |
{
"code": 4002,
"msg": "Missing required field: prompt"
}Resource Errors (5xxx)
| Code | Message | Description | Resolution |
|---|---|---|---|
| 5001 | Task not found | Task ID doesn't exist | Verify task ID |
| 5002 | Task expired | Task data no longer available | Results expire after 24h |
| 5003 | Resource unavailable | Requested resource missing | Check resource exists |
{
"code": 5001,
"msg": "Task not found"
}Server Errors (9xxx)
| Code | Message | Description | Resolution |
|---|---|---|---|
| 9001 | Internal server error | Unexpected server error | Retry later |
| 9002 | Service unavailable | Service temporarily down | Retry later |
| 9003 | Upstream error | Provider error | Retry later |
| 9004 | Timeout | Request timed out | Retry with longer timeout |
{
"code": 9001,
"msg": "Internal server error. Please try again later."
}Handling Errors
JavaScript/TypeScript
interface ApiError {
code: number;
msg: string;
retryAfter?: number;
}
async function callApi(endpoint: string, body: object) {
const response = await fetch(`https://api.example.com${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
const data = await response.json();
if (data.code !== 0) {
// Handle error based on code
switch (data.code) {
case 1001:
throw new Error('Invalid API key - check your credentials');
case 2001:
// Rate limited - wait and retry
if (data.retryAfter) {
await sleep(data.retryAfter * 1000);
return callApi(endpoint, body);
}
throw new Error('Rate limited');
case 3001:
throw new Error('Insufficient credits - please recharge');
default:
throw new Error(data.msg);
}
}
return data.data;
}Python
import requests
import time
class ApiError(Exception):
def __init__(self, code, message, retry_after=None):
self.code = code
self.message = message
self.retry_after = retry_after
def call_api(endpoint, body, retries=3):
for attempt in range(retries):
response = requests.post(
f'https://api.example.com{endpoint}',
headers={
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
},
json=body
)
data = response.json()
if data['code'] == 0:
return data['data']
# Handle rate limiting
if data['code'] == 2001:
retry_after = data.get('retryAfter', 2 ** attempt)
time.sleep(retry_after)
continue
# Handle other errors
raise ApiError(data['code'], data['msg'])
raise ApiError(2001, 'Max retries exceeded')Best Practices
Log Error Details
Always log the full error response for debugging:
try {
const result = await callApi('/api/v1/sora2/text-to-video', { prompt });
} catch (error) {
console.error('API Error:', {
code: error.code,
message: error.msg,
endpoint: '/api/v1/sora2/text-to-video',
timestamp: new Date().toISOString()
});
}Implement Retry Logic
Use exponential backoff for transient errors:
async function withRetry(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.code >= 9000 || error.code === 2001) {
// Server or rate limit error - retry
await sleep(Math.pow(2, i) * 1000);
continue;
}
throw error; // Don't retry client errors
}
}
throw new Error('Max retries exceeded');
}Show User-Friendly Messages
Map error codes to user-friendly messages:
const errorMessages = {
1001: 'Please check your API key and try again.',
2001: 'Service is busy. Please wait a moment.',
3001: 'You\'re out of credits. Please top up to continue.',
4002: 'Some information is missing. Please fill all required fields.',
9001: 'Something went wrong. Please try again later.'
};
function getUserMessage(code) {
return errorMessages[code] || 'An unexpected error occurred.';
}