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

# 프롬프트 실행하기

> 프롬프트 등록부터 실행 요청, 완료 폴링까지 — 비동기 수집 파이프라인

프롬프트 실행은 비동기로 동작합니다. 제출하면 `runID`가 즉시 반환되고, 수집은 백그라운드에서 진행됩니다. 완료 여부는 폴링으로 확인합니다.

## 1. 프롬프트 준비

프롬프트는 반드시 프롬프트 세트에 속하므로, 세트를 먼저 만듭니다.

```bash theme={null}
curl -X POST "https://dev-platform-api.trychainshift.ai/api/v1beta/platform/prompt-sets" \
  -H "API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "중고차 GEO 모니터링"}'
```

```json theme={null}
{ "id": "Jix75RbQ2gfTB0qzlh125g" }
```

반환된 세트 ID로 프롬프트를 등록합니다. 프롬프트는 실제 사용자가 AI에 물어볼 법한 질문 그대로 씁니다. 여러 개를 한 번에 등록하려면 `POST /prompts/bulk`(최대 100개)를 사용하세요.

```bash theme={null}
curl -X POST "https://dev-platform-api.trychainshift.ai/api/v1beta/platform/prompts" \
  -H "API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "promptSetID": "Jix75RbQ2gfTB0qzlh125g",
    "content": "2000만원대 중고 SUV 추천해줘"
  }'
```

```json theme={null}
{ "id": "W-KMZMXwDB7ihFtj5CMHSQ" }
```

## 2. 실행 요청

프롬프트 지정 방법은 두 가지이며, **정확히 하나만** 사용해야 합니다.

* `promptIDs` — 개별 프롬프트 ID 목록 (1\~500개)
* `promptSetID` — 세트에 속한 모든 프롬프트를 실행

<CodeGroup>
  ```bash 세트로 제출 theme={null}
  curl -X POST "https://dev-platform-api.trychainshift.ai/api/v1beta/platform/runs" \
    -H "API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "promptSetID": "Jix75RbQ2gfTB0qzlh125g",
      "models": ["CHATGPT", "PERPLEXITY", "GEMINI", "NAVER_AI_BRIEFING", "NAVER_AI_TAB"],
      "repeatCount": 5
    }'
  ```

  ```bash 개별 프롬프트로 제출 theme={null}
  curl -X POST "https://dev-platform-api.trychainshift.ai/api/v1beta/platform/runs" \
    -H "API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "promptIDs": ["W-KMZMXwDB7ihFtj5CMHSQ"],
      "models": ["CHATGPT", "PERPLEXITY"]
    }'
  ```
</CodeGroup>

```json theme={null}
{ "runID": "GULjgaLy-DjX9NAVxjZBFg" }
```

| 파라미터          | 필수 | 설명                                              |
| ------------- | -- | ----------------------------------------------- |
| `models`      | 필수 | 실행할 AI 모델 1\~20개. 사용 가능한 값은 [지원 모델](/models) 참고 |
| `promptIDs`   | 택일 | 실행할 프롬프트 ID 1\~500개                             |
| `promptSetID` | 택일 | 세트 전체 실행. 빈 세트는 `PROMPT_SET_EMPTY` 에러           |
| `region`      | 선택 | 답변을 수집할 지역. 생략 시 `KR`                           |
| `repeatCount` | 선택 | 프롬프트 × 모델 조합당 반복 횟수 (1\~100). 생략 시 1            |

<Note>
  AI 답변은 실행마다 달라지므로, 언급률처럼 비율로 보는 지표는 `repeatCount`를 2 이상으로 두어야 의미가 있습니다. 1회 실행 결과는 답변 내용·인용 출처를 눈으로 확인할 때 쓰세요.
</Note>

<Info>
  총 실행 수(프롬프트 수 × 모델 수 × `repeatCount`)는 실행 요청 하나당 10,000개를 넘을 수 없습니다. 초과하면 `RUN_TOO_MANY_TASKS` 에러가 반환됩니다. 과금 방식은 [Rate Limit & 크레딧](/rate-limit)을 참고하세요.
</Info>

## 3. 완료 폴링

`status`가 `FINISHED`가 될 때까지 조회합니다. 수집은 보통 수 분이 걸리므로 30초 정도 간격의 폴링을 권장합니다.

```bash theme={null}
curl -H "API-Key: YOUR_API_KEY" \
  "https://dev-platform-api.trychainshift.ai/api/v1beta/platform/runs/GULjgaLy-DjX9NAVxjZBFg"
```

아래는 실제 수집 응답입니다(`answers` 배열은 두 건만 남겼습니다).

```json theme={null}
{
  "runID": "GULjgaLy-DjX9NAVxjZBFg",
  "status": "FINISHED",
  "totalCount": 100,
  "finishedCount": 100,
  "successCount": 63,
  "failedCount": 37,
  "runningCount": 0,
  "answers": [
    {
      "promptID": "RWWJZHPxJ0QEroVpj-3yDQ",
      "model": "PERPLEXITY",
      "region": "KR",
      "query": "중고차 직거래랑 딜러 거래 중에 뭐가 나아?",
      "status": "SUCCESS"
    },
    {
      "promptID": "W-KMZMXwDB7ihFtj5CMHSQ",
      "model": "NAVER_AI_TAB",
      "region": "KR",
      "query": "2000만원대 중고 SUV 추천해줘",
      "status": "FAILED"
    }
  ]
}
```

