개발 가이드
개발 가이드
빠른 시작에서는 요청 하나를 동작시키는 데 집중합니다. 이 페이지에서는 코드가 프로덕션에서 계속 안정적으로 동작하려면 무엇이 달라지는지 다룹니다.
두 가지 호출 형태
BeatAPI의 요청 수명 주기는 정확히 두 가지이며, 통합 과정의 실수는 대부분 한쪽을 다른 쪽처럼 다루는 데서 생깁니다.
텍스트는 동기식입니다. POST /v1/chat/completions, /v1/responses, /v1/messages 또는 Gemini 호환 엔드포인트가 결과를 반환합니다. 그 밖의 요청은 작업을 접수하고 ID를 돌려줍니다.
비동기 수명 주기
- 제출 —
POST /v1/images/tasks(또는videos,effects,video-analysis,music-video,ecommerce-video).201은 접수되었다는 뜻이지 완료되었다는 뜻이 아닙니다. - ID 저장 — 백그라운드 작업을 시작하기 전에
data.id와data.request_id를 저장하세요. 응답을 받은 뒤 저장하기 전에 프로세스가 중단되면, 비용은 냈지만 찾을 수 없는 작업이 남습니다. - 대기 —
GET /v1/tasks/{task_id}를 폴링하거나 웹훅을 등록합니다. - 결과 확인 —
succeeded이면data.output.media를 사용합니다.failed이면data.error_code와 환불 필드를 확인합니다.
폴링
이 루프에서 중요한 세 가지 특성은 다음과 같습니다.
- 종료 상태에서 멈춥니다. 경과 시간을 추측해 멈추지 않습니다. 완료된 작업은 다시 바뀌지 않습니다.
- 지터를 넣어 백오프합니다.
poll_after_seconds를 지키고, 동시에 실행되는 여러 작업의 폴링 시점이 겹치지 않게 하세요. 더 자주 폴링한다고 작업이 빨리 끝나지는 않습니다. 429를 ‘실패’가 아닌 ‘대기’로 처리합니다.Retry-After를 따르세요.
Music Video 작업에는 계속 폴링하는 대신 판단이 필요한 비종료 상태(storyboard_ready, requires_action)가 있습니다. 이를 ‘아직 처리 중’으로 취급하면 폴링이 끝나지 않습니다. 모든 상태와 각 상태에서 해야 할 조치는 빠른 시작에 정리되어 있습니다.
폴링 대신 웹훅
POST /v1/webhooks로 엔드포인트를 등록하면 BeatAPI가 종료 상태를 해당 엔드포인트로 전송합니다. 외부에서 접근 가능한 HTTPS 엔드포인트가 필요하지만, 폴링 루프를 완전히 없앨 수 있습니다.
JSON을 파싱하기 전에 원본 요청 바이트로 서명을 검증하세요. 본문을 다시 직렬화하면 내용이 바뀌어 서명이 일치하지 않습니다. 웹훅을 참고하세요.
웹훅을 설정했더라도 느린 주기의 대조용 폴링은 유지하세요. 전달이 실패할 수 있으며, 모델의 일반적인 처리 시간보다 훨씬 오래 processing 상태인 작업은 직접 확인해 볼 필요가 있습니다.
오류
모든 실패에는 고정된 error.code, 원인을 설명하는 영어 message, retryable, request_id가 포함됩니다. request_id를 로그에 남기세요. 지원팀이 정확한 호출을 찾는 데 사용합니다.
오류의 retryable도 코드별로 같은 정보를 알려 주므로, 상태 코드 대신 이 값으로 분기할 수 있습니다. BeatAPI는 502나 504를 반환하지 않습니다. 이런 응답을 받았다면 네트워크 엣지에서 발생한 것이며 503처럼 재시도하면 됩니다. 모든 코드는 오류에 나와 있습니다.
제출 요청에서 받은 500은 판단하기 애매합니다. 작업이 생성되었을 수도, 생성되지 않았을 수도 있습니다. 무작정 다시 제출하면 같은 작업에 두 번 비용을 낼 수 있습니다. 작업 생성 시 Idempotency-Key를 보내고 재시도할 때 같은 값을 다시 사용하세요. BeatAPI는 두 번째 작업을 만들지 않고 원래 작업을 반환합니다.
요청 속도 제한
두 가지 제한이 따로 적용되며, 실패 방식도 다릅니다.
- 요청 속도 — 키별 분당 요청 수입니다. 초과하면
Retry-After와 함께429를 반환합니다. 한도는 누적 충전액에 따라 올라가며, 현재 값과 다음 단계는 대시보드와GET /api/user/self에서 확인할 수 있습니다.
GET /v1/usage는 두 가지를 모두 보고합니다: concurrency.limit과 concurrency.active.
비용이 들지 않는 재시도
429와5xx는 백오프를 적용해 재시도하세요(BeatAPI가 반환하는5xx는 모두500또는503입니다).400,401,402,403,404,409는 재시도하지 마세요. 이 응답에는retryable: false가 포함됩니다.- 지터를 넣은 지수 백오프를 사용하고 상한을 두세요.
- 모든 작업 생성 요청에
Idempotency-Key를 넣어, 제출을 재시도해도 중복 과금되지 않게 하세요. - 제출이 실패했는데 ID가 있다면 다시 제출하기 전에 폴링하세요.
- 전체 시도 횟수에 상한을 두세요. 계속 실패하는 요청을 끝없이 재시도하면 비용이 계속 나가는 장애가 됩니다.
비용 관리
- 텍스트 호출에는 출력 상한을 설정하세요. 비용이 큰 쪽은 출력이며,
max_tokens가 가장 간단한 조절 수단입니다. - 단계에 맞는 모델을 고르세요. 분류나 라우팅에는 최상위 모델이 필요하지 않습니다.
- 구간별 요금 모델에 주의하세요. GPT-5.6 계열과 Grok 계열은 컨텍스트가 일정 기준을 넘으면 더 높은 요금이 적용됩니다. DeepSeek HC(high-cache) 모델 두 개는 평일 베이징 시간 09:00–12:00와 14:00–18:00에, Hunyuan
hy3는 공개된 피크 시간대에 더 높은 요금이 적용됩니다. 일반 유료 DeepSeek 모델은 시간과 관계없이 같은 요금입니다. 오래 실행되는 에이전트나 예약된 배치 작업은 모르는 사이에 이 기준을 넘을 수 있습니다. 각 응답의 사용량 기록에서 어떤 요금이 적용되었는지 확인할 수 있습니다. - 구성 요소마다 키를 하나씩 사용하세요. 그러면 별도 작업 없이
GET /v1/usage의by_api_key로 비용을 구분해 볼 수 있습니다. - 환불 내역을 대조하세요. 실패한 작업은 환불됩니다. 장부에 보류 금액만 기록하면 실제 청구서와 숫자가 어긋납니다.
프로덕션 배포 전 확인 사항
- 정확한
https://api.beatapi.io오리진을 사용하세요. - 영구 키는 서버에만 두세요. 브라우저에는 API 키가 아니라 수명이 짧은 Realtime
client_secret을 전달하세요. - 백그라운드 작업을 시작하기 전에
data.id와request_id를 저장하세요. - 지터를 넣어 폴링하고, 종료 상태나 조치가 필요한 상태에서 멈추세요.
- 웹훅 서명은 원본 바이트로 검증하세요.
- 보류, 정산, 환불, 오류, 최종 출력 URL을 기록하세요.
402응답에 알림을 걸어 두세요. 이 상태가 되면 계정의 모든 유료 작업이 한꺼번에 중단됩니다.

