에러 코드
HTTP 상태 코드, detail.error 기계 판독 코드, 응답 형식으로 에러를 반환합니다.
상태 코드#
| 코드 | 이름 | 설명 |
|---|---|---|
400 | Bad Request | 잘못된 요청. 지원하지 않는 모델 ID(유사 모델 추천 포함), 모델별 파라미터 제약 위반(duration·해상도·참조 이미지 수 등), 키의 허용 모델 밖 접근 등. |
401 | Unauthorized | API 키 누락·무효·만료 또는 삭제된 계정. |
402 | Payment Required | 크레딧 부족, 예산·토큰 한도 초과 또는 BYOK 정지. 코드별 해결책이 다릅니다(아래 기계 판독 코드 표). |
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 | 게이트웨이 오류(요청이 API 서버에 닿지 못함). 본문이 JSON이 아닐 수 있습니다 — 잠시 후 재시도하세요. |
503 | Service Unavailable | 업스트림 프로바이더 오류 또는 일시적 처리 불가(카탈로그 스냅샷 확인 불가·리미터 장애). 텍스트 요청의 업스트림 오류는 서버가 자동 재시도·폴백 후에도 실패한 경우이며, retryable 필드로 재시도 의미를 구분하세요. |
응답 형식#
오류 본문 형식은 표면마다 다릅니다. /v1/messages는 Anthropic 형식 { type: "error", error: { type, message } }, /v1beta는 Google 형식 { error: { code, message, status } }입니다. Chat Completions·Responses 등 그 밖의 모델 API는 detail(문자열·객체)을 담고, OpenAI 호환 { error: { message, type, code, param } } 봉투가 함께 오는 응답도 있습니다. 스키마 검증 실패(422)는 detail에 배열이 담깁니다. 오류 판별에는 HTTP 상태 코드와 error.code 또는 detail을 쓰세요.
{
"error": {
"message": "사용 가능 크레딧 부족: 12,000 크레딧 < 54,000 크레딧. 대시보드 → 결제에서 충전해주세요.",
"type": "insufficient_quota",
"code": "insufficient_credits",
"param": null
},
"detail": {
"error": "insufficient_credits",
"message": "사용 가능 크레딧 부족: 12,000 크레딧 < 54,000 크레딧. 대시보드 → 결제에서 충전해주세요.",
"action": { "type": "topup", "path": "/billing" }
}
}{
"error": {
"message": "모델 제공자가 요청을 거부했습니다. 잠시 후 다시 시도하거나 다른 모델을 사용해주세요. (upstream 400: ...)",
"type": "api_error",
"code": "upstream_request_rejected",
"param": null
},
"detail": {
"error": "upstream_request_rejected",
"message": "모델 제공자가 요청을 거부했습니다. 잠시 후 다시 시도하거나 다른 모델을 사용해주세요. (upstream 400: ...)",
"retryable": false,
"upstream": { "status": 400, "detail": "..." }
}
}{
"error": {
"message": "요청 본문이 너무 큽니다(최대 50MB).",
"type": "payload_too_large"
}
}{
"detail": [
{
"type": "greater_than_equal",
"loc": ["body", "duration_seconds"],
"msg": "Input should be greater than or equal to 2",
"input": 1,
"ctx": {"ge": 2}
}
]
}구조화 에러에는 action 필드에 대시보드 경로가 실릴 수 있고, retryable·providers·upstream 필드가 상황별로 추가됩니다. message는 한국어 고정이므로 파싱 대상이 아니라 사람용 안내로 쓰세요.
기계 판독 코드#
| 코드 | 위치 · HTTP | 의미와 해결 |
|---|---|---|
insufficient_credits | error.code · detail.error · 402 | 크레딧 부족. 대시보드의 결제 페이지에서 충전 후 재시도. |
request_exceeds_credits | error.code · detail.error · 402 | 잔액으로 이 요청의 최대 비용을 감당할 수 없음. 메시지에 생성 가능한 최대 토큰 수가 담김. max_tokens를 줄이거나 충전 후 재시도. |
monthly_budget_exceeded | error.code · detail.error · 402 | API 키 일·주·월 예산 초과. 충전이 아니라 키 설정에서 예산 조정. |
monthly_token_quota_exceeded | error.code · detail.error · 402 | API 키 월 토큰 한도 초과. 키 설정에서 한도 조정. |
byok_suspended | error.code · detail.error · 402 | BYOK 사용료 미납으로 BYOK 호출 정지. 충전하면 자동으로 해제. |
workspace_budget_exceeded | error.code · detail.error · 403 | 워크스페이스 한도 초과. 워크스페이스 소유자에게 한도 조정을 요청. details에 한도에 걸린 기간 포함. |
xborder_training_consent_required | error.code · detail.error · 403 | 학습 사용 provider 별도 동의 미보유. providers 목록과 함께 오며 설정에서 동의하면 해결. |
guardrail_blocked | error.code · detail.error · 403 | 가드레일 정책에 걸려 차단된 요청. guardrail 필드에 정책 이름이 담김. 요청 내용을 수정. |
rate_limit_exceeded | error.code · 429 | 요청 속도 제한 초과. 별도 코드가 없는 429의 기본 코드. Retry-After 이후 재시도. |
admission_busy | error.code · detail.error · 429 | 동시 진행 요청이 잔액을 확보하는 중이라 일시적으로 거절됨. 잔액 부족(402)이 아니므로 Retry-After 이후 재시도. |
concurrency_limit_exceeded | error.code · detail.error · 429 | 사용자당 동시 요청 한도 초과. 진행 중인 요청이 끝난 뒤 재시도. |
upstream_rate_limited | error.code · detail.error · 429 | 업스트림 전체가 한도 도달. Retry-After 이후 재시도. |
upstream_unavailable | error.code · detail.error · 503 | 업스트림 일시 장애(retryable=true). 잠시 후 재시도. |
upstream_request_rejected | error.code · detail.error · 503 | 업스트림이 요청 거부(retryable=false). 요청 내용 점검 또는 다른 모델. upstream 필드에 원문 요약 포함. |
catalog_snapshot_stale | error.code · detail.error · 503 | 카탈로그 스냅샷 확인 불가. 잠시 후 재시도. |
provider_unavailable | error.code · detail.error · 503 | 이 모델의 제공자 연결 문제(플랫폼 측). 잠시 후 재시도하거나 다른 모델 사용. |
upstream_error | SSE error.code | SSE 스트림 도중 업스트림 중단. partial은 불리언이며, true이면 받은 부분까지만 과금됩니다. |
invalid_request | error.type · 400 | 잘못된 요청 형식(예: UUID 자리에 비-UUID 문자열). |
payload_too_large | error.type · 413 | 요청 본문 상한 초과. |
limiter_unavailable | error.type · 503 | 리미터 일시 장애. 잠시 후 재시도. |
스트리밍 중 에러#
stream: true 요청이 도중 실패해도 HTTP 상태는 200으로 열려 있으므로, 실패는 SSE 이벤트로 전달됩니다. partial은 불리언입니다.true이면 이미 받은 응답이 있고, 그 부분만 과금되며 사용량 청크가 이어진 뒤 data: [DONE]으로 끝납니다. false이면 받은 응답이 없고 data: [DONE]이 바로 내려옵니다.
data: {"error": {"code": "upstream_error", "type": "api_error", "message": "모델 제공자 연결이 중단되었습니다. 받은 부분까지만 과금됩니다.", "partial": true}}
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":3,"total_tokens":15}}
data: [DONE]재시도 가이드#
429와 503(retryable=true)은 지수 백오프로 재시도하세요. 텍스트 경로는 서버가 프로바이더당 기본 2회 자동 재시도·폴백하므로, 클라이언트 재시도 간격은 1초 이상을 권장합니다. 4xx와 retryable=false 503은 요청을 수정하기 전까지 재시도해도 같은 결과입니다.
retryable=true여도 동일 요청의 즉시 재시도는 같은 결과를 낳을 수 있으니 파라미터를 점검한 뒤 재시도하세요.자주 보는 에러와 해결#
| 에러 | 해결 |
|---|---|
400 — 지원하지 않는 모델 ID (gpt-5.5-mini 오타 등) | 메시지에 유사 모델 추천이 포함됩니다. GET /v1/models로 전체 목록을 확인하세요. |
| 400/422 — 미디어 파라미터 거부 (duration·해상도·참조 이미지 수 등) | 모델별 허용값은 각 미디어 문서(이미지·영상)의 제약 표를 확인하세요. 에러 메시지가 거부된 파라미터와 허용값을 안내합니다. |
| 402 — insufficient_credits | 대시보드의 결제 페이지에서 충전 후 재시도. 예산·토큰 한도 코드라면 키 설정에서 조정. |
| 429 — rate limit | Retry-After 헤더 값 이후 지수 백오프로 재시도하세요. |
| 503 — upstream_request_rejected | upstream 요약을 확인해 요청 파라미터를 점검하고, 같은 결과가 반복되면 다른 모델로 전환하세요. |