---
title: Generation admission
description: Sume가 유료 생성 Job을 수락하고, 워크스페이스 동시성을 적용하며, 작업을 큐에 넣고, 큐 상태를 보고하는 방식을 살펴보세요.
---

Sume 생성 API는 오래 걸리는 유료 작업에 queue-first admission을 씁니다. 제출 요청은
요청이 유효하고, 잔액을 예약할 수 있으며, 워크스페이스에 수락된 Job 용량이 남아 있을
때 내구성 있는 Job을 만듭니다. Job은 즉시 시작되거나, 워크스페이스 동시성 슬롯이
열릴 때까지 `queued`에서 기다릴 수 있습니다.

```text
submit
  -> queued
  -> processing
  -> completed | failed | canceled
```

동시성은 디스패치 한도이며 제출 한도가 아닙니다. 워크스페이스가 이미 생성 동시성
한도에 있어도, 큐 용량이 남아 있으면 Sume는 더 많은 Job을 `queued`로 수락할 수
있습니다. 워커는 이후 워크스페이스별 동시성 가드 아래에서 queued Job을
`processing`으로 옮깁니다.

## 한눈에 보는 한도

Sume는 혼동하기 쉬운 네 가지 제어를 분리합니다.

| Control | Applies to | What happens when full |
|---|---|---|
| Generation concurrency | 상태가 `processing`인 유료 생성 Job입니다. | 큐 용량이 남아 있으면 새 유효 Job을 여전히 `queued`로 수락할 수 있습니다. |
| Queue capacity | 수락되었지만 아직 processing이 아닌 유료 생성 Job입니다. | 새 유료 생성 제출은 `429 queue_full`로 실패합니다. |
| Submit rate limits | 공개 API 제출 엔드포인트의 요청량입니다. | 요청은 `429 rate_limited`로 실패합니다. backoff와 멱등성 키로 재시도하세요. |
| Balance and reservation | 인증된 워크스페이스의 사용 가능 USD 잔액입니다. | provider 작업이 시작되기 전에 생성 제출이 `402 insufficient_credits`로 실패합니다. |

읽기/상태/목록 엔드포인트에도 rate limit이 있을 수 있습니다. 생성 동시성이 아니라
폴링 백프레셔로 취급하세요.

## 플랜 동시성(소스 오브 트루스)

생성 동시성은 **플랜만**입니다. 선불 충전은 processing 동시성 한도를 **올리지
않습니다**. Admin override는 유효 `concurrency_limit`을 올릴 수 있습니다
(`limit_source: admin_override`). 큐 용량 기본값은
`max(3, concurrency_limit × 5)`입니다.

| Plan | Processing concurrency | Queue capacity (default) | Accepted job capacity |
|---|---:|---:|---:|
| Free | 1 | 5 | 6 |
| Pro | 2 | 10 | 12 |
| Startup | 4 | 20 | 24 |
| Scale | 10 | 50 | 60 |
| Enterprise | 10 | 50 | 60 |

정적 표보다 유효 `generation_limits.concurrency_limit` 필드를 항상 선호하세요.
`accepted job capacity`는 `concurrency_limit + queued_jobs_limit`이며 — 같은
시점에 워크스페이스에서 `processing` 또는 `queued`일 수 있는 유료 생성 Job의
최대 수입니다.

## Queue-first 동작

워크스페이스의 `concurrency_limit`이 `1`이어도 유효한 Job을 여러 개 제출할 수
있습니다. 잔액과 큐 용량이 있으면 Sume는 모두 `queued`로 반환할 수 있습니다.
같은 워크스페이스의 생성 Job은 한 번에 하나만 `processing`으로 옮겨져야 합니다.

이것이 의도된 동작입니다.

```text
Job A: queued -> processing -> completed
Job B: queued -------------> processing -> completed
Job C: queued ---------------------------> processing -> completed
```

`queued`를 실패로 취급하지 마세요. `job_id`를 저장하고, backoff로 상태를 폴링하며,
Job이 `result_ready: true` 또는 `status: completed`를 보고할 때만 결과를
가져오세요.

## 즉시 거절

Sume는 요청을 안전하게 수락할 수 없을 때만 즉시 거절합니다.

