탐색으로 건너뛰기

BeatAPI 빠른 시작

빠른 시작

BeatAPI는 텍스트, 워크플로, 실시간, 영상, 이미지, 이펙트 API 전반에서 서버 측 API 키 하나를 사용합니다. 아래 세 단계로 시작한 다음, 동기식 텍스트 응답, 공통 작업 필드, 업로드, 제한, 운영 환경 오류는 이 가이드의 나머지 부분을 참고하세요.

세 단계로 첫 작업 만들기

1. API 키 만들기

대시보드 → API Keys에서 키를 만든 다음, 명령 기록에 남지 않도록 셸에 불러오세요.

read -rsp "BeatAPI API key: " BEATAPI_API_KEY && echo
export BEATAPI_API_KEY

모든 요청은 https://api.beatapi.io 기본 URL과 다음 헤더를 사용합니다.

Authorization: Bearer <BEATAPI_API_KEY>

2. 작업 만들기

이 최소 이미지 요청은 POST /v1/images/tasks를 사용합니다.

curl https://api.beatapi.io/v1/images/tasks \
-X POST \
-H "Authorization: Bearer $BEATAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana",
"prompt": "Editorial product photograph on a warm stone pedestal."
}'

올바른 요청은 201 Created를 반환합니다. 반환된 data.id를 저장하세요.

3. 결과 폴링

curl https://api.beatapi.io/v1/tasks/task_8K2qA \
-H "Authorization: Bearer $BEATAPI_API_KEY"

task_8K2qA를 2단계의 data.id로 바꾸세요. 폴링 사이에는 data.poll_after_seconds만큼 기다리세요(이미지 5, 영상과 이펙트 8, 데이터와 워크플로 10. 작업이 실행되는 동안 표시됩니다). succeeded이면 data.output.media를 읽고 폴링을 멈추세요. failed이면 data.error_code와 data.error_message를 읽고 폴링을 멈추세요.

영구 API 키는 신뢰할 수 있는 서버에만 두세요. 브라우저 코드, 모바일 코드, 스크립트, 로그, 스크린샷에는 절대 넣지 마세요. 실시간 브라우저에는 서버에서 만든 수명이 짧은 client_secret만 전달됩니다.

API 선택

API생성 작업입력결과
텍스트(GPT-5.6)POST /v1/responses텍스트, 이미지, 도구, 추론 설정동기식 JSON 또는 스트리밍 텍스트 응답
워크플로 — 뮤직비디오POST /v1/music-video/tasks오디오와 등급별 시각 참조 자료완성된 뮤직비디오와 스토리보드 메타데이터
워크플로 — 이커머스POST /v1/ecommerce-video/tasks제품 이미지, 길이, 크리에이티브 브리프완성된 제품 영상
워크플로 — 영상 분석POST /v1/video-analysis/tasks업로드한 영상, 분석 프롬프트, 분석 깊이분석 텍스트와 토큰 사용량
실시간POST /v1/realtime/sessions브라우저 출처와 고정 길이, 이후 라이브 MediaStream실시간 생성 WebRTC 영상
영상POST /v1/videos/tasks모델별 프롬프트와 미디어 참조호스팅된 영상 하나
이미지POST /v1/images/tasks모델별 프롬프트와 선택적 참조호스팅된 이미지 하나
이펙트POST /v1/effects/tasks게시된 이펙트 ID, 이미지, 지원 옵션호스팅된 이미지 또는 영상 이펙트 결과 하나

텍스트 호출은 동기식으로 또는 서버 전송 이벤트 스트림으로 반환됩니다. 실시간 API는 수명이 짧은 세션을 만듭니다. 워크플로, 영상, 이미지, 이펙트 생성 작업은 비동기 작업을 반환합니다. data.id를 저장한 뒤 공통 작업 엔드포인트를 폴링하세요. GET /v1/tasks/{task_id} 폴링에는 요청 속도 제한이 없으며, 폴링 사이에 poll_after_seconds만큼 기다리세요.

GPT 모델 선택, 요청 형식, 스트리밍 예시는 GPT 가이드를 참고하세요.

작업 상태 조회

GET /v1/tasks/{task_id}

파라미터위치타입필수규칙
task_id경로string예생성 응답의 data.id를 사용하세요

