오류
오류
BeatAPI는 모든 실패를 정해진 코드 중 하나로 알려 줍니다. code 또는 retryable로 분기하세요. message는 원인을 사람이 읽을 수 있게 설명한 영어 문장입니다. BeatAPI는 모델 뒤의 공급사를 밝히지 않으며 모델 측의 원본 응답 본문도 전달하지 않습니다. 유일한 예외는 텍스트 엔드포인트에서 모델이 반환하는 영어 입력 검증 문장으로, 입력을 고칠 수 있도록 그대로 전달합니다. 지원 요청을 위해 request_id를 보관하세요.
오류 객체
이미지·영상 작업, GET /v1/tasks/{task_id}, 기능, 워크플로, /v1/systemone(별칭 /v1/decisions 포함), /v1/moderations, /v1/social-data/call, /v1/web/* 등 BeatAPI의 모든 엔드포인트는 같은 형식으로 오류를 반환합니다.
POST /v1/chat/completions, POST /v1/responses, POST /v1/messages는 모델을 호출하기 전의 실패에는 이 형식을 사용하고, 호출 중의 실패에는 각 SDK 고유의 오류 형식을 유지합니다. 텍스트 엔드포인트를 참고하세요. Gemini 네이티브 엔드포인트(/v1beta/...)와 GET /v1/models는 이와 다른 더 단순한 형식을 사용하며, 같은 섹션에서 설명합니다.
POST /v1/moderations도 이 형식을 사용합니다. 이 엔드포인트에서는 오류 객체에 OpenAI의 type과 param도 포함되므로(param은 항상 null) OpenAI SDK가 평소와 같은 예외를 발생시킵니다. 콘텐츠 검수 API를 참고하세요.
실패가 나타나는 위치
작업은 두 시점에서 실패할 수 있으며, 각각 형태가 다릅니다.
- 생성할 때. 작업이 만들어지기 전에 요청이 거부됩니다.
error객체가 담긴 HTTP 오류를 받으며data.id는 없습니다. 과금되지 않습니다. - 접수된 후.
POST가data.id와 함께201을 반환했고, 이후 작업이status: "failed"로 끝납니다.GET /v1/tasks/{task_id}는 여전히200을 반환하며, 실패 정보는data.error_code,data.error_message,data.retryable에 있습니다. 작업을 위해 보류된 크레딧은 환불됩니다.
같은 실패는 두 위치 모두에서, 그리고 사용량 로그의 오류 줄(content_policy_violation: The request was blocked…)에서도 같은 코드를 갖습니다. 실패한 작업은 HTTP 오류가 아닙니다. GET /v1/tasks/{task_id}는 status: "failed", error_code, error_message, retryable과 함께 200을 반환하고, 작업을 위해 보류된 크레딧은 환불됩니다. 실패한 작업에서 usage.credits_reserved는 생성 시 보류된 금액이고, usage.credits_charged와 usage.credits_settled는 0이며, usage.credits_refunded는 환불된 금액입니다.
접수된 작업은 다음 여섯 가지 코드 중 하나로만 끝날 수 있습니다. 나머지 코드는 요청 시점의 거부입니다.
시간 초과 정리 과정에서 실패 처리된 작업은 웹훅 이벤트를 보내지 않으므로 GET /v1/tasks/{task_id} 폴링을 계속하세요. 기준이 되는 정보는 폴링 결과입니다.
기능 실행
지연 실행된 기능이 실패하면 위의 공통 오류 형식(code, message, retryable, request_id)으로 응답하며, 상태 코드는 오류 코드에 따릅니다(processing_* 코드는 503). 이 실행은 과금되지 않습니다. 약 85초가 지나도 실행이 계속되면 대신 status: "running"과 함께 202를 반환합니다.
operation: "result"를 지정한 POST /v1/capabilities/run은 request_id로 저장된 결과를 읽습니다. 결과는 1시간 동안 보관됩니다. 저장된 결과가 없으면 404 result_expired(retryable: false)를 반환하므로 기능을 다시 실행하세요.
코드
이미지·영상 작업 엔드포인트에서 본문이 너무 크면 400 bad_request(“Request body is too large.”)입니다. 413 read_request_body_failed는 텍스트 엔드포인트에만 있으며 위 표에는 없습니다. 본문에 retryable 필드가 없습니다. 그대로 재시도해도 소용없으니 더 작은 본문을 보내세요. 아래를 참고하세요.
processing_unavailable과 rate_limit_exceeded는 서로 다릅니다. rate_limit_exceeded는 사용자 측의 요청 속도에 관한 것으로, 속도를 늦추라는 뜻입니다. processing_unavailable은 모델이 지금 작업을 받을 수 없다는 뜻이며, 요청 자체에는 문제가 없습니다.
BeatAPI는 502나 504를 반환하지 않습니다. 그래도 502 또는 504를 받았다면 BeatAPI에 연결할 수 없었던 네트워크 엣지에서 온 것이며, 본문은 JSON이 아닙니다. 503처럼 백오프를 적용해 재시도하세요. 본문이 error code: 1010인 403도 마찬가지입니다. 엣지가 클라이언트의 기본 User-Agent(예: Python의 urllib)를 거부한 것이므로 User-Agent를 명시적으로 보내세요.
Realtime 코드
이 코드는 Realtime 세션에서만 나타납니다. 웹훅 서명 검증은 받은 콜백을 직접 확인하는 절차이며, BeatAPI는 이에 대한 오류 코드를 반환하지 않습니다(웹훅 참고).
텍스트 엔드포인트
POST /v1/chat/completions, POST /v1/responses, POST /v1/messages는 두 단계에서 실패할 수 있으며, 단계마다 본문 형식이 다릅니다.
1. 모델을 호출하기 전. 키가 없거나 유효하지 않은 경우, 무료 크레딧 제한, 키의 IP 허용 목록이나 그룹, 라우팅, 요청 속도 제한은 BeatAPI 오류 형식으로 응답합니다. code, message, retryable, request_id가 포함되며 429에는 retry_after_seconds와 Retry-After도 포함됩니다. 이 단계에서 알 수 없는 모델은 404 not_found입니다. 키의 IP 허용 목록 밖에서 보낸 요청이나 키의 그룹에 속하지 않은 모델은 403 forbidden입니다. /v1/chat/completions, /v1/responses, /v1/messages 모두 같습니다.
Gemini 네이티브 엔드포인트와 GET /v1/models. /v1beta/...와 GET /v1/models는 BeatAPI 오류 형식을 사용하지 않습니다. 오류는 {"error":{"message":"... (request id: ...)","type":"beatapi_error","code":...}} 형태이며 retryable이나 retry_after_seconds가 없습니다. 429에는 여전히 Retry-After 헤더가 포함됩니다.
2. 호출 중. OpenAI·Anthropic SDK가 파싱해 평소와 같은 예외를 발생시킬 수 있도록, 본문은 의도적으로 SDK 고유 형식을 유지합니다. retryable 필드는 없으므로 상태 코드와 오류 코드를 사용하세요. 이 단계에서는 모든 message 뒤에 요청 ID가 덧붙습니다. 여기서는 세 종류의 실패가 발생합니다.
- 게이트웨이가 직접 거부한 경우에는 BeatAPI 코드(
insufficient_credits,content_policy_violation,bad_request,not_found,internal_error)를 사용합니다. - 모델 측 실패는
temporary_error,upstream_timeout,model_unavailable,rate_limit_exceeded중 하나의 코드와 함께 SDK 고유 형식으로 바꿔 반환하며, HTTP 상태는 유지합니다. 단,502와504는503이 됩니다. 공급사와 관련된 BeatAPI 계정 측 문제는503 model_unavailable로 보고합니다. - 모델이 반환한 영어 파라미터 오류(예: 컨텍스트 길이 초과)는 입력을 고칠 수 있도록 문장 그대로 전달합니다.
OpenAI 형식(/v1/chat/completions, /v1/responses):
Anthropic 형식(/v1/messages):
게이트웨이가 직접 거부한 경우 OpenAI 형식에서는 type이 beatapi_error이고 BeatAPI 코드는 error.code에 들어갑니다. Anthropic 형식에서는 코드가 error.type에 들어갑니다.
재시도 정책
- 그대로 재시도하지 마세요(
retryable: false):bad_request,content_policy_violation,missing_api_key,invalid_api_key,unauthorized,insufficient_credits,forbidden,not_found,result_expired,read_request_body_failed,idempotency_conflict,not_implemented,realtime_session_expired. 즉 모든400,401,402,403,404,409,410,413,501이 해당합니다.read_request_body_failed에는retryable필드가 없고 코드 표에도 없지만false로 취급하세요. - 기다린 뒤 재시도(
retryable: true):rate_limit_exceeded.Retry-After/retry_after_seconds를 따르세요. - 백오프를 적용해 재시도(
retryable: true):internal_error와 네 가지503코드(processing_unavailable,processing_timeout,processing_failed,result_transfer_failed). Realtime503코드는 다릅니다.realtime_capacity_unavailable은 재시도할 수 있고realtime_disabled는 재시도할 수 없습니다. 지터를 넣은 지수 백오프와 상한을 사용하세요. 실패한 작업은 환불되었으므로, 새로운 시도는 성공할 때만 새로 과금됩니다. 작업 생성 시Idempotency-Key를 보내면 제출을 재시도해도 두 번째 작업이 생기지 않습니다.
멱등성
Idempotency-Key는 작업 생성과 POST /v1/capabilities/run에서 선택 사항입니다.
- 키는 24시간 동안 기억됩니다.
- 255자를 넘는 키는
400 bad_request입니다. - 같은 키를 다른 본문이나 경로에 사용하면
409 idempotency_conflict입니다. 첫 요청이 아직 처리 중일 때 같은 키를 사용해도 마찬가지입니다. - 완전히 같은 요청을 반복하면 저장된 응답을 반환하고
Idempotent-Replayed: true헤더를 추가합니다. 2xx응답만 저장됩니다.400또는402이후에는 같은 키로 재시도할 수 있습니다.
결과
결과 URL은 output.media[].url에 반환됩니다. 보관해야 하는 결과는 직접 다운로드해 저장하세요.
변경 내역
- 2026-10-15 — 파일을 저장할 수 없는 업로드는
503(processing_unavailable또는result_transfer_failed)으로 응답하며 아무것도 저장되지 않습니다. 텍스트 호출 중 모델 측에서 실패하면temporary_error,upstream_timeout,model_unavailable,rate_limit_exceeded와 함께 SDK 고유 형식으로 바꿔 반환하며, 이 단계의 모든 메시지 뒤에 요청 ID가 덧붙습니다. - 2026-10-15 — 지연 실행된 기능이 실패하면 이제
type: api_error가 담긴 본문이 아니라 공통 오류 형식(code,message,retryable,request_id)과 해당 코드의 상태로 응답합니다.retry_after_seconds와Retry-After는429 rate_limit_exceeded에서만 보내며503에서는 보내지 않습니다.result_expired와not_implemented를 표에 추가했습니다. 게이트웨이가 실제로 반환한 적이 없는user_concurrency_exceeded와invalid_signature는 삭제했습니다. 실패한 작업에서usage.credits_charged는0이고usage.credits_refunded는 환불된 금액입니다. 텍스트 엔드포인트에서는 모델 호출 전의 실패에 BeatAPI 오류 형식을 사용하고, 호출 중의 실패에는 SDK 고유 본문을 유지합니다. - 2026-09-29 — 이제
401은 항상missing_api_key(키를 보내지 않음) 또는invalid_api_key(잘못되었거나 만료, 비활성화, 소진된 키, 메시지에 원인 표시)입니다.unauthorized는 두 경우의 이전 이름이며, 오래된 클라이언트에서 보이면invalid_api_key처럼 처리하세요. 잔액 부족은 텍스트 엔드포인트를 포함한 모든 엔드포인트에서 항상402 insufficient_credits입니다.retryable은 모든 오류에 포함되며, 모든 오류의message는 원인을 설명하는 영어 문장입니다. - 2026-09-25 — BeatAPI는 더 이상
502나504를 직접 반환하지 않습니다. 완료하지 못한 동기식 소셜 데이터·웹 호출과 백그라운드에서 실패한 리서치 실행(환불됨)을 포함해 모든 처리 실패(processing_unavailable,processing_timeout,processing_failed,result_transfer_failed)는 JSON 오류 본문이 담긴503입니다. 그래도502를 받았다면 BeatAPI에 연결할 수 없었던 엣지에서 온 것이며 본문은 JSON이 아닙니다. 백오프를 적용해 재시도하세요. - 2026-09-23 — 거부된 파라미터나 접근할 수 없는 입력 때문에 접수 후 실패한 작업은 이제
bad_request를 보고합니다(이전에는processing_failed). 생성 시 모델 자체의 상태 코드는 더 이상 그대로 전달하지 않습니다. 콘텐츠 검수 거부는 항상400 content_policy_violation이고, 모델을 사용할 수 없으면503 processing_unavailable입니다. 생성 시 잔액이 부족하면402 insufficient_credits입니다.

