에러
Video API 엔드포인트의 모든 에러는 동일한 JSON shape를 사용합니다:
{
"error": {
"code": "...",
"message": "..."
}
}HTTP status는 문제의 종류를 나타내며, error.code는 코드에서 분기할 수 있는 안정적인 문자열입니다. 항상 error.message를 파싱하지 말고 error.code를 기준으로 매칭하세요.
에러 코드
| HTTP | Code | 의미 |
|---|---|---|
| 400 | invalid_request | 필수 파라미터가 누락되었거나 값이 유효하지 않음 |
| 400 | invalid_callback_url | callback_url이 HTTPS가 아니거나 private network를 가리킴(SSRF checks로 차단) |
| 400 | references_conflict | frame_images와 input_references가 같은 요청에 전송됨(상호 배타적) |
| 400 | too_many_references | input_references가 제한을 초과함(images > 9 / audio > 3 / video > 1) |
| 400 | cancel_not_supported | 업스트림 공급자가 이 job을 중단할 수 없음 |
| 400 | cancel_failed | job이 이미 terminal state라 취소할 수 없음 |
| 401 | unauthorized / invalid_api_key | 인증 실패 |
| 401 | upstream_auth_failed | 업스트림 공급자 인증 실패 |
| 402 | insufficient_credits | job을 수락하기에 잔액이 부족함 |
| 404 | not_found | job이 존재하지 않거나 접근 권한이 없음 |
| 404 | model_not_found | 요청한 모델이 존재하지 않음 |
| 429 | rate_limited | 요청이 너무 많음(polling rate limit 또는 upstream rate limit) |
| 502 | upstream_error / route_error | 업스트림 공급자 오류 / routing 실패 |
| 500 | internal_error | 예상치 못한 내부 오류 |
references_conflict와 too_many_references는 request body validation errors입니다. 정확한 제한은 비디오 생성을 참조하세요. cancel_not_supported와 cancel_failed는 비디오 취소에 설명되어 있습니다. not_found는 알 수 없는 job과 다른 API key가 소유한 job 모두에 반환되며, 두 경우는 의도적으로 구분할 수 없습니다.
402 Insufficient credits
insufficient_credits는 job 생성 시(POST /v1/videos)에만 반환됩니다. 사전 승인이 활성화된 경우, ofox는 job을 수락하기 전에 요청한 resolution과 duration을 기준으로 비용을 추정합니다. 이 예상 비용이 잔액을 초과하면 요청은 즉시 거부됩니다. job 레코드는 생성되지 않으며 아무것도 청구되지 않습니다.
{ "error": { "code": "insufficient_credits", "message": "..." } }insufficient_credits는 Video API가 반환하는 유일한 402 code입니다. 이 단일 code를 처리하고, 잔액을 충전한 뒤 재시도하세요.
429 Rate limiting
rate_limited는 GET /v1/videos/{id}의 per-key polling limit과 upstream rate limits를 모두 포괄합니다. Polling limit에 도달하면 응답에 Retry-After header가 포함됩니다:
HTTP/1.1 429 Too Many Requests
Retry-After: 1
Content-Type: application/json
{ "error": { "code": "rate_limited", "message": "..." } }Retry-After header를 지키고 재시도 전에 back off하세요. 자주 폴링하고 있다면 webhook 알림으로 전환해 ofox가 terminal state를 push하도록 하세요. 이렇게 하면 polling limit을 완전히 피할 수 있습니다. Job 생성(POST)과 취소(DELETE)는 polling limit의 영향을 받지 않습니다.