상태 값

상태의미클라이언트 조치
queued접수되어 대기 중폴링을 계속하세요
processing생성 중폴링을 계속하세요
storyboard_ready뮤직비디오 스토리보드가 준비됨자동 흐름이 계속될 수 있습니다. 필요하면 확인하세요
requires_action뮤직비디오 수동 검토 대기 중샷을 편집하거나 합성하세요
editing뮤직비디오 샷 편집 중폴링을 계속하세요
composing뮤직비디오 합성 중폴링을 계속하세요
succeeded호스팅된 출력이 준비됨data.output를 읽고 폴링을 멈추세요
failed작업이 오류로 끝났습니다. 응답은 여전히 HTTP 200입니다error_code, error_message, retryable을 읽고 폴링을 멈추세요

이미지와 영상 작업은 queued, processing, succeeded, failed만 사용합니다. 나머지 상태는 뮤직비디오 전용입니다.

정규화된 작업 필드

필드타입포함 조건의미
idstring항상고정된 작업 ID
objectstring항상task
task_kindstring항상workflow, effect, image, video 또는 data
capability_idstring항상고정된 워크플로, 이펙트 또는 생성 모델 ID
capability_versioninteger항상항상 1
workflowstring워크플로 작업music-video 또는 ecommerce-video
effect_idstring이펙트 작업고정된 이펙트 ID
effect_versioninteger이펙트 작업선택된 이펙트의 변경 불가 버전
media_typestring이미지/영상 작업image 또는 video
modelstring이미지/영상 작업고정된 모델 별칭
statusstring항상현재 수명 주기 상태
stagestring항상status와 같은 값. 호환성을 위해 유지
storyboardobject뮤직비디오가능한 경우 샷 메타데이터
created_atinteger항상Unix 타임스탬프
updated_atinteger항상Unix 타임스탬프
completed_atinteger or null항상종료 시점의 Unix 타임스탬프
poll_after_secondsinteger작업 실행 중다음 폴링까지 기다릴 초: 이미지 5, 영상과 이펙트 8, 데이터와 워크플로 10
typical_secondsobject작업 실행 중이며, 기록이 충분할 때만p50, p90, samples, window: 이 모델이 최근에 걸린 시간입니다. p90를 넘으면 작업이 오래 걸리고 있는 것입니다.
outputobject or null항상성공할 때까지 null
usageobject항상크레딧과 과금 대상 길이
request_idstring항상지원/디버그용 상관 ID
error_codestring or null항상기계가 읽을 수 있는 작업 실패 코드
error_messagestring or null항상사람이 읽을 수 있는 작업 실패 메시지
retryableboolean실패한 작업에만 있음작업을 다시 제출하면 성공할 수 있는지 여부

사용량과 출력 필드

credits_reserved 같은 공개 응답 이름은 API 호환성을 위해 유지됩니다. 모든 크레딧과 잔액 값은 소수점 USD 원장 금액입니다: 1 Credit = 1USD.대시보드는같은값을‘1 USD. 대시보드는 같은 값을 `` 기호로 표시합니다.

필드타입의미
usage.credits_reservednumber작업을 위해 보류된 USD 금액
usage.credits_chargednumber청구된 USD 금액. 실패한 작업은 0
usage.billable_duration_secondsinteger, optionalUSD 계산에 사용된 길이
usage.credits_settlednumber작업 성공 후 확정된 USD 금액. 실패한 작업은 0
usage.credits_refundednumber작업 실패 후 환불된 USD 금액
output.mediaobject[]호스팅된 결과 파일
output.media[].typestringimage 또는 video
output.media[].urlstring결과 URL. 보관해야 하는 결과는 내려받아 저장하세요.
output.media[].mime_typestring결과 MIME 형식
output.r2_urlstring주 결과의 호스팅 URL

실패한 작업에서 usage.credits_reserved는 생성 시 보류된 금액, usage.credits_charged와 usage.credits_settled는 0, usage.credits_refunded는 환불된 금액입니다. 접수된 작업은 6가지 코드 중 하나로 실패합니다. content_policy_violation과 bad_request(재시도 불가), processing_unavailable, processing_timeout, processing_failed, result_transfer_failed(재시도 가능)입니다. 오류를 참고하세요.

