LogoDocumentação SoraVideo
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"
}
FieldTypeDescription
codenumberNumeric error code
msgstringHuman-readable error message

HTTP Status Codes

Status CodeDescription
200 OKRequest succeeded
400 Bad RequestInvalid request parameters
401 UnauthorizedAuthentication failed
403 ForbiddenAccess denied
404 Not FoundResource not found
429 Too Many RequestsRate limit exceeded
500 Internal Server ErrorServer error
503 Service UnavailableService temporarily unavailable

Error Code Reference

Authentication Errors (1xxx)

CodeMessageDescriptionResolution
1001Invalid API keyThe API key is not validVerify your API key is correct
1002API key revokedThe key has been revokedCreate a new API key
1003Missing authorizationNo Authorization headerInclude Bearer token in header
1004Invalid token formatAuthorization header malformedUse format: Bearer sk_xxx
Example: Invalid API Key
{
  "code": 1001,
  "msg": "Invalid API key"
}

Rate Limiting Errors (2xxx)

CodeMessageDescriptionResolution
2001Rate limit exceededToo many requestsWait and retry with backoff
2002Concurrent limit exceededToo many active tasksWait for tasks to complete
2003Daily limit exceededDaily quota reachedWait until midnight UTC
Example: Rate Limit Exceeded
{
  "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)

CodeMessageDescriptionResolution
3001Insufficient creditsNot enough creditsPurchase more credits
3002Credit deduction failedFailed to process creditsRetry the request
Example: Insufficient Credits
{
  "code": 3001,
  "msg": "Insufficient credits. Required: 100, Available: 50"
}

Validation Errors (4xxx)

CodeMessageDescriptionResolution
4001Invalid request bodyJSON parsing failedCheck JSON syntax
4002Missing required fieldRequired parameter missingInclude all required fields
4003Invalid field valueParameter value invalidCheck parameter constraints
4004Prompt too longPrompt exceeds limitShorten the prompt
4005Invalid image URLImage URL not accessibleUse valid HTTPS URL
4006Invalid video URLVideo URL not from SoraUse sora.chatgpt.com URL
4007Invalid file typeUnsupported file formatUse JPEG, PNG, WebP, or GIF
4008File too largeFile exceeds size limitReduce file size (max 10MB)
Example: Missing Required Field
{
  "code": 4002,
  "msg": "Missing required field: prompt"
}

Resource Errors (5xxx)

CodeMessageDescriptionResolution
5001Task not foundTask ID doesn't existVerify task ID
5002Task expiredTask data no longer availableResults expire after 24h
5003Resource unavailableRequested resource missingCheck resource exists
Example: Task Not Found
{
  "code": 5001,
  "msg": "Task not found"
}

Server Errors (9xxx)

CodeMessageDescriptionResolution
9001Internal server errorUnexpected server errorRetry later
9002Service unavailableService temporarily downRetry later
9003Upstream errorProvider errorRetry later
9004TimeoutRequest timed outRetry with longer timeout
Example: Server Error
{
  "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.';
}

Next Steps