202 Accepted와 200 OK의 차이: 작업이 끝났나요?

200 OK는 요청이 성공했고 결과가 담겼다는 뜻이고, 202 Accepted는 작업을 접수했지만 아직 끝나지 않았다는 뜻입니다. 영상 API에서는 본문의 상태를 확인하세요.

읽는 시간 5분Sume
전체 글

200 OK는 요청이 성공했고 응답에 그 결과가 담겨 있다는 뜻입니다. 202 Accepted는 서버가 요청을 처리하려고 접수했지만 아직 끝내지 않았고 시작하지 않았을 수도 있다는 뜻이므로, 결과는 나중에 상태 URL이나 웹훅으로 알게 됩니다. 영상을 생성하는 API에서는 어느 코드도 영상이 준비됐다는 증거로 여기지 말고, 응답 본문의 상태 필드를 확인하세요.

HTTP 정의는 MDN의 202 Accepted와 200 OK 페이지에서 인용했고, Sume의 동작은 Job과 결과 (영문), Format 호출하기 (영문), 이미지 API (영문) 문서에서 가져왔습니다. 모두 2026-09-27에 확인했습니다.

202 Accepted는 무슨 뜻인가요?

MDN은 202를 확정하지 않는(non-committal) 응답이라고 부릅니다. 요청은 처리하려고 접수됐지만 처리는 여전히 실패하거나 거부될 수 있고, HTTP에는 나중에 결과를 두 번째 응답으로 보낼 방법이 없습니다. 그래서 202로 응답하는 API는 후속 확인에 쓸 무언가를 함께 돌려줍니다. MDN의 예시는 작업 ID와 모니터링할 URL을 반환합니다.

Sume의 생성 Job이 이렇게 동작합니다. 기본값인 async 모드와 webhook 모드는 Job 봉투와 폴링 URL을 담아 202로 응답하며, 모든 모드가 첫 응답에 Job ID를 돌려줍니다. 문서의 표현대로 2xx는 Job이 존재하고 유료 작업이 진행 중이라는 뜻이지, Job이 끝났다는 뜻이 아닙니다. POST /v1/videos도 비동기입니다. 문서에 나온 제출 응답은 Job ID와 폴링 URL이 담긴 202 Accepted입니다.

API는 언제 202 대신 200을 반환하나요?

작업이 요청 안에서 끝났을 때, 또는 새로 일어날 일이 없었을 때입니다. Sume에서는 호출에 따라 두 경우가 모두 나타납니다. 제출 모드 자체는 영상 생성 API 동기 vs 비동기에서 다룹니다.

이미지 API (영문), Timeline 1.0, Format 호출하기 (영문), 고급: API로 스케줄 실행하기, 대량 실행 기준, 2026-09-27 확인.
호출202의 의미200의 의미
POST /v1/images30초 대기가 끝났을 때 아직 실행 중이었거나, mode: "async"를 보냈거나, webhook_url과 함께 "webhook"을 보낸 경우. Job 봉투응답에 담긴 완성된 이미지
mode: "sync"로 요청한 Timeline 렌더30초 안에 끝나지 않음. 폴링하기완료된 Job
POST /v1/formats/{handle}/{slug}/runs새 실행같은 Idempotency-Key와 본문의 재전송. idempotency_hit: true와 함께 원래 실행
POST /v1/actions/{action_id}/runs실행이 접수되어 시작됨재전송, 또는 다른 실행이 활성이라 건너뛴 실행
POST /v1/formats/{handle}/{slug}/bulk-runs새 큐, 그리고 같은 키와 페이로드의 재전송재전송에는 쓰이지 않음. 대량 실행 재전송은 202 그대로

200이면 영상이 준비된 건가요?

실행 생성에서는 아닙니다. Format 실행 재전송은 원래 실행의 영수증과 함께 200을 반환하고, 스케줄의 200은 재전송이거나 건너뛴 실행입니다. 코드만으로는 영상이 존재하는지 결코 알 수 없습니다. 스케줄 문서는 분명하게 말합니다. 200은 작업이 끝났다는 뜻이 아니므로, HTTP 상태가 아니라 영수증의 status 필드로 분기하세요.

이미지 엔드포인트에서는 코드 자체가 무엇을 받았는지 알려 줍니다. 200은 이미지 응답이고 202는 Job 봉투이므로, 본문 형태가 아니라 상태 코드를 확인하세요. 4K, 높은 quality, 큰 n처럼 느린 설정일수록 202로 돌아올 가능성이 큽니다. 4K 요청이 202를 반환하는 이유를 참고하세요.

const res = await fetch("https://api.sume.com/v1/images", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SUME_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ model: "sume/auto", prompt: "a red panda astronaut" }),
});
const body = await res.json();
if (res.status === 200) {
  console.log(body.data[0].url); // the finished image
} else if (res.status === 202) {
  console.log(body.data.status_url); // a job envelope: poll this
}

202를 받은 뒤 코드는 무엇을 해야 하나요?

202는 결과가 아니라 영수증으로 다루세요.

  • 첫 응답의 ID를 저장하세요. 모든 모드가 ID를 돌려주며, 재시작한 뒤 연동 코드가 작업을 되찾는 수단이 바로 이 ID입니다.
  • 백오프하며 폴링하세요. Job 봉투라면 terminal이 true가 될 때까지 status_url을 폴링하고(next_poll_after_seconds가 있으면 그 값을 따르세요), result_ready가 true가 되면 result_url을 읽으세요. POST /v1/videos는 대신 polling_url을 줍니다. 루프 코드는 영상 생성 Job 상태 API 폴링하기에 있습니다.
  • 또는 제출할 때 웹훅 URL(생성 Job에는 webhook_url, POST /v1/videos에는 callback_url)을 보내고 종료 콜백을 기다리되, 폴링은 백업으로 유지하세요.
  • 대기 시간이 끝났다고 다시 제출하지 마세요. 클라이언트 쪽 타임아웃은 Job을 취소하지 않으며, Job은 계속 실행되고 계속 과금됩니다. 제출을 꼭 재시도해야 한다면 같은 Idempotency-Key를 재사용해 재시도가 원래 Job을 돌려받게 하세요.
  • 실패는 상태 줄이 아니라 영수증에서 확인하세요. Format 실행에서 202가 나중에 생성 오류로 바뀌는 일은 없으며, 실패는 영수증에 status: "failed"로 도착합니다.

출처

관련 글

개발자 카테고리의 다른 글

개발자 글 전체 보기

작성자 Sume