입력 파일 업로드

POST /v1/files

입력이 공개 HTTPS URL에 없고 로컬에 있을 때 파일 업로드를 사용하세요. 모든 업로드에는 정확한 Content-Length가 있어야 합니다. 일반적인 curl, 브라우저, SDK 업로드는 자동으로 설정합니다. 길이를 선언하지 않은 청크 업로드는 본문을 버퍼링하기 전에 거부됩니다.

멀티파트 필드

필드타입필수기본값규칙
filebinary예—지원되는 파일 하나. 영상은 최대 100 MB, 그 밖의 형식은 최대 50 MB입니다. 100 MB를 넘는 멀티파트 파트는 바로 거부됩니다
purposestring아니요input무시됩니다. 응답은 항상 input입니다
curl https://api.beatapi.io/v1/files \
-X POST \
-H "Authorization: Bearer $BEATAPI_API_KEY" \
-F "file=@./song.mp3" \
-F "purpose=input"

파일 본문을 해당 자산의 Content-Type과 함께 그대로 보낼 수도 있습니다.

자산허용 확장자허용 MIME 형식추가 규칙
이미지PNG, JPG/JPEG, WebPimage/png, image/jpeg, image/webp최대 50 MB
오디오MP3, WAV, AAC, M4Aaudio/mpeg, audio/wav, audio/aac, audio/mp4최대 50 MB
자막SRTapplication/x-subrip. text/plain은 파일 이름이 .srt로 끝나는 멀티파트 업로드에서만 허용최대 50 MB
영상MP4, MOVvideo/mp4, video/quicktime최대 100 MB

흔히 쓰이는 일부 별칭은 받아서 표준 형식으로 저장합니다. 예를 들어 image/jpg는 image/jpeg으로, audio/mp3는 audio/mpeg로, text/plain(.srt 파일 이름)은 application/x-subrip으로 저장합니다. PDF, 일반 텍스트, octet-stream, 지원하지 않는 영상 컨테이너, ZIP 업로드는 400 bad_request로 거부됩니다. 게이트웨이는 선언된 Content-Type을 신뢰하며, 파일 이름에 확장자가 있으면 그 형식과 일치해야 합니다. 파일 내용은 검사하지 않으며 길이나 크기도 읽지 않습니다. 업로드에서 받은 파일이라도 작업을 만들 때 그 파일을 쓰는 모델이나 워크플로가 길이나 크기 규칙 등으로 거부할 수 있습니다. 워크플로 입력 URL은 localhost, 사설 네트워크 또는 데이터 URL일 수 없습니다.

업로드 거부는 다음 메시지 중 하나와 함께 400 bad_request로 반환됩니다.

메시지원인
Content-Length is required for file uploads.선언된 길이가 없습니다.
Content-Length must be a positive integer.선언된 길이가 잘못되었습니다.
File exceeds the declared upload limit.선언된 길이가 업로드 제한을 넘습니다.
No file provided. Use multipart "file" field or a raw body.요청에 파일이 없습니다.
The uploaded file is empty.0바이트입니다.
Unsupported file type. Supported uploads are png, jpg, jpeg, webp, mp3, wav, aac, m4a, mp4, mov, and srt.허용되지 않는 형식이나 확장자입니다.
File exceeds the 50 MB limit.50 MB 초과(영상은 File exceeds the 100 MB limit.).
File exceeds the 100 MB upload limit.100 MB를 넘는 멀티파트 파트.
Could not read the uploaded file.파일 본문을 읽을 수 없습니다.
Could not read the multipart upload.멀티파트 양식을 파싱할 수 없습니다.

파일을 저장할 수 없으면 업로드는 processing_unavailable(“File storage is temporarily unavailable. Retry later; nothing was stored.”) 또는 result_transfer_failed(“The file could not be stored on our side. Retry; nothing was stored.”)와 함께 503으로 응답합니다. 백오프를 두고 재시도하세요.

파일 응답

