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

# Running prompts

> From registering prompts to submitting a run request and polling for completion: the asynchronous collection pipeline

Runs are asynchronous. When you submit one, a `runID` is returned immediately and collection proceeds in the background. You check for completion by polling.

## 1. Prepare prompts

Every prompt must belong to a prompt set, so create the set first.

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

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

Register prompts using the returned set ID. Write each prompt exactly as a real user would ask an AI. To register several at once, use `POST /prompts/bulk` (up to 100). The example below uses a Korean prompt asking for used SUV recommendations under 20M KRW.

```bash theme={null}
curl -X POST "https://platform-api.trychainshift.ai/api/v1/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. Submit a run request

There are two ways to specify prompts, and you must use **exactly one**.

* `promptIDs`: a list of individual prompt IDs (1 to 500)
* `promptSetID`: runs every prompt in the set

```bash Submit by set theme={null}
curl -X POST "https://platform-api.trychainshift.ai/api/v1/platform/runs" \
  -H "API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "promptSetID": "Jix75RbQ2gfTB0qzlh125g",
    "models": ["CHATGPT", "GOOGLE_OVERVIEW", "GEMINI", "NAVER_AI_BRIEFING", "NAVER_AI_TAB"],
    "repeatCount": 5
  }'
```

```bash Submit by individual prompts theme={null}
curl -X POST "https://platform-api.trychainshift.ai/api/v1/platform/runs" \
  -H "API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "promptIDs": ["W-KMZMXwDB7ihFtj5CMHSQ"],
    "models": ["CHATGPT", "GEMINI"]
  }'
```

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

| Parameter | Required | Description |
| - | - | - |
| `models` | Required | AI models to run. Use only values listed in [Supported models](https://docs.trychainshift.ai/en/models.md). At least 1; duplicates count once |
| `promptIDs` | One of two | 1 to 500 prompt IDs to run |
| `promptSetID` | One of two | Runs the whole set. An empty set returns the `PROMPT_SET_EMPTY` error |
| `region` | Optional | Region to collect answers from. `KR` if both are omitted; the location's country if only `location` is set. Supported regions differ by model; see [Supported models](https://docs.trychainshift.ai/en/models.md#supported-regions) |
| `location` | Optional | Location to collect answers from (a city within a country, for example `US-NEW_YORK`). If omitted, collection happens at the `region` level. See [Supported models](https://docs.trychainshift.ai/en/models.md#supported-locations) |
| `repeatCount` | Optional | Number of repetitions per prompt × model combination (1 to 100). Defaults to 1 |

> [!NOTE]
>
> AI answers vary from run to run, so ratio-based metrics such as mention rate
> are only meaningful with `repeatCount` set to 2 or higher. Use a single run
> when you want to inspect answer content and sources by eye.

> [!NOTE]
>
> The total number of runs (prompts × models × `repeatCount`) cannot exceed
> 10,000 per run request. Exceeding it returns the `RUN_TOO_MANY_TASKS` error.
> For billing details, see [Credits](https://docs.trychainshift.ai/en/guides/credits.md).

### Collecting at the location level

To collect at the city level, which is narrower than `region`, specify `location`. If you omit both `region` and `location`, collection happens in `KR`. If you specify only `location`, the country that location belongs to becomes the `region`. If you specify both, the location must belong to that region. Only ChatGPT and Perplexity support locations, so including any other model in `models` rejects the entire request.

```bash theme={null}
curl -X POST "https://platform-api.trychainshift.ai/api/v1/platform/runs" \
  -H "API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "promptSetID": "Jix75RbQ2gfTB0qzlh125g",
    "models": ["CHATGPT"],
    "location": "US-NEW_YORK"
  }'
```

Query the available location codes with [List supported locations](https://docs.trychainshift.ai/en/api-reference/discovery/list-locations.md).

### Using models that require an agreement

`PERPLEXITY` and `CLAUDE` are available only to organizations with a separate agreement. If an organization without the grant includes them in `models`, the entire request is rejected with `403` (`MODEL_NOT_GRANTED`). To check whether you have the grant, see whether the model appears in the [List supported models](https://docs.trychainshift.ai/en/api-reference/discovery/list-models.md) response.

```bash theme={null}
curl -X POST "https://platform-api.trychainshift.ai/api/v1/platform/runs" \
  -H "API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "promptSetID": "Jix75RbQ2gfTB0qzlh125g",
    "models": ["CHATGPT", "PERPLEXITY"]
  }'
```

## 3. Poll for completion

Poll until `status` becomes `FINISHED`. Collection usually takes a few minutes, so an interval of about 30 seconds is recommended.

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

Below is a real collection response (the `answers` array is trimmed to two entries).

```json theme={null}
{
  "iD": "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"
    }
  ]
}
```

How to read the response:

* While in progress, `status` is `RUNNING` and `runningCount` shows how many runs remain. Once they become `FINISHED` / `0`, collection is complete.
* **A run request ends as `FINISHED` even if individual runs fail.** The example above is a real case where 37 of 100 runs failed. It is not unusual for a particular model to stop responding temporarily.
* Each `answers` entry only carries the per-run status (`PENDING`/`SUCCESS`/`FAILED`). You fetch the answer body with the answers API in the next step.

> [!WARNING]
>
> Failed runs (`FAILED`) produce no answer and consume no credits. If you need
> to collect again, submit a new run request with the same prompts.

> [!NOTE]
>
> AI answers are non-deterministic. The same prompt × model combination can
> return different content and sources on every run. To measure probabilistic
> metrics such as brand visibility rate, repeat the same combination with
> `repeatCount`.

### Polling loop example

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

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

run_id = requests.post(f"{API}/runs", headers=HEADERS, json={
    "promptSetID": "Jix75RbQ2gfTB0qzlh125g",
    "models": ["CHATGPT", "GEMINI"],
}).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://platform-api.trychainshift.ai/api/v1/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", "GEMINI"] }),
})).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();
```

## 4. Retrieve answers

Once collection is complete, retrieve the answer bodies and sources.

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

For filters and the response structure, see [Retrieving answers](https://docs.trychainshift.ai/en/guides/collecting-answers.md).

## Error cases

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

The full list of codes returned at submission is in the **Errors** table on the [Submit a run request](https://docs.trychainshift.ai/en/api-reference/runs/submit-run.md) page. For common codes and retry strategies, see [Error handling](https://docs.trychainshift.ai/en/guides/error-handling.md).

Two things that are especially easy to trip over:

* Specify exactly one of `promptIDs` and `promptSetID`. Omitting both or sending both returns the error above.
* If even one model and region combination is unsupported, the **entire** request is rejected. Check combinations in [Supported models](https://docs.trychainshift.ai/en/models.md#supported-regions).
* The same applies to `location`. If any requested model does not support that location, the whole request is rejected with `LOCATION_NOT_SUPPORTED_FOR_MODEL`. If you also specify `region`, the location must belong to that region (`LOCATION_REGION_MISMATCH`).

## Operational tips

* List runs with `GET /runs`, newest first (page size up to 10).
* To collect the same prompts on a regular schedule, the simplest approach is to create a set once and submit it repeatedly with `promptSetID`.
* Check collection characteristics such as per-model fan-out support in [Supported models](https://docs.trychainshift.ai/en/models.md).


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