API Hop 문서
오류 코드와 문제 해결
모든 플랫폼 오류 코드를 확인하고, 프로토콜별 오류를 구분하며, 안전하게 재시도하고 사용자와 AI를 위한 진단 정보를 수집합니다.
무엇이 실패했는지 확인하기
- 실제 HTTP 상태, 요청 메서드와 경로를 기록하세요. HTTP 상태와 애플리케이션 오류 코드는 서로 다른 계층을 설명하므로 서로 대신 사용하지 마세요.
- 호출한 프로토콜에 맞게 오류 필드를 읽으세요. 네이티브, OpenAI, Claude, Gemini 응답의 구조는 모두 같지 않습니다.
- 스트리밍에서는 오류 이벤트와 완료 상태도 확인하고, 비동기 작업에서는
status를 확인하세요. HTTP200은 생성 성공을 보장하지 않습니다. - 아래 표를 사용해 요청을 수정하거나 재시도 여부를 판단하세요.
message는 설명문이며 안정적인 열거형 값이 아니므로 문구에 따라 분기하지 마세요.
플랫폼 오류 코드 열거형
다음은 플랫폼 애플리케이션 오류 코드의 전체 열거형입니다. 이름은 참조용 레이블이며 응답의 code 값은 숫자입니다. 일반적인 HTTP 상태는 문제 해결을 위한 참고 자료이며 모든 엔드포인트의 고정 매핑이 아닙니다. 실제 HTTP 상태와 응답 본문을 사용하세요. 업스트림에서 그대로 전달된 code는 이 열거형에 포함되지 않을 수 있습니다.
숫자 code | 이름 | 일반적인 HTTP 상태 | 의미와 조치 |
|---|---|---|---|
10000 | BAD_REQUEST | 400 | 요청 형식, 경로 또는 기본 매개변수가 잘못되었습니다. 메서드, 경로, JSON 구문과 매개변수 이름을 확인하세요. |
10001 | VALIDATION_ERROR | 400 / 422 | 매개변수 검증에 실패했습니다. 필수 필드, 형식, 범위와 매개변수 조합을 확인하세요. |
20000 | AUTH_ERROR | 401 | 인증에 실패했습니다. API 키의 유효성, 만료 여부와 인증 헤더 형식을 확인하세요. |
20001 | FORBIDDEN | 403 | 접근이 거부되었거나 계정이 제한되었습니다. 계정 권한과 리소스 소유권을 확인하세요. |
30000 | NOT_FOUND | 404 | 경로, 모델 또는 리소스가 없습니다. 현재 API 키에 표시되는 리소스를 기준으로 엔드포인트 경로, model과 작업 ID를 확인하세요. |
30001 | CONFLICT | 409 | 작업이 현재 리소스 상태와 충돌합니다. 수정하기 전에 현재 상태를 읽고 중복 제출을 피하세요. |
40000 | INSUFFICIENT_CREDIT | 402 | 잔액이 부족합니다. 다시 호출하기 전에 잔액을 확인하고 충전하세요. |
40001 | RATE_LIMIT | 429 | 요청이 너무 자주 발생합니다. 요청 빈도를 낮추고 재시도를 지연하세요. |
40002 | CONCURRENCY_LIMIT | 429 | 동시 요청이 너무 많습니다. 동시 실행 수를 줄이고 진행 중인 요청이 완료될 때까지 기다리세요. |
50000 | PROVIDER_ERROR | 502 | 업스트림 호출이 실패했거나 유효한 결과를 반환하지 않았습니다. 제한된 재시도를 검토하기 전에 결과가 생성되었는지 확인하세요. |
50001 | SERVICE_UNAVAILABLE | 503 | 서비스를 일시적으로 사용할 수 없습니다. 나중에 횟수를 제한해 재시도하고 오류가 계속되면 진단 정보를 수집하세요. |
50002 | GATEWAY_TIMEOUT | 504 | 처리 시간이 초과되었습니다. 결과가 불확실할 수 있으므로 재시도 전에 실행 여부를 확인하세요. |
50003 | INTERNAL_ERROR | 500 | 분류되지 않은 서버 오류가 발생했습니다. 횟수를 제한해 재시도하고 오류가 계속되면 진단 정보를 수집하세요. |
HTTP 429만으로는 요청 빈도 제한과 동시 실행 제한을 확실히 구분할 수 없습니다. 명시적인 숫자 오류 코드가 있을 때만 구분하세요. 모델 목록에서 모델 식별자를 확인하고 model 값을 임의로 바꾸지 마세요.
프로토콜별 오류 읽기
아래 예제는 플랫폼이 생성하는 일반적인 구조를 보여 주며 모든 오류에 보장되는 단일 형식이 아닙니다. 인증 오류는 서로 다른 처리 계층에서 발생할 수 있고, 그대로 전달되는 업스트림 응답은 자체 구조, 문자열 코드 또는 유형을 유지할 수 있습니다. 파싱하기 전에 실제 구조를 확인하세요. 알 수 없는 구조라면 강제로 변환하지 말고 원래 필드와 HTTP 상태를 보존하세요.
플랫폼 네이티브 API
일반적으로 error.code와 error.message를 읽습니다. requestId는 없을 수 있습니다.
{
"success": false,
"error": {
"code": 10000,
"message": "Bad request"
},
"requestId": "req_example"
}일부 오류는 최상위 code와 message 필드를 사용합니다. 클라이언트는 이를 허용해야 하며 error 객체가 없다는 이유만으로 성공으로 판단하면 안 됩니다. 매개변수 검증 응답에도 숫자 오류 코드가 없을 수 있습니다. 없는 코드는 만들어 내지 말고 알 수 없음으로 처리하세요.
OpenAI 호환 API
일반적인 플랫폼 오류는 최상위 code, message, type 필드를 사용하며 반드시 error 안에 들어 있는 것은 아닙니다.
{
"code": 40000,
"message": "Insufficient credit",
"type": "api_error"
}type은 프로토콜 범주이고 이 구조의 code는 플랫폼의 숫자 오류 코드입니다. api_error만으로 재시도 가능 여부를 판단할 수 없습니다. 업스트림에서 전달된 오류와 스트리밍 오류에는 중첩된 error가 있을 수 있으므로 실제 프로토콜 응답에 맞게 처리하세요. Chat Completions와 Responses를 참고하세요.
Claude 호환 API
일반적인 구조에서 최상위 type은 error이고, 구체적인 범주는 error.type, 설명은 error.message에 있습니다. 이 구조에는 플랫폼 숫자 code가 없습니다. 임의로 만들지 마세요.
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "max_tokens must be a positive safe integer"
}
}플랫폼은 다음 Claude 오류 유형을 로컬에서 생성합니다. 업스트림 오류 유형의 전체 열거형은 아닙니다.
error.type | 로컬 HTTP 매핑 | 확인 사항 |
|---|---|---|
invalid_request_error | 400 | 요청 형식과 매개변수를 확인하세요. |
authentication_error | 401 | 인증 자격 증명을 확인하세요. |
api_error | 그 밖의 HTTP 상태 | 일반 API 오류입니다. 실제 HTTP 상태와 설명을 확인하세요. 반드시 재시도할 수 있는 것은 아닙니다. |
Claude 메시지를 참고하세요.
Gemini 형식 오류
Gemini 형식 응답에서는 error.code, error.message, error.status를 읽으세요. 여기서 status는 문자열 범주이며 HTTP 상태나 비동기 작업 상태가 아닙니다.
{
"error": {
"code": 10000,
"message": "Bad request",
"status": "INVALID_ARGUMENT"
}
}플랫폼이 이 구조로 생성한 오류는 code에 플랫폼 숫자 값을 사용합니다. 문자열 status의 로컬 매핑은 아래와 같으며 모든 업스트림 상태를 나열한 것은 아닙니다.
error.status | 로컬 HTTP 매핑 | 확인 사항 |
|---|---|---|
UNAUTHENTICATED | 401 | 인증 자격 증명을 확인하세요. |
RESOURCE_EXHAUSTED | 402 / 429 | 잔액이나 사용 제한을 확인하세요. 문자열만으로는 둘을 구분할 수 없습니다. |
PERMISSION_DENIED | 403 | 권한과 리소스 소유권을 확인하세요. |
NOT_FOUND | 404 | 경로, 모델 또는 리소스를 확인하세요. |
UNAVAILABLE | 503 | 서비스를 일시적으로 사용할 수 없습니다. |
INTERNAL | >= 500, 단 503 제외 | 서버 오류입니다. 504도 이 값을 사용합니다. |
INVALID_ARGUMENT | 그 밖의 HTTP 상태 | 실제 HTTP 상태와 요청을 확인하세요. 409도 이 값을 사용합니다. |
503이 우선하며 INTERNAL이 아닌 UNAVAILABLE을 사용합니다. 업스트림 응답의 code와 status는 의미가 다를 수 있습니다. 모든 Gemini 숫자 코드에 플랫폼 오류 코드 표를 적용하지 마세요.
안전한 재시도
| 상황 | 권장 조치 |
|---|---|
400 / 401 / 402 / 403 / 404 / 409 / 422 | 먼저 요청, 자격 증명, 잔액, 권한 또는 리소스 상태를 수정하세요. 변경하지 않은 요청을 반복해서 보내지 마세요. API 키는 헤더에만 넣고 URL 쿼리 매개변수에는 절대 넣지 마세요. |
429 | 요청 빈도와 동시 실행 수를 줄이고 기다린 뒤 재시도하세요. 시도 횟수만 늘리면 일반적으로 제한 상황이 악화됩니다. |
500 / 502 / 503 / 504 | 먼저 중복 실행 위험을 평가하세요. 그런 다음 지터를 포함한 제한된 지수 백오프를 사용하세요. 예를 들어 최대 3회 재시도와 전체 대기 시간 제한을 설정합니다. |
| 네트워크 연결 종료 또는 클라이언트 시간 초과 | 결과를 받지 못했다고 서버가 요청을 실행하지 않았다는 뜻은 아닙니다. 실패로 단정하거나 즉시 새 요청을 만들지 말고 결과를 알 수 없음으로 표시하세요. |
유효한 Retry-After 헤더가 있으면 따르세요. 모든 오류에 이 헤더가 있다고 가정하지 마세요. 멱등하지 않은 생성 요청을 자동으로 재시도하면 다시 실행되고 추가 비용이 발생할 수 있습니다. 이 페이지는 일반적인 멱등성 키 지원을 약속하지 않습니다. 직접 Idempotency-Key를 추가해도 중복 제거는 보장되지 않습니다.
이미 jobId가 있다면 새 작업을 만들기 전에 해당 작업을 조회하세요. jobId가 없고 결과가 불확실하면 조사를 위해 요청 식별자와 타임스탬프를 보존하세요.
스트림과 비동기 작업
SSE 요청
SSE가 시작된 후 HTTP 상태는 200으로 유지되면서 이후 오류가 스트림의 이벤트나 페이로드로 보고될 수 있습니다. 선택한 프로토콜의 이벤트와 데이터를 파싱하고 정상 완료 여부를 확인하세요. 오류나 예기치 않은 연결 종료가 발생하면 일부 텍스트나 이미지를 완전히 성공한 결과로 간주하지 마세요. 이벤트 이름과 페이로드는 엔드포인트마다 다릅니다. 하나의 고정된 error 필드만 확인하거나 텍스트를 조금이라도 받았다는 이유로 성공으로 판단하지 마세요.
비동기 작업
생성 응답의 data.jobId는 접수를 의미하며 생성 완료를 뜻하지 않습니다. 작업 조회의 성공 HTTP 응답은 조회가 성공했다는 뜻입니다. 여전히 작업의 data.status를 확인해야 합니다:
PENDING,CONNECT,PROCESSING: Jobs 문서에 따라 계속 폴링하세요.COMPLETED:outputResult를 읽으세요.FAILED,CANCELLED: 폴링을 중단하고 조사를 위해 작업 ID와 민감 정보를 제거한 응답 데이터를 보존하세요.
오류 세부 정보는 data.outputResult.error에 있을 수 있습니다. 이 필드는 선택 사항이며 모든 실패한 작업에 보장되지 않습니다. 생성 응답이 명시적으로 jobId를 반환할 때만 Jobs를 사용하세요. JSON 또는 SSE로 결과를 직접 반환하는 엔드포인트에 작업 폴링을 적용하지 마세요.
사용자와 AI 어시스턴트를 위한 진단
지원팀이나 AI 어시스턴트에 다음과 같이 민감 정보를 제거한 정보를 제공하세요. 없는 필드는 unknown으로, HTTP 응답을 받지 못했다면 HTTP 상태도 unknown으로 표시하세요. error.code: 10000 (number) 또는 error.code: "invalid_api_key" (string)처럼 필드 경로와 원래 값의 형식을 보존하세요. 문자열 code를 플랫폼 숫자 코드로 자동 변환하거나 message, HTTP 상태 또는 모델 이름으로부터 없는 필드를 만들어 내지 마세요.
time_with_timezone: unknown
method: unknown
path_without_query: unknown
model: unknown
stream: unknown
http_status: unknown
error_code_path_value_and_type: unknown
error_type_path_and_value: unknown
protocol_status_path_and_value: unknown
sanitized_message: unknown
request_id_from_body_or_X-Request-ID: unknown
job_id: unknown
job_status: unknown
retry_after: unknown
retry_count_and_delays: unknown
received_partial_output: unknown가능하면 응답 본문이나 X-Request-ID 응답 헤더에서 requestId를 읽으세요. 긴 숫자의 정밀도 손실을 피하려면 jobId를 문자열로 유지하세요. 민감 정보를 제거한 최소한의 요청 매개변수만 공유하세요. API 키, 토큰, 쿠키, 전체 인증 헤더, 개인 정보, 비공개 프롬프트와 입력 파일 내용을 제거하세요. URL 쿼리 매개변수와 서명 또는 자격 증명이 포함된 입력·출력 URL도 제거하세요. 검토하지 않은 전체 요청 로그를 붙여 넣지 마세요.
AI 어시스턴트는 관찰된 필드와 가능한 원인을 구분하고 누락된 정보를 밝혀야 합니다. 근거가 부족하다는 이유로 요청이 성공했거나 실행되지 않았거나 비용이 발생하지 않았다고 단정하면 안 됩니다.