{
"data": {
"id": "file_6f1c2b9e-4d0a-4c58-9a57-2f0a8f3d7b11",
"object": "file",
"url": "https://files.beatapi.io/u/6f1c2b9e4d0a4c589a572f0a8f3d7b11.mp3",
"key": "u/6f1c2b9e4d0a4c589a572f0a8f3d7b11.mp3",
"mime_type": "audio/mpeg",
"size_bytes": 1048576,
"purpose": "input",
"created_at": 1782210000
}
}
필드타입포함 조건의미
idstring항상파일 ID, file_<uuid>
objectstring항상file
urlstring항상HTTPS 입력 URL
keystring항상스토리지 키, u/<random>.<ext>
mime_typestring항상파일이 저장되고 제공되는 표준 MIME 형식(예: image/jpg는 image/jpeg으로 표시)
size_bytesinteger항상업로드된 바이트 크기
purposestring항상input
created_atinteger항상Unix 타임스탬프

모델이나 워크플로 요청에는 data.url을 사용하세요. 모델이나 워크플로는 작업을 만들 때 자체 제한을 검사합니다. 예를 들어 Standard 뮤직비디오는 10180초, Premium은 10300초 길이의 오디오를 받습니다.

사용량과 한도 확인

GET /v1/usage

API 키나 계정의 개인 액세스 토큰을 보내세요. 둘 다 같은 계정 전체 요약을 반환합니다.

유일한 선택 쿼리 파라미터 period는 집계와 세부 내역의 기간(현재 시점까지)을 정합니다: 24h, 7d, 30d 또는 all(기본값, 계정 전체 기록). credit_balance와 concurrency는 항상 현재 값입니다. 그 밖의 파라미터나 다른 period 값은 400으로 거부됩니다.

curl "https://api.beatapi.io/v1/usage?period=7d" \
-H "Authorization: Bearer $BEATAPI_API_KEY"
필드타입의미
objectstringusage
periodstring24h, 7d, 30d 또는 all
since, untilinteger, optional기간의 시작·끝(Unix 초). all에서는 없음
account_namestring, optional계정 표시 이름
credit_balancenumber현재 USD 잔액. 음수일 수 있음
total_tasksinteger계정 작업 수
credits_settlednumber정산된 USD 금액
credits_refundednumber환불된 USD 금액
concurrencyobject처리 중 작업 용량 요약
concurrency.limitinteger계정의 처리 중 작업 한도
concurrency.activeinteger현재 처리 용량을 사용 중인 작업
realtimeobject, optional실시간 세션 사용량 요약
realtime.sessionsinteger실시간 세션 총수
realtime.creditsnumber실시간 정산 USD 금액
realtime.activeintegerready, connecting 또는 active 상태의 세션
by_workflow[]object[]워크플로 호환성 세부 내역
by_capability[]object[]고정 기능별 전체 작업 종류
by_model[]object[]모델 별칭별 이미지/영상 작업
by_api_key[]object[]API 키별 작업/크레딧 합계

세부 항목 필드:

Array필수 항목 필드
by_workflowworkflow, tasks, credits_settled
by_capabilitytask_kind, capability_id, tasks, credits_settled
by_modelmedia_type, model, tasks, credits_settled
by_api_keyapi_key_id, title, key_prefix, tasks, credits_settled

storyboard_ready 또는 requires_action에서 일시 중지된 뮤직비디오 작업은 처리 중 작업으로 집계되지 않으면서도 정산된 크레딧이 있을 수 있습니다.

작업이나 텍스트 요청별 비용은 계정의 개인 액세스 토큰으로 요청별 사용 기록을 읽어 확인하세요.

오류와 재시도 정책

{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded: at most 60 successful requests per 1 minute(s). Retry after 60 seconds.",
"retryable": true,
"request_id": "req_abc123",
"retry_after_seconds": 60
}
}

모든 오류에는 code, 원인을 설명하는 영어 message, request_id가 있습니다. 429 rate_limit_exceeded에만 retry_after_seconds와 Retry-After 헤더가 추가로 있으며, 503은 대기 시간을 알 수 없으므로 백오프를 두고 재시도하세요. 아래 표의 모든 코드에는 retryable이 있습니다. 이 값으로 분기하세요. false는 요청을 바꾸기 전까지 같은 호출이 다시 실패한다는 뜻입니다.

공개 오류 코드