응답을 읽는 법:

* 진행 중에는 `status`가 `RUNNING`이고 `runningCount`가 남은 실행 수를 보여줍니다. 두 값이 `FINISHED` / `0`이 되면 수집이 끝난 것입니다.
* **개별 실행이 실패해도 실행 요청은 `FINISHED`로 끝납니다.** 위 예시는 100개 실행 중 37개가 실패한 실제 사례입니다 — 특정 모델이 일시적으로 응답하지 않는 일은 드물지 않습니다.
* `answers` 항목은 실행별 진행 상태(`PENDING`/`SUCCESS`/`FAILED`)만 담습니다. 답변 본문은 다음 단계의 답변 API로 가져옵니다.

<Warning>
  실패한 실행(`FAILED`)은 답변이 생성되지 않으며, 크레딧도 차감되지 않습니다. 재수집이 필요하면 해당 프롬프트로 다시 실행을 요청하세요.
</Warning>

<Note>
  AI 답변은 비결정적입니다. 같은 프롬프트 × 모델 조합도 실행마다 내용과 출처가 달라질 수 있습니다. 브랜드 노출률처럼 확률적인 지표를 측정할 때는 `repeatCount`로 같은 조합을 반복 실행하세요.
</Note>

### 폴링 루프 예시

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

  API = "https://dev-platform-api.trychainshift.ai/api/v1beta/platform"
  HEADERS = {"API-Key": os.environ["CHAINSHIFT_API_KEY"]}

  run_id = requests.post(f"{API}/runs", headers=HEADERS, json={
      "promptSetID": "Jix75RbQ2gfTB0qzlh125g",
      "models": ["CHATGPT", "PERPLEXITY"],
  }).json()["runID"]

  while True:
      status = requests.get(f"{API}/runs/{run_id}", headers=HEADERS).json()
      if status["status"] == "FINISHED":
          break
      time.sleep(30)

  answers = requests.get(f"{API}/answers", headers=HEADERS,
                         params={"runID": run_id, "status": "SUCCESS"}).json()
  ```

  ```javascript JavaScript theme={null}
  const API = "https://dev-platform-api.trychainshift.ai/api/v1beta/platform";
  const headers = { "API-Key": process.env.CHAINSHIFT_API_KEY, "Content-Type": "application/json" };

  const { runID } = await (await fetch(`${API}/runs`, {
    method: "POST",
    headers,
    body: JSON.stringify({ promptSetID: "Jix75RbQ2gfTB0qzlh125g", models: ["CHATGPT", "PERPLEXITY"] }),
  })).json();

  let status;
  do {
    await new Promise((r) => setTimeout(r, 30_000));
    status = await (await fetch(`${API}/runs/${runID}`, { headers })).json();
  } while (status.status !== "FINISHED");

  const answers = await (await fetch(`${API}/answers?runID=${runID}&status=SUCCESS`, { headers })).json();
  ```
</CodeGroup>

## 4. 답변 가져오기

수집이 끝나면 답변 본문과 출처를 조회합니다.

```bash theme={null}
curl -H "API-Key: YOUR_API_KEY" \
  "https://dev-platform-api.trychainshift.ai/api/v1beta/platform/answers?runID=GULjgaLy-DjX9NAVxjZBFg"
```

필터와 응답 구조는 [답변 수집하기](/guides/collecting-answers)를 참고하세요.

## 에러 케이스

```json theme={null}
{
  "code": "RUN_PROMPT_TARGET_REQUIRED",
  "message": "promptIDs 또는 promptSetID 중 정확히 하나를 지정해야 합니다"
}
```

| 코드                               | HTTP | 원인                                          |
| -------------------------------- | ---- | ------------------------------------------- |
| `RUN_PROMPT_TARGET_REQUIRED`     | 400  | `promptIDs`·`promptSetID`를 둘 다 생략했거나 둘 다 지정 |
| `RUN_TOO_MANY_TASKS`             | 400  | 총 실행 수가 10,000개 초과                          |
| `PROMPT_SET_EMPTY`               | 400  | 빈 프롬프트 세트로 제출                               |
| `MODEL_NOT_SUPPORTED`            | 400  | 지원하지 않는 모델 값                                |
| `REGION_NOT_SUPPORTED_FOR_MODEL` | 400  | 해당 모델이 지원하지 않는 지역                           |
| `INSUFFICIENT_CREDITS`           | 402  | 크레딧 잔액 부족                                   |

## 운영 팁

* 실행 목록은 `GET /runs`로 최신순 조회합니다(페이지 크기 최대 10).
* 같은 프롬프트를 정기적으로 수집하려면 세트를 만들어 두고 `promptSetID`로 반복 제출하는 방식이 간단합니다.
* 모델별 fan-out 지원 여부 등 수집 특성은 [지원 모델](/models)에서 확인하세요.