| Status | Code | Why it happens | Client behavior |
|---|---|---|---|
| `400` | `invalid_request` | 요청 본문, 모델 id 형태, mode, 웹훅 옵션, 헤더가 유효하지 않습니다. | 재시도하기 전에 요청을 고치세요. |
| `401` | `unauthorized` | API 키가 없거나, 형식이 잘못되었거나, 폐기되었거나, 유효하지 않습니다. | 인증을 고치세요. |
| `402` | `insufficient_credits` | Sume가 워크스페이스 잔액에서 예상 생성 비용을 예약할 수 없습니다. | 플랜을 업그레이드하거나 포함 Gen$를 기다리거나, 더 저렴한 요청을 제출하세요. 선불 충전을 지어내지 마세요. |
| `404` | `model_not_found` 또는 `not_found` | 이 워크스페이스에 공개 모델이나 리소스가 없습니다. | `/v1/catalog`를 쓰거나 id를 확인하세요. |
| `409` | `idempotency_conflict` | 같은 멱등성 키가 다른 작업이나 페이로드에 재사용되었습니다. | 정확한 재시도에만 키를 재사용하세요. |
| `429` | `queue_full` | 워크스페이스에 남은 수락 생성 용량이 없습니다. | Job이 끝나거나 queued Job을 취소한 뒤, 같은 멱등성 키로 재시도하세요. |
| `429` | `rate_limited` | API 요청량이 남용 방지 한도를 넘었습니다. | 있으면 `retry-after`로 backoff하세요. |
| `503` | `provider_capacity_exceeded` 또는 런타임 구성 오류 | Sume가 생성 작업을 안전하게 시작하거나 디스패치할 수 없습니다. | 오류가 재시도하지 말라고 하지 않는 한, 같은 멱등성 키로 나중에 재시도하세요. |

동시성이 가득 찬 것 자체는 오류가 아닙니다. 큐도 가득 찼을 때만 제출 오류가
됩니다.

## `generation_limits`

Sume가 워크스페이스 admission 스냅샷을 계산할 수 있으면 생성 제출 응답에
`generation_limits`가 포함됩니다.

```json
{
  "generation_limits": {
    "plan_id": "pro",
    "limit_source": "plan",
    "plan_concurrency_limit": 2,
    "concurrency_limit": 2,
    "queued_jobs_limit": 10,
    "accepted_generation_jobs_limit": 12,
    "active_generation_jobs": 0,
    "queued_generation_jobs": 0,
    "queue_capacity_remaining": 12
  }
}
```

필드 의미:

| Field | Meaning |
|---|---|
| `plan_id` | 기본 동시성 맵을 정하는 구독 플랜입니다. |
| `limit_source` | 유효 동시성에 대한 `plan` 또는 `admin_override`입니다. |
| `plan_concurrency_limit` | 플랜 기본 processing 동시성입니다(override 시 wave sizing에는 무시하세요). |
| `concurrency_limit` | 같은 워크스페이스에서 `processing`일 수 있는 유료 생성 Job의 **유효** 최대값입니다. |
| `queued_jobs_limit` | `queued`에서 기다릴 수 있는 추가 같은 워크스페이스 유료 생성 Job입니다. |
| `accepted_generation_jobs_limit` | `concurrency_limit + queued_jobs_limit`입니다. |
| `active_generation_jobs` | 상태가 `processing`인 현재 같은 워크스페이스 생성 Job입니다. |
| `queued_generation_jobs` | 상태가 `queued`인 현재 같은 워크스페이스 생성 Job입니다. |
| `queue_capacity_remaining` | `queue_full` 전까지 남은 수락 Job 슬롯입니다. |

수는 스냅샷입니다. 워커가 Job을 가져가거나 다른 클라이언트가 작업을 제출하면
응답 직후에도 바뀔 수 있습니다.

## 대량 제출 전

런치 연동에서는 `GET /v1/balance`와 생성 제출 응답의 `generation_limits`로
보수적인 큐 결정을 하세요. 이후 라이브 OpenAPI가 환경에 읽기 전용 admission
preview 엔드포인트를 노출하면, 선택적 preflight로만 취급하세요. Job을 만들거나,
크레딧을 예약·확정·환불하거나, 생성 provider를 호출해서는 안 됩니다.

## 제출과 폴링 패턴

프로덕션 연동에서는 멱등성 키와 함께 비동기 제출을 선호하세요.

