일괄 전사 API: 여러 오디오 파일을 텍스트로 변환하기
API 일괄 전사는 파일마다 음성 인식 Job을 하나씩 보내는 루프입니다. 키는 파일 ID로 만들고, 결과는 웹훅이나 폴링으로 모읍니다. Sume에서 동작하는 방식을 설명합니다.

Job 기반 음성 인식 API에서 일괄 전사는 루프입니다. 오디오 파일마다 그 파일에서 만든 멱등성 키를 붙여 Job을 하나씩 제출하고, 아직 시작할 수 없는 Job은 서비스가 큐에 넣도록 두고, Job이 끝날 때마다 전사문을 저장하세요. Sume STT 1.0도 이렇게 동작합니다. 파일마다 별도의 POST /v1/stt-1.0/transcribe Job이 되며, 워크스페이스의 동시성 한도를 넘는 Job은 큐 용량이 남아 있는 동안 queued 상태로 기다립니다.
STT 1.0은 Sume API 레퍼런스의 바탕이 되는 OpenAPI 문서에 명세되어 있으며, API 레퍼런스 문서 페이지는 정확한 요청·응답 형태의 기준으로 이 문서를 안내합니다. 큐와 폴링은 Generation admission과 Job과 결과 (영문) 문서를 따릅니다. 모두 2026-09-27에 확인했습니다. 파일 하나만 전사한다면 단어별 타임스탬프를 주는 음성 인식 API를 참고하세요.
여러 파일을 한 번에 보내는 일괄 엔드포인트가 있나요?
없습니다. STT 1.0 요청은 audio_url 문자열 하나를 받고 스키마에 정의되지 않은 필드는 거부하므로, 파일 목록을 보낼 수 없습니다. 일괄 처리는 여러분의 서버에서 도는 루프이며, 파일 하나에 요청을 하나씩 보냅니다.
audio_url: 파일의 공개 HTTPS URL입니다. 요청에 업로드 필드가 없으므로, 각 파일은 이미 URL로 접근할 수 있어야 합니다.duration_seconds: 파일 길이로, 1–600 범위입니다. 사용량 예약의 크기를 정하며, 생략하면 Sume가 1분을 예약합니다. 10분이 넘는 파일은 먼저 여러 조각으로 나눠야 합니다.segmentation: { "mode": "sentence" }를 넣으면 각 결과에 문장 타임스탬프가 추가됩니다.webhook_url: 각 Job이 끝날 때 호출할 공개 HTTPS 콜백입니다. 대신 폴링하려면 생략하세요.Idempotency-Key: 파일 자체의 ID로 만듭니다. 그래서 같은 본문으로 다시 보내면 두 번째 Job 대신 원래 Job이 반환됩니다.
// Server-side Node 18+. files: [{ id, url, seconds }] from your own storage.
const jobIds = new Map(); // your file id -> Sume job id; persist it
for (const file of files) {
const res = await fetch("https://api.sume.com/v1/stt-1.0/transcribe", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.SUME_API_KEY,
"Content-Type": "application/json",
"Idempotency-Key": "stt-" + file.id, // same key, same body on every retry
},
body: JSON.stringify({
audio_url: file.url,
duration_seconds: file.seconds,
segmentation: { mode: "sentence" },
webhook_url: "https://example.com/webhooks/sume",
}),
});
if (res.status === 429) break; // queue full or rate limited: wait, then resume
if (!res.ok) throw new Error(await res.text());
const { data } = await res.json();
jobIds.set(file.id, data.request_id); // request_id is the job id
}동시에 실행할 수 있는 것보다 많은 파일을 제출하면 어떻게 되나요?
남는 Job은 기다립니다. Sume는 유료 Job을 큐 우선(queue-first) 방식으로 접수합니다. 유효한 Job은 곧바로 시작하거나, 워크스페이스 동시성 슬롯이 열릴 때까지 queued에서 기다립니다. 현재 코드에서 speech_to_text는 이 슬롯을 차지하는 Job 유형 중 하나입니다.
동시성 한도는 요금제가 정하며, 큐 용량의 기본값은 max(3, concurrency_limit × 5)입니다. Sume가 계산할 수 있을 때는 제출 응답에 generation_limits 스냅샷이 담깁니다. 이 스냅샷으로 제출 묶음(wave)마다 크기를 정하는 방법은 영상 Job 동시성과 큐에서 다룹니다. 루프는 다음 응답을 처리해야 합니다.
| 응답 | 의미 | 루프가 할 일 |
|---|---|---|
2xx | Job이 존재하고 유료 작업이 진행 중이라는 뜻. 끝났다는 뜻은 아님. | Job ID를 저장하고 다음 파일로 넘어감. |
429 queue_full | 워크스페이스에 남은 수락 생성 용량이 없음. | 멈추고 Job이 끝나기를 기다린 뒤, 같은 파일을 같은 키로 재시도. |
429 rate_limited | 요청량이 남용 방지 한도를 넘음. | retry-after가 있으면 그 값을 따라 백오프하고, 같은 키로 재시도. |
402 insufficient_credits | 잔액으로 예상 금액을 감당할 수 없음. 아무것도 시작되지 않음. | 잔액이 감당할 수 있을 때까지 일괄 처리를 멈춤. |
409 idempotency_conflict | 그 키가 이미 다른 페이로드에 쓰였음. | 키를 만드는 방식을 고침. 키는 똑같은 요청을 재시도할 때만 재사용. |
전사문은 어떻게 모으나요?
웹훅을 받거나, 폴링하거나, 둘 다 쓰세요. 문서는 웹훅을 유일한 복구 경로가 아니라 전달 최적화라고 설명하므로, 폴링도 쓸 수 있게 남겨 두세요.
- 웹훅: 각 Job이 끝나면 Sume가
job.completed,job.failed,job.canceled중 하나의 서명된 이벤트를 보내며, 진행 상황 콜백은 없습니다. 서명을 검증한 다음 그 Job의 결과를 가져오세요. - 폴링:
terminal이 true가 될 때까지next_poll_after_seconds를 지키며 백오프로GET /v1/jobs/{id}/status를 호출하세요.GET /v1/jobs/{id}/result는 Job이 완료될 때까지409 job_not_completed로 응답합니다. - 복구:
GET /v1/jobs?type=speech_to_text는 Job을 최신순으로, 페이지당 최대 100개까지 나열합니다. 각 행에는 생성할 때 쓴idempotency_key가 담기므로, 결과는 순서가 아니라 이 키로 파일과 맞추세요. - 완료된 결과에는
text, 각 단어의start와end를 초 단위로 담은words[], 문장을 요청했다면segments[], 그리고 있는 경우language_code가 들어 있습니다. - 같은 키로 다시 보내면 원래 Job이 반환됩니다. 그러니 실패한 파일을 다시 시도하려면 파일 ID에 시도 번호를 붙이는 식으로 새 키를 만들어 보내세요.
일괄 전사 비용은 얼마인가요?
파일을 하나씩 전사할 때와 같습니다. API 요금에 나온 오디오 분당 $0.01에 기본 5.5% 에이전트 수수료가 더해집니다. 5분짜리 녹음 100개가 밀려 있다면 오디오는 500분이고, 수수료 전 비용은 $5.00입니다.
Sume는 제출을 수락할 때 Job마다 예상 금액을 예약하고, Job이 완료되면 확정하며, Job이 실패하면 해당하는 경우 예약을 해제하거나 환불합니다. 큐에서 대기 중인 Job이 더 이상 필요 없다면 POST /v1/jobs/{id}/cancel로 취소하세요. Job이 이미 시작된 뒤에는 취소 요청이 409 job_generation_already_started로 응답하고, Job은 끝까지 실행됩니다.
어떤 제한이 있나요?
- 요청 하나에 파일 하나, 오디오는 최대 10분입니다.
duration_seconds의 최댓값이 600입니다. webhook_url은 공개 HTTPS여야 하며 최대 2,048자입니다. localhost와 사설 네트워크 URL은 거부됩니다.mode: "sync"는 요청을 최대 30초까지만 붙잡고 있으므로, 일괄 처리에는async나webhook을 쓰세요.- 워크스페이스에서 수락되는 Job은 동시성 한도에 큐 용량을 더한 수까지입니다. 그 이상이면 제출이
429 queue_full로 응답합니다.
출처
관련 글
개발자 카테고리의 다른 글
- AI 이미지 대량 생성 API: 스크립트로 수백 장 만들기
행마다 이미지 요청을 하나씩 보내되, 요청마다 고유한 Idempotency-Key와 async 모드를 쓰고 호출당 최대 네 장을 요청하세요. 속도는 요금제의 동시성이 정합니다.
- 여러 사람이 같은 API 키를 써도 되나요?
쓸 수는 있지만, 그러면 키의 요청 한도와 사용 기록, 폐기까지 함께 나누게 됩니다. 사람이나 서비스마다 키를 따로 주고, 그래도 공유되는 것이 무엇인지 알아 두세요.
- Python으로 말하는 아바타 만들기: Sume API 활용
Python Requests로 말하는 아바타를 만드세요. 아바타를 생성하고 Job을 폴링한 뒤, 말할 스크립트를 보내고 완성된 영상의 URL을 읽습니다.
- AI 생성 영상 URL은 만료되나요? Sume의 결과물 보관 방식
Format 실행과 Agent Completions에서는 만료되지 않습니다. Sume는 그 미디어를 만료되지 않는 media.sume.com URL로 돌려주며, 링크를 가진 누구나 열 수 있습니다.
작성자 Sume