에러 코드
HTTP 상태 코드, detail.error 기계 판독 코드, 응답 형식으로 에러를 반환합니다.
상태 코드#
| 코드 | 이름 | 설명 |
|---|---|---|
| 400 | Bad Request | 잘못된 요청. 지원하지 않는 모델 ID(유사 모델 추천 포함), 모델별 파라미터 제약 위반(duration·해상도·참조 이미지 수 등), 키의 허용 모델 밖 접근 등. |
| 401 | Unauthorized | API 키 누락·무효·만료 또는 삭제된 계정. |
| 402 | Payment Required | 크레딧 부족 또는 예산·토큰 한도 초과. 코드별 해결책이 다릅니다(아래 기계 판독 코드 표). |
| 403 | Forbidden | 접근 거부. 키 IP 허용 목록 위반, 읽기 전용 스코프, 국외이전 학습 동의 미보유 등. |
| 404 | Not Found | 존재하지 않는 리소스. 지원하지 않는 모델 ID(단일 조회), 없는 호출 기록·작업(job) ID 등. |
| 409 | Conflict | 같은 Idempotency-Key 요청이 이미 처리 중일 때. |
| 413 | Payload Too Large | 요청 본문이 상한(기본 50MB)을 초과했을 때. |
| 415 | Unsupported Media Type | 지원하지 않는 이미지·마스크 MIME 형식. |
| 422 | Unprocessable Entity | 요청 스키마 검증 실패(필드 타입·범위 위반 등). detail에 위치·사유 배열이 담깁니다. |
| 429 | Too Many Requests | Rate limit 초과(키별 기본 60 RPM) 또는 업스트림 전체가 한도에 도달. Retry-After 헤더를 존중하세요. |
| 502 | Bad Gateway | 업스트림 프로바이더 오류. 텍스트 요청은 서버가 자동 재시도·폴백 후에도 실패한 경우입니다. retryable 필드로 재시도 의미를 구분하세요. |
| 503 | Service Unavailable | 일시적으로 처리 불가(카탈로그 스냅샷 확인 불가·리미터 장애). 잠시 후 재시도하세요. |
응답 형식#
에러 본문은 세 가지 형태로 반환됩니다. 대부분은 detail 안에 문자열 또는 객체가 담기고, 요청 본문 크기·형식 계열은 OpenAI 호환 { error: { message, type } } 형태입니다. 스키마 검증 실패(422)는 detail에 배열이 담깁니다.
402 — 구조화 에러(과금·동의 계열)
{
"detail": {
"error": "insufficient_credits",
"message": "사용 가능 크레딧 부족: 12,000 크레딧 < 54,000 크레딧. 대시보드 → 결제에서 충전해주세요.",
"action": { "type": "topup", "path": "/billing" }
}
}502 — 업스트림 거부(retryable + upstream 요약)
{
"detail": {
"error": "upstream_request_rejected",
"message": "모델 제공자가 요청을 거부했습니다. 잠시 후 다시 시도하거나 다른 모델을 사용해주세요. (upstream 400: ...)",
"retryable": false,
"upstream": { "status": 400, "detail": "..." }
}
}413 — OpenAI 호환 형태(본문 크기)
{
"error": {
"message": "요청 본문이 너무 큽니다(최대 50MB).",
"type": "payload_too_large"
}
}422 — 스키마 검증 배열
{
"detail": [
{
"loc": ["body", "duration_seconds"],
"msg": "Input should be between 2 and 20",
"type": "greater_than_equal"
}
]
}구조화 에러에는 action 필드에 대시보드 경로가 실릴 수 있고, retryable·providers·upstream 필드가 상황별로 추가됩니다. message는 한국어 고정이므로 파싱 대상이 아니라 사람용 안내로 쓰세요.
기계 판독 코드#
| 코드 | 위치 · HTTP | 의미와 해결 |
|---|---|---|
| insufficient_credits | detail.error · 402 | 크레딧 부족. 대시보드 → 결제에서 충전 후 재시도. |
| monthly_budget_exceeded | detail.error · 402 | API 키 월 예산 초과. 충전이 아니라 키 설정에서 예산 조정. |
| monthly_token_quota_exceeded | detail.error · 402 | API 키 월 토큰 한도 초과. 키 설정에서 한도 조정. |
| org_member_monthly_budget_exceeded | detail.error · 402 | 팀 멤버 월 예산 초과. 팀 관리자에게 조정 요청. |
| xborder_training_consent_required | detail.error · 403 | 학습 사용 provider 별도 동의 미보유. providers 목록과 함께 오며 설정에서 동의하면 해결. |
| org_membership_required | detail.error · 403 | 유효한 팀 멤버십 필요. |
| upstream_rate_limited | detail.error · 429 | 업스트림 전체가 한도 도달. Retry-After 이후 재시도. |
| upstream_unavailable | detail.error · 502 | 업스트림 일시 장애(retryable=true). 잠시 후 재시도. |
| upstream_request_rejected | detail.error · 502 | 업스트림이 요청 거부(retryable=false). 요청 내용 점검 또는 다른 모델. upstream 필드에 원문 요약 포함. |
| catalog_snapshot_stale | detail.error · 503 | 카탈로그 스냅샷 확인 불가. 잠시 후 재시도. |
| upstream_error | SSE error.code | SSE 스트림 도중 업스트림 중단. partial에 수신된 부분이 담기고 그 부분만 과금됩니다. |
| invalid_request | error.type · 400 | 잘못된 요청 형식(예: UUID 자리에 비-UUID 문자열). |
| payload_too_large | error.type · 413 | 요청 본문 상한 초과. |
| limiter_unavailable | error.type · 503 | 리미터 일시 장애. 잠시 후 재시도. |
스트리밍 중 에러#
stream: true 요청이 도중 실패해도 HTTP 상태는 200으로 열려 있으므로, 실패는 마지막 SSE 이벤트로 전달됩니다. partial 객체에 지금까지 수신된 응답이 담기고 과금도 그 부분만 발생합니다. 부분 응답이 없으면 data: [DONE]이 바로 내려옵니다.
SSE — stream failure
data: {"error": {"code": "upstream_error", "message": "모델 제공자 연결이 중단되었습니다. 받은 부분까지만 과금됩니다.", "partial": {...}}}
data: [DONE]재시도 가이드#
429와 502(retryable=true)는 지수 백오프로 재시도하세요. 텍스트 경로는 서버가 프로바이더당 기본 2회 자동 재시도·폴백하므로, 클라이언트 재시도 간격은 1초 이상을 권장합니다. 4xx와 retryable=false 502는 요청을 수정하기 전까지 재시도해도 같은 결과입니다.
이미지·영상·음악 등 미디어 생성 요청은 서버 자동 재시도가 없습니다(텍스트 전용).
retryable=true여도 동일 요청의 즉시 재시도는 같은 결과를 낳을 수 있으니 파라미터를 점검한 뒤 재시도하세요.자주 보는 에러와 해결#
| 에러 | 해결 |
|---|---|
400 — 지원하지 않는 모델 ID (gpt-5.5-mini 오타 등) | 메시지에 유사 모델 추천이 포함됩니다. GET /v1/models로 전체 목록을 확인하세요. |
| 400/422 — 미디어 파라미터 거부 (duration·해상도·참조 이미지 수 등) | 모델별 허용값은 각 미디어 문서(이미지·영상)의 제약 표를 확인하세요. 에러 메시지가 거부된 파라미터와 허용값을 안내합니다. |
| 402 — insufficient_credits | 대시보드 → 결제에서 충전 후 재시도. 예산·토큰 한도 코드라면 키 설정에서 조정. |
| 429 — rate limit | Retry-After 헤더 값 이후 지수 백오프로 재시도하세요. |
| 502 — upstream_request_rejected | upstream 요약을 확인해 요청 파라미터를 점검하고, 같은 결과가 반복되면 다른 모델로 전환하세요. |