```bash
curl -X POST https://api.sume.com/v1/avatar-1.0/generate \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: avatar-batch-001-item-001" \
  -d '{
    "avatar_handle": "studio_presenter",
    "input": {
      "type": "prompt",
      "prompt": "Friendly studio presenter"
    },
    "mode": "async"
  }'
```

이어서 상태 폴링:

```bash
curl https://api.sume.com/v1/jobs/job_123/status \
  -H "Authorization: Bearer $SUME_API_KEY"
```

완료 후 결과 가져오기:

```bash
curl https://api.sume.com/v1/jobs/job_123/result \
  -H "Authorization: Bearer $SUME_API_KEY"
```

권장 클라이언트 동작:

- `queued`와 `processing`을 정상적인 비종료 상태로 취급하세요.
- 폴링에 exponential backoff를 쓰세요. 많은 Job에 걸친 촘촘한 루프는 피하세요.
- `terminal: true`가 되거나 자체 애플리케이션 deadline까지 폴링하세요.
- 재시도될 수 있는 모든 유료 제출에 `Idempotency-Key`를 쓰세요.
- 로컬 워커가 타임아웃했다고 유료 요청을 다시 제출하지 마세요.
- 있으면 `status_url`, `result_url`, `events_url`, `cancel_url`을 저장하세요.
- `generation_limits`를 확인하고 큐 용량이 낮으면 작업을 추가하지 마세요.

Sume CLI도 같은 모델을 따릅니다.

```bash
sume avatars create --confirm-paid --avatar-handle studio_presenter --type prompt --prompt "Friendly studio presenter" --json
sume jobs status job_123 --agent --json
sume jobs result job_123 --agent --json
sume jobs events job_123 --agent --json
```

## Queue-full 처리

`queue_full`은 워크스페이스가 수락된 생성 용량을 모두 소진했다는 뜻입니다.

```json
{
  "error": {
    "code": "queue_full",
    "message": "Workspace generation queue is full. Wait for running jobs to complete before submitting more generation work.",
    "request_id": "req_..."
  }
}
```

오류 details에는 실패한 admission 시도에 대한 `generation_limits` 스냅샷과 Job
메타데이터가 포함될 수 있습니다. Sume는 해당될 때 실패한 admission의 예약을
해제하거나 환불합니다.

`queue_full`을 받으면:

- 그 워크스페이스에 생성 작업을 더 추가하지 마세요;
- 기존 Job을 폴링해 최소 하나가 종료 상태에 도달할 때까지 기다리세요;
- 더 이상 필요 없는 queued Job을 취소하세요;
- 용량이 열린 뒤 같은 멱등성 키로 재시도하세요;
- 있으면 `retry-after`를 쓰세요.

## 취소와 빌링

유료 생성은 공개 Sume USD 추정치를 씁니다. 제출 시 요청이 수락되면 Sume가 예상
금액을 예약합니다. 성공적 완료는 예약된 사용량을 확정합니다. 실패한 Job과 실패한
큐 admission은 해당될 때 예약을 해제하거나 환불합니다.

취소는 아직 `queued` 또는 `processing`인 Job에 사용할 수 있습니다.

```bash
curl -X POST https://api.sume.com/v1/jobs/job_123/cancel \
  -H "Authorization: Bearer $SUME_API_KEY"
```

더 이상 필요 없는 queued Job은 processing이 시작되기 전에 취소하세요. Job이 이미
`processing`이면 취소는 best-effort이며, Job은 여전히 정상적으로 완료되거나 실패할
수 있습니다.

## 엣지 케이스와 현재 경계

- Sume는 현재 큐 수와 남은 수락 용량을 노출하며, Job별 정확한 큐 위치나 ETA는
  노출하지 않습니다.
- `sync`와 `subscribe` 모드는 최대 30초까지 기다릴 수 있습니다. 대기 예산이
  소진되면 job id를 계속 폴링하세요.
- 큐 만료와 클라이언트가 명시한 fail-fast 큐 길이는 현재 공개 API 옵션이
  아닙니다. 라이브 OpenAPI 스키마에 나타나기 전에는 미래 계약 추가분으로
  취급하세요.
- 공개 API 응답은 provider-neutral입니다. 숨겨진 provider 이름, 원본 provider
  task id, 원본 provider URL, 내부 워크플로 이름, 스토리지 오브젝트 키, API 키,
  비공개 워크스페이스/사용자 메타데이터를 노출하지 않습니다.
