> ## Documentation Index
> Fetch the complete documentation index at: https://studio-docs.thezet.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 작업 흐름

> 시작부터 결과를 받기까지의 흐름이에요.

이미지와 영상은 만드는 데 시간이 걸려서, 요청하면 작업을 먼저 받고 결과는 나중에 조회해요.

1. `POST /estimate`로 가격을 확인해요. 건너뛰어도 돼요.
2. `POST /generations`로 시작하면 `202`와 작업 `id`가 와요.
3. `GET /generations/{id}`를 `terminal`이 `true`가 될 때까지 조회해요.
4. `status`가 `succeeded`면 `outputs[].url`에서 결과를 받아요.

## 작업 상태

| `status` | 뜻 | `terminal` |
| - | - | - |
| `queued` | 시작을 기다려요. 이때만 취소할 수 있어요. | `false` |
| `running` | 만들고 있어요. | `false` |
| `succeeded` | 끝났어요. `outputs`에 결과가 있고 금액이 청구돼요. | `true` |
| `failed` | 실패했어요. `error`에 이유가 있고 금액은 돌려드려요. | `true` |
| `canceled` | 취소했어요. 금액은 돌려드려요. | `true` |

## 얼마나 자주 조회할까요

이미지는 3초, 영상은 10초에 한 번이면 충분해요. `terminal`이 `true`가 될 때까지 조회하고, 그동안 같은 작업을 다시 시작하지 마세요. 조회는 요금이 들지 않아요.

[웹훅](https://studio-docs.thezet.io/webhooks.md)을 등록하면 조회하지 않아도 작업이 끝날 때 알려드려요.

## 전체 예시

```typescript TypeScript theme={null}
const API = "https://api.studio.thezet.io/v1";
const headers = { Authorization: `Bearer ${process.env.ZET_API_KEY}` };

async function generate(body: object, idempotencyKey: string) {
  const started = await fetch(`${API}/generations`, {
    method: "POST",
    headers: { ...headers, "Content-Type": "application/json", "Idempotency-Key": idempotencyKey },
    body: JSON.stringify(body),
  });
  let job = await started.json();
  if (!started.ok) throw new Error(`${job.error.code}: ${job.error.message}`);

  while (!job.terminal) {
    await new Promise((resolve) => setTimeout(resolve, 5_000));
    job = await (await fetch(`${API}/generations/${job.id}`, { headers })).json();
  }
  if (job.status !== "succeeded") throw new Error(`${job.error?.code ?? job.status}`);
  return job.outputs;
}
```

```python Python theme={null}
import os, time
import requests

API = "https://api.studio.thezet.io/v1"
headers = {"Authorization": f"Bearer {os.environ['ZET_API_KEY']}"}

def generate(body: dict, idempotency_key: str) -> list:
    started = requests.post(
        f"{API}/generations",
        headers={**headers, "Idempotency-Key": idempotency_key},
        json=body,
    )
    job = started.json()
    if not started.ok:
        raise RuntimeError(f"{job['error']['code']}: {job['error']['message']}")

    while not job["terminal"]:
        time.sleep(5)
        job = requests.get(f"{API}/generations/{job['id']}", headers=headers).json()

    if job["status"] != "succeeded":
        raise RuntimeError(job["error"]["code"] if job["error"] else job["status"])
    return job["outputs"]
```

## 취소

`POST /generations/{id}/cancel`로 시작 전인 작업을 취소하고 금액을 돌려받아요. 이미 시작했다면 `409 generation_not_cancelable`이고, 그 작업은 끝까지 진행돼요. 다시 호출해도 괜찮아요.

## 목록

`GET /generations`로 API로 만든 작업을 최신순으로 받아요. 사이트에서 만든 작업은 나오지 않고, 반대로 API 작업도 사이트 기록에 나오지 않아요. 잔액과 동시 실행 한도는 함께 써요.

| 쿼리 | 뜻 |
| - | - |
| `limit` | 한 번에 받을 개수예요. 1\~100, 기본 20이에요. |
| `cursor` | 이전 응답의 `next_cursor`를 넣으면 다음 페이지를 줘요. |
| `status` | 이 상태인 작업만 받아요. |
| `model` | 이 모델의 작업만 받아요. |

## 결과 다시 쓰기

`prompt`와 `outputs[].id`는 다음 작업에 그대로 쓸 수 있어요. 영상으로 바꾸거나 고칠 때 결과를 입력으로 넣으면 돼요. 자세한 내용은 [입력 파일](https://studio-docs.thezet.io/uploads.md)을 봐 주세요.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.