BeatAPI는 아래의 고정된 공개 코드만 노출합니다. BeatAPI는 모델 뒤의 공급사를 밝히지 않으며 원본 응답 본문을 그대로 전달하지 않습니다. 오류 페이지에서 작업 생성 시와 접수된 작업에서 각 실패가 어떤 코드를 내는지, 텍스트 엔드포인트가 모델 호출 전(이 형식)과 호출 중(SDK 고유의 오류 형식. BeatAPI 자체 거부에는 BeatAPI 코드, 모델 측 실패에는 변환된 코드)에 어떻게 실패하는지 확인할 수 있습니다. 이 값은 응답의 error.code에 나타납니다. 비동기 작업이 최종 실패하면 작업의 error_code에도 해당 값이 반환될 수 있습니다.

코드의미클라이언트 조치
bad_requestJSON 형식이 잘못되었거나 요청 필드, 조합, 형식, URL, 제한이 올바르지 않습니다. 작업 생성 시이거나, 접수된 작업에서 모델이 파라미터나 입력을 거부한 경우입니다. 메시지에 해당 필드가 표시됩니다재시도 전에 요청을 수정하세요
missing_api_keyAPI 키를 보내지 않았습니다Authorization: Bearer <key>를 보내세요
invalid_api_key키가 잘못되었거나 만료·비활성화·소진되었습니다. 메시지에 어느 경우인지 표시됩니다대시보드에서 활성 키를 확인하세요
unauthorized401의 이전 이름으로, 2026-09-29에 missing_api_key와 invalid_api_key로 대체되었습니다. 아직 나타날 수 있습니다invalid_api_key처럼 처리하세요
forbidden키나 계정이 이 작업을 수행할 수 없습니다. 예: 무료 크레딧으로 쓸 수 없는 모델, 키의 IP 허용 목록, 키의 그룹메시지를 확인하세요. 무료 크레딧 계정은 충전하면 모든 모델을 쓸 수 있습니다
not_found알 수 없는 모델이나 기능, 또는 존재하지 않거나 이 API 키의 계정 소유가 아닌 리소스ID와 API 키 소유 계정을 확인하세요
insufficient_credits잔액 부족: 계정 잔액이 0이거나 이 요청 가격보다 적습니다유료 요청을 다시 보내기 전에 충전하세요
idempotency_conflict멱등성 키가 이미 다른 요청 본문에 사용되었습니다같은 논리적 요청에만 키를 재사용하거나 새 키를 사용하세요
rate_limit_exceededAPI 키가 요청 속도 제한(무료 모델 제한 포함)을 넘었습니다Retry-After 또는 retry_after_seconds를 따르세요
content_policy_violation프롬프트, 입력 미디어 또는 결과가 콘텐츠 검수에서 거부되었습니다새 요청을 제출하기 전에 프롬프트나 미디어를 수정하세요
processing_unavailable모델을 일시적으로 사용할 수 없거나 용량이 가득 찼습니다(요청 속도 제한과는 무관)나중에 백오프를 두고 재시도하세요. 이미 접수된 작업은 계속 폴링하세요
processing_failedBeatAPI 측 원인으로 처리에 실패했습니다폴링을 멈추고 error_message와 환불 필드를 확인한 뒤 백오프를 두고 재시도하세요
processing_timeout처리 시간 안에 처리가 끝나지 않았습니다폴링을 멈추고 환불 필드를 확인한 뒤, 필요하면 새 요청을 제출하세요
result_transfer_failedBeatAPI가 생성 결과를 자체 스토리지에 저장하지 못했습니다폴링을 멈추고 환불 필드를 확인한 뒤, 필요하면 작업을 재시도하세요
result_expiredoperation: "result"를 사용한 POST /v1/capabilities/run에서 저장된 결과를 찾지 못했습니다. 결과는 1시간 동안 보관됩니다(404)기능을 다시 실행하세요
not_implemented엔드포인트는 게시되었지만 이 게이트웨이에서 아직 제공하지 않습니다(501)재시도하지 마세요
realtime_disabled이 배포 환경에서는 Realtime Video가 활성화되어 있지 않습니다이 배포 환경에서는 Realtime Video가 활성화되어 있지 않습니다. 직접 조치할 방법이 없으니 지원팀에 문의하세요
realtime_capacity_unavailable실시간 처리 용량을 일시적으로 사용할 수 없습니다잠시 후 백오프를 두고 재시도하세요. 대기 시간은 표시되지 않습니다
realtime_session_expired실시간 세션을 더 이상 사용할 수 없습니다새 세션과 클라이언트 시크릿을 만드세요
origin_not_allowed이 브라우저 출처는 실시간 세션에 허용되지 않습니다설정한 HTTPS 출처를 정확히 사용하세요
invalid_client_secret실시간 클라이언트 시크릿이 잘못되었거나 더 이상 사용할 수 없습니다새 세션을 만들고 새 클라이언트 시크릿을 사용하세요
transport_not_allowed요청한 실시간 전송 방식이 허용되지 않습니다실시간 API 문서에 나온 전송 방식을 사용하세요
internal_errorBeatAPI에서 예기치 않은 내부 오류가 발생했습니다request_id를 보관하세요. 안전할 때만 재시도하거나 BeatAPI 지원팀에 문의하세요
HTTP코드retryable클라이언트 조치
400bad_request, content_policy_violationfalse필드, 조합, 형식, URL, 제한 또는 입력을 수정하세요
401missing_api_key, invalid_api_keyfalseBearer 키를 보내거나 교체하세요
402insufficient_creditsfalse새 유료 요청 전에 충전하세요
403forbidden 또는 실시간 출처 오류false권한이나 정확한 브라우저 출처를 확인하세요
404not_found, result_expiredfalse모델, 레퍼런스 또는 ID와 API 키 소유 계정을 확인하세요
409idempotency_conflictfalse같은 논리적 요청 본문에만 키를 재사용하세요
429rate_limit_exceededtrueRetry-After 또는 retry_after_seconds를 따르세요
500internal_errortruerequest_id를 보관하고 한 번 재시도한 뒤 지원팀에 문의하세요
501not_implementedfalse재시도하지 마세요
503processing_unavailable, processing_timeout, processing_failed, result_transfer_failedtrue백오프를 두고 재시도하세요

