문서
오류
Kunavo는 재시도 여부를 나타내는 HTTP 상태 코드와 함께 OpenAI 형식의 오류 페이로드를 반환합니다. 표준 OpenAI SDK 오류 처리 방식을 따르면 문제없이 처리할 수 있습니다.
모든 2xx가 아닌 응답은 OpenAI 표준과 동일한 JSON 형식을 사용합니다. 프로그래밍 방식의 처리는 error.code를 기준으로 하고, 재시도 정책은 status_code를 기준으로 정하세요.
오류 페이로드
{
"error": {
"message": "Model 'xyz-2025' is not available",
"type": "model_not_found",
"code": "model_not_found",
"param": null
}
}| 필드 | 유형 | 참고 |
|---|---|---|
message | string | 사람이 읽을 수 있는 형식입니다. 로그에 기록해도 안전하며, 비밀 정보는 절대 포함하지 않습니다. |
type | string | 대략적인 범주(authentication_ |
code | string | 세분화된 식별자입니다. 프로그래밍 방식의 분기 처리에 사용합니다. |
param | string|null | 오류가 특정 필드와 관련된 경우 해당 필드의 이름을 표시합니다. |
HTTP 상태 코드
| HTTP | 의미 | Retry? |
|---|---|---|
| 400 | invalid_ — 요청 페이로드의 형식이 잘못되었습니다. | 아니요 — 요청을 수정하세요. |
| 401 | authentication_ — API 키가 잘못되었거나, 누락되었거나, 취소되었습니다. | 아니요 — 키를 교체하세요. |
| 402 | insufficient_ — 지갑 잔액이 없거나(code: insufficient_), 월간 한도에 도달했습니다. | 아니요 — /app/Retry-After 헤더가 있으면 자동 충전이 진행 중이라는 뜻입니다. 충전이 완료된 후 재시도하세요. |
| 403 | permission_ — 키는 유효하지만 IP 허용 목록에 현재 IP가 포함되어 있지 않습니다. | 아니요 — 허용된 주소에서 호출하세요. |
| 404 | model_ — 알 수 없거나 비활성화된 모델 ID입니다. | 아니요 — /v1/models를 확인하세요. |
| 404 | missing_ — api./v1가 없는 엔드포인트 경로를 사용했거나, 기본 호스트로 POST 요청을 보냈습니다. | 아니요 — 기본 URL을 https://api. |
| 404 | unknown_url — /v1 아래에 해당 경로의 엔드포인트가 없습니다. 메시지에 가장 가까운 경로가 표시됩니다. | 아니요 — 경로를 수정하세요. |
| 408 | 클라이언트 요청 시간 초과입니다. | 예. 단, 멱등성에 유의하세요. |
| 422 | upstream_422 — 업스트림에서 입력을 거부했습니다(예: 지원하지 않는 크기). | 아니요 — 입력을 조정하세요. |
| 429 | 요청이 너무 많아 속도가 제한되었습니다. 동시 호출 수가 너무 많습니다. | 예 — 지수 백오프를 사용하세요. |
| 500 | Kunavo 내부 오류입니다. | 예 — 짧은 백오프를 적용하세요. |
| 502 | upstream_ — 업스트림 제공업체에서 오류가 발생했습니다. | 예 — 지수 백오프를 사용하세요. |
| 504 | 작업 시간이 초과되었습니다(이미지/ | 예. 다만 비용이 발생할 수 있습니다. |
실패한 호출(4xx 및 5xx)에는 요금이 청구되지 않습니다.
usage_logs의 비용 항목은 $0입니다. 예외: 장시간 실행되는 작업 API에서 504 시간 초과가 발생한 경우, 작업은 완료되었지만 결과를 전달하지 못했다면 업스트림 비용이 표시될 수 있습니다. 드문 경우입니다.일반적인 오류 코드
authentication_error
Authorization: Bearer ...헤더 설정을 잊었습니다./app/keys에서 API 키가 취소되었습니다.- 키의 접두사가 여전히 잘못되었습니다(
sk-kn-로 시작해야 함).
insufficient_quota
- 이 요청을 처리하기에 지갑 잔액이 부족합니다 →
error.code는insufficient_balance이며, 오류에는 지갑 보유액(balance_usd), 이 요청에서 예약하는 금액(needed_usd), 두 개의 링크가 포함됩니다.topup_url를 열면 충전 금액이 미리 선택된 결제 페이지가 표시되고,auto_recharge_url를 열면 자동 충전 설정이 표시됩니다. 링크를 여는 것만으로는 요금이 청구되지 않습니다. - 키별 월간 한도에 도달했습니다. 한도는 매월 1일(UTC)에 초기화됩니다.
/app/keys에서 한도를 높이세요.
{
"error": {
"message": "Wallet balance is too low for this request. Top up at https://kunavo.com/app/billing — or turn on auto-recharge there, and a saved card refills the wallet before requests are refused.",
"type": "insufficient_quota",
"code": "insufficient_balance",
"param": null,
"balance_usd": 0.0142,
"needed_usd": 0.0381,
"topup_url": "https://kunavo.com/app/billing?topup=20",
"auto_recharge_url": "https://kunavo.com/app/billing?autorecharge=1&src=api_402"
}
}응답에 Retry-After 헤더가 없는 한 insufficient_balance에서는 재시도를 중단하세요. 이 헤더가 있으면 저장된 카드로 자동 충전이 진행 중이라는 뜻이며, 몇 초 후 같은 요청이 성공해야 합니다.
permission_error
- 키에 IP 허용 목록이 설정되어 있지만, 호출이 목록에 없는 주소에서 들어왔습니다. 메시지에 확인된 주소가 표시됩니다.
/app/keys에서 해당 주소(또는 CIDR 블록)를 추가하거나, 허용 목록을 완전히 삭제해 모든 주소를 허용하세요. - 에이전트를 새 호스트나 새 NAT 게이트웨이로 옮기거나, 다른 네트워크에 연결된 노트북에서 실행하면 해당 주소가 바뀝니다. 허용 목록이 없는 키는 이 사유로 거부되지 않습니다.
model_not_found
- 슬러그의 철자가 잘못되었습니다. 표준 목록은 /models에서 확인하세요.
- 모델이 현재 비활성화되어 있습니다(업스트림 장애 또는 가격 검토).
upstream_error
업스트림 모델 제공업체에서 오류를 반환했지만, 이를 더 구체적인 코드로 변환할 수 없음을 나타냅니다. 응답 본문에 원본 메시지가 포함됩니다. 일반적인 원인은 다음과 같습니다.
- 제공업체 측 과부하입니다.
- 콘텐츠 조정 정책에 의해 거부되었습니다(다른 프롬프트를 시도하세요).
- 지역 또는 이용 가능 여부 제한입니다.
재시도 전략
가장 간단하고 안정적인 방법은 429 및 5xx에서만 지터를 적용한 지수 백오프를 사용하는 것입니다.
import time, random
from openai import OpenAI, RateLimitError, APIError
client = OpenAI(api_key=os.environ["KUNAVO_API_KEY"], base_url="https://api.kunavo.com/v1")
def call_with_retry(call, max_attempts=5):
for attempt in range(max_attempts):
try:
return call()
except RateLimitError:
if attempt + 1 == max_attempts: raise
# 429: exponential backoff with jitter
time.sleep(min(2 ** attempt, 30) + random.random())
except APIError as e:
if e.status_code and 500 <= e.status_code < 600 and attempt + 1 < max_attempts:
time.sleep(min(2 ** attempt, 30) + random.random())
else:
raise
result = call_with_retry(lambda: client.chat.completions.create(
model="claude-haiku-4-5",
messages=[{"role": "user", "content": "hi"}],
))- 시도당 대기 시간은 최대 30초, 전체 시도 횟수는 최대 5회로 제한하세요.
- 408 및 429를 제외하고 4xx는 재시도하지 마세요. 재시도해도 시간만 낭비됩니다.
- 이미지 생성과 동영상 생성은 멱등적이지 않습니다. 재시도는 새로운 생성이며, 성공하면 요금이 청구됩니다. 실패한 호출에는 요금이 청구되지 않았으므로 이를 재시도하는 것은 안전합니다. 동영상의 경우
POST /v1/videos는Idempotency-Key헤더를 지원하며, 같은 키로 다시 제출하면 첫 번째 작업이 반환됩니다. - 자체 코드에서 부수 효과가 있는 채팅 요청을 처리할 때는 애플리케이션 계층에서 멱등성 키를 사용해 중복을 제거하세요.
대시보드에서 디버깅하기
성공 여부와 관계없이 모든 API 호출을 /app/usage에서 확인할 수 있습니다. 행을 클릭하면 전체 요청/응답 상세 페이지가 열립니다.
- 클라이언트에 반환된 HTTP 상태 코드입니다.
- 해당하는 경우 업스트림 오류 코드입니다.
- 지연 시간, 요청 IP, 사용자 에이전트입니다.
- 상태별로 필터링하면 패턴을 파악하는 데 도움이 됩니다(예: 특정 모델에서 발생한 모든 422 오류).
인시던트 신고
정상 작동해야 하는 모델에서 5xx 오류가 계속 발생하면 다음 정보를 support@kunavo.com으로 이메일로 보내세요.
- 모델 슬러그와 샘플 요청 본문(비밀 정보는 삭제하세요).
- 오류가 발생한 시간대입니다.
- 응답의 오류
code및message입니다. - 가능하다면
/app/usage/[id]의 사용 로그 링크를 보내주세요.
영업일 기준 1일 이내에 응답하며, 긴급하고 매출에 영향을 미치는 문제에는 더 빠르게 응답합니다.