BeatAPI는 502나 504로 응답하지 않습니다. 이런 응답을 받았다면 네트워크 에지에서 온 것이며 JSON 본문이 없으므로 503처럼 재시도하세요.

멱등성:

  • 워크플로, 이미지, 영상, 이펙트 작업 생성과 POST /v1/capabilities/run은 선택적으로 키를 받습니다. 실시간 세션 생성에는 키가 필수입니다(최대 255자).
  • 키는 24시간 동안 기억됩니다. 255자를 넘는 키는 400 bad_request입니다.
  • 같은 키를 다른 본문이나 경로에 사용하면 409 idempotency_conflict입니다. 첫 요청이 아직 처리 중일 때 같은 키를 사용해도 마찬가지입니다.
  • 완전히 같은 요청을 반복하면 Idempotent-Replayed: true 헤더와 함께 저장된 응답이 반환됩니다.
  • 2xx 응답만 저장되므로 400이나 402 뒤에는 같은 키로 재시도할 수 있습니다.

운영 환경 체크리스트

  • 정확한 https://api.beatapi.io 오리진을 사용하세요.
  • 영구 API 키는 신뢰할 수 있는 서버에만 두세요.
  • 선택한 API 페이지에 따라 필수/선택 필드, 열거값, 제한, 조건부 규칙을 검증하세요.
  • 백그라운드 작업을 시작하기 전에 작업/세션 ID와 request_id를 저장하세요.
  • poll_after_seconds마다 폴링하고, 문서에 나온 종료 상태나 조치 필요 상태에서 멈추세요.
  • 보관해야 하는 결과는 내려받아 저장하세요.
  • 상태 코드, Retry-After, retry_after_seconds를 따르세요.
  • JSON을 파싱하기 전에 원본 바이트로 웹훅 서명을 검증하세요. 웹훅은 task.succeeded와 task.failed만 보내며 3번 시도합니다(1분 후와 5분 후 재시도). 시간 초과 정리로 실패 처리된 작업은 이벤트를 보내지 않으므로, 폴링을 기준으로 삼으세요.
  • 크레딧 보류, 정산, 환불, 오류, 최종 출력 URL을 기록하세요.
  • 카메라, 얼굴, 음성, 참조 자료를 처리하기 전에 개인정보처리방침과 서비스 약관을 검토하세요.