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

# Agent API

> Управляйте сессиями Krea Agent по HTTP с API-ключом: запускайте сессию, ожидайте завершения хода, читайте результаты и отправляйте новые сообщения.

Используйте Agent API, чтобы ставить задачи Krea Agent из собственного приложения. В запросах и ответах используются JSON-поля в camelCase. Агент работает в фоновом режиме, а ваше приложение читает его прогресс и результаты.

| Эндпоинт | Назначение |
| - | - |
| [`POST /agent/send-message`](/docs/api-reference/agent/send-agent-message) | Запустить сессию или отправить следующий ход. |
| [`GET /agent/session/{sessionId}`](/docs/api-reference/agent/get-agent-session) | Прочитать текущее состояние сессии без ожидания. |
| [`POST /agent/wait-for-session`](/docs/api-reference/agent/wait-for-agent-session) | Дождаться завершения хода, но не дольше тайм-аута. |

<Warning>
  Агент работает в фоновом режиме. Он не задаёт вопросов, а запросы на подтверждение стоимости и разрешений одобряются автоматически. Укажите в промпте все требования и ограничения. Проверьте задачу перед отправкой.
</Warning>

## Аутентификация, доступ и биллинг

Передавайте `Authorization: Bearer KREA_API_KEY` в каждом запросе к `https://api.krea.ai`. Персональные, сервисные и устаревшие API-ключи используют стандартную [аутентификацию публичного API](/docs/ru/developers/api-keys-and-billing).

Читать и продолжать можно только сессии, принадлежащие аутентифицированному пользователю в аутентифицированном рабочем пространстве. Знание ID сессии не даёт к ней доступа. Вложения из Krea Files также должны быть доступны этому пользователю в этом рабочем пространстве.

<Info>
  Ходы агента расходуют баланс compute-юнитов рабочего пространства. API-баланс они **не** используют. Права тарифа Agent и лимиты сообщений тарифа Free по-прежнему действуют. См. [Тарифы, доступ и кредиты Agent](/docs/ru/user-guide/agent/plans-and-credits).
</Info>

Каждый ответ содержит `url`, по которому можно открыть сессию в приложении Krea при наличии соответствующего доступа к аккаунту и рабочему пространству.

## Запуск сессии и ожидание результата

Сначала задайте `KREA_API_KEY` в переменных окружения. Выберите Bash с `curl` и `jq`, Python с `requests` или Node.js со встроенным `fetch` либо Krea SDK.

<Steps>
  <Step title="Отправьте первый ход">
    Не указывайте `sessionId`, чтобы создать сессию. Сохраните возвращённые `sessionId` и `runId`. Ответ приходит сразу со `status: "running"`.
  </Step>

  <Step title="Дождитесь завершения хода">
    Передайте оба ID в `wait-for-session`. Если `timedOut` равно `true`, вызовите его снова с теми же ID. Тайм-аут не отменяет ход.
  </Step>

  <Step title="Прочитайте результат">
    Когда `finished` равно `true`, проверьте `status`. Изучите `text`, `media` и `error` (если есть) или откройте возвращённый `url`.
  </Step>
</Steps>

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light-default","dark":"vesper"}}
  set -euo pipefail
  : "${KREA_API_KEY:?Set your Krea API key}"

  START=$(curl --fail-with-body --silent --show-error --max-time 60 \
    https://api.krea.ai/agent/send-message \
    -H "Authorization: Bearer $KREA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "prompt": "Create three square product images for a ceramic coffee mug on a neutral studio background. Use no text or logos.",
      "name": "Coffee mug campaign"
    }')

  SESSION_ID=$(printf '%s' "$START" | jq -er '.sessionId')
  RUN_ID=$(printf '%s' "$START" | jq -er '.runId')
  printf '%s' "$START" | jq -r '.url'

  DEADLINE=$((SECONDS + 300))

  while (( SECONDS < DEADLINE - 10 )); do
    WAIT_SECONDS=$((DEADLINE - SECONDS - 10))
    if (( WAIT_SECONDS > 60 )); then WAIT_SECONDS=60; fi
    WAIT_BODY=$(jq -n --arg sessionId "$SESSION_ID" --arg runId "$RUN_ID" \
      --argjson timeoutSeconds "$WAIT_SECONDS" \
      '{sessionId: $sessionId, runId: $runId, timeoutSeconds: $timeoutSeconds}')
    RESULT=$(curl --fail-with-body --silent --show-error --max-time "$((WAIT_SECONDS + 10))" \
      https://api.krea.ai/agent/wait-for-session \
      -H "Authorization: Bearer $KREA_API_KEY" \
      -H "Content-Type: application/json" \
      -d "$WAIT_BODY")
    printf '%s' "$RESULT" | jq '{status, finished, timedOut, text, media, error, url}'
    if printf '%s' "$RESULT" | jq -e '.finished' > /dev/null; then
      if printf '%s' "$RESULT" | jq -e '.status == "completed"' > /dev/null; then
        exit 0
      fi
      printf '%s' "$RESULT" | jq -r '"Turn ended: \(.status). \(.error // "No error details")"' >&2
      exit 1
    fi
  done

  printf 'Wait budget exhausted; the turn continues. Resume waiting with sessionId=%s runId=%s\n' \
    "$SESSION_ID" "$RUN_ID" >&2
  exit 1
  ```

  ```python Python theme={"theme":{"light":"github-light-default","dark":"vesper"}}
  import json
  import os
  import time
  import requests

  api = "https://api.krea.ai"
  headers = {"Authorization": f"Bearer {os.environ['KREA_API_KEY']}"}

  response = requests.post(
      f"{api}/agent/send-message",
      headers=headers,
      json={
          "prompt": "Create three square product images for a ceramic coffee mug on a neutral studio background. Use no text or logos.",
          "name": "Coffee mug campaign",
      },
      timeout=60,
  )
  response.raise_for_status()
  start = response.json()
  session_id, run_id = start["sessionId"], start["runId"]
  print(start["url"])

  deadline = time.monotonic() + 300
  while True:
      wait_seconds = min(60, int(deadline - time.monotonic()) - 10)
      if wait_seconds < 1:
          raise TimeoutError(
              "Wait budget exhausted; the turn continues. Resume waiting with "
              f"sessionId={session_id} runId={run_id}"
          )
      response = requests.post(
          f"{api}/agent/wait-for-session",
          headers=headers,
          json={
              "sessionId": session_id,
              "runId": run_id,
              "timeoutSeconds": wait_seconds,
          },
          timeout=wait_seconds + 10,
      )
      response.raise_for_status()
      result = response.json()
      print(json.dumps(result, indent=2))
      if result["finished"]:
          if result["status"] != "completed":
              raise RuntimeError(
                  f"Turn ended: {result['status']}. {result.get('error', 'No error details')}"
              )
          break
  ```

  ```javascript Node.js theme={"theme":{"light":"github-light-default","dark":"vesper"}}
  import { performance } from "node:perf_hooks";

  const token = process.env.KREA_API_KEY;
  if (!token) throw new Error("Set your Krea API key");
  const api = "https://api.krea.ai";

  async function post(path, body, timeoutMs) {
    const response = await fetch(`${api}${path}`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
      signal: AbortSignal.timeout(timeoutMs),
    });
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${await response.text()}`);
    }
    return response.json();
  }

  const start = await post("/agent/send-message", {
    prompt: "Create three square product images for a ceramic coffee mug on a neutral studio background. Use no text or logos.",
    name: "Coffee mug campaign",
  }, 60_000);
  const { sessionId, runId } = start;
  console.log(start.url);

  const deadline = performance.now() + 300_000;
  while (true) {
    const timeoutSeconds = Math.min(60, Math.floor((deadline - performance.now()) / 1000) - 10);
    if (timeoutSeconds < 1) {
      throw new Error(
        `Wait budget exhausted; the turn continues. Resume waiting with sessionId=${sessionId} runId=${runId}`,
      );
    }
    const result = await post("/agent/wait-for-session", {
      sessionId,
      runId,
      timeoutSeconds,
    }, (timeoutSeconds + 10) * 1000);
    console.log(JSON.stringify(result, null, 2));
    if (result.finished) {
      if (result.status !== "completed") {
        throw new Error(`Turn ended: ${result.status}. ${result.error ?? "No error details"}`);
      }
      break;
    }
  }
  ```

  ```javascript Node.js (SDK) theme={"theme":{"light":"github-light-default","dark":"vesper"}}
  import { performance } from "node:perf_hooks";
  import { Krea } from "@krea-ai/sdk";

  const token = process.env.KREA_API_KEY;
  if (!token) throw new Error("Set your Krea API key");
  const krea = new Krea({ apiKey: token });

  const start = await krea.requestRaw("/agent/send-message", {
    method: "POST",
    retry: false,
    signal: AbortSignal.timeout(60_000),
    body: {
      prompt: "Create three square product images for a ceramic coffee mug on a neutral studio background. Use no text or logos.",
      name: "Coffee mug campaign",
    },
  });
  const { sessionId, runId } = start;
  console.log(start.url);

  const deadline = performance.now() + 300_000;
  while (true) {
    const timeoutSeconds = Math.min(60, Math.floor((deadline - performance.now()) / 1000) - 15);
    if (timeoutSeconds < 1) {
      throw new Error(
        `Wait budget exhausted; the turn continues. Resume waiting with sessionId=${sessionId} runId=${runId}`,
      );
    }
    const result = await krea.requestRaw("/agent/wait-for-session", {
      method: "POST",
      retry: false,
      signal: AbortSignal.timeout((timeoutSeconds + 15) * 1000),
      body: { sessionId, runId, timeoutSeconds },
    });
    console.log(JSON.stringify(result, null, 2));
    if (result.finished) {
      if (result.status !== "completed") {
        throw new Error(`Turn ended: ${result.status}. ${result.error ?? "No error details"}`);
      }
      break;
    }
  }
  ```
</CodeGroup>

Для Python установите `requests` командой `pip install requests`. Для Node.js используйте Node.js 22+ и сохраните пример как `example.mjs`. Для примера с SDK нужно выполнить `npm install @krea-ai/sdk`; в нём для вызова HTTP-эндпоинтов используется `requestRaw`.

Эти примеры отправляют одно сообщение и ждут до пяти минут. Они останавливаются при HTTP-ошибках, а также при неудачных или отменённых ходах. Отправка никогда не повторяется автоматически. Если запрос на отправку завершился по тайм-ауту, проверьте сессию в Krea, прежде чем отправлять снова: первый запрос мог уже запустить ход.

Когда отведённое на ожидание время истекает, ход продолжается в фоновом режиме. Сохраните выведенные ID сессии и запуска, чтобы продолжить ожидание позже.

`timeoutSeconds` — целое число от `1` до `300`, по умолчанию `60`. Тайм-аут вашего HTTP-клиента должен быть больше запрошенного времени ожидания. При ожидании после отправки всегда передавайте последний `runId`, чтобы финальный статус предыдущего хода не был принят за статус нового.

### Чтение без ожидания

Используйте `GET /agent/session/{sessionId}`, чтобы получить снимок текущего состояния сессии:

```bash cURL theme={"theme":{"light":"github-light-default","dark":"vesper"}}
curl --fail-with-body --silent --show-error \
  "https://api.krea.ai/agent/session/$SESSION_ID" \
  -H "Authorization: Bearer $KREA_API_KEY"
```

### Продолжение сессии

После завершения хода отправьте новое сообщение с его `sessionId`:

```bash cURL theme={"theme":{"light":"github-light-default","dark":"vesper"}}
FOLLOW_UP=$(curl --fail-with-body --silent --show-error \
  https://api.krea.ai/agent/send-message \
  -H "Authorization: Bearer $KREA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg sessionId "$SESSION_ID" \
    '{sessionId: $sessionId, prompt: "Make a landscape variation of the first image."}')")

# Use this new runId in the next wait-for-session request.
RUN_ID=$(printf '%s' "$FOLLOW_UP" | jq -er '.runId')
```

Сессия выполняет только один ход за раз. Отправка нового сообщения во время выполнения хода возвращает `409` с `code: "conflict"`.

## Входные данные и вложения

`send-message` принимает следующие поля. Полный enum моделей и схемы см. в [справочнике](/docs/api-reference/agent/send-agent-message).

| Поле | Поведение |
| - | - |
| `sessionId` | Необязательный UUID. Не указывайте для новой сессии; укажите, чтобы продолжить собственную сессию. |
| `prompt` | Строка длиной до 100 000 символов. По умолчанию `""`. Требуется непустой промпт или хотя бы одно вложение. |
| `attachments` | До 20 вложений. По умолчанию `[]`. Для каждого обязателен `url`; можно также указать `name` и `contentType`. |
| `model` | Необязательный ID LLM агента. Не указывайте, чтобы использовать Auto. Закреплённая модель должна входить в тариф рабочего пространства. |
| `effort` | Необязательно: `fast`, `default`, `high` или `xhigh`. Для новых сессий по умолчанию `default`; не указывайте, чтобы сохранить effort существующей сессии. |
| `name` | Необязательное название сессии, только для новых сессий. Пробелы по краям обрезаются; значение не может быть пустым и должно быть не длиннее 120 символов. |
| `desktopAppId` | Необязательный UUID подключённого десктопного приложения. Этот ход выполняется внутри этого приложения. Приложение должно быть доступно аутентифицированному пользователю и рабочему пространству. |

`url` вложения принимает доступный HTTP(S)-URL или авторизованный URI Krea Files, например `file:550e8400-e29b-41d4-a716-446655440000`. Необязательные `name` и `contentType` — непустые строки длиной до 255 символов, пробелы по краям обрезаются. Локальные пути на стороне вызывающего и ID OpenAI вида `file_` не поддерживаются. Сначала передайте сам файл: ID в тексте промпта не передаёт его содержимое.

Агент не наследует переписку и вложения вашего приложения. Прикрепляйте файлы-референсы, к которым у него нет доступа иным способом. Повторять в промпте пригодные URL, существующий контекст Krea или файлы из предыдущих ходов сессии не нужно.

## Результаты сессии

`send-message` возвращает `sessionId`, `threadId`, `runId`, `status` (всегда `"running"`) и `url`.

`GET /agent/session/{sessionId}` и `wait-for-session` возвращают следующее представление сессии. Только `wait-for-session` добавляет обязательное поле `timedOut`.

| Поле | Значение |
| - | - |
| `sessionId`, `threadId` | Идентификаторы сессии и корневого треда. |
| `runId` | Идентификатор текущего хода, если доступен. |
| `status` | `not_started`, `running`, `completed`, `failed` или `cancelled`. |
| `finished` | `true` для завершённого хода. Если при ожидании передан `runId`, завершённый ход также должен соответствовать этому ID. |
| `text` | Текст последнего сообщения ассистента. |
| `media` | Массив медиафайлов, созданных в сессии. Порядок не имеет значения. |
| `error` | Необязательный текст ошибки сессии. |
| `url` | Ссылка на сессию в приложении Krea. |
| `timedOut` | Только в ответах на ожидание: `true`, если срок истёк до завершения запрошенного хода. |

Каждый элемент `media` может представлять генерацию (`jobId` и необязательный `mediaKind`: `image`, `video`, `audio` или `3d`), перезагруженный медиафайл (`url`, с необязательным `mimeType`) или файл Krea (`uri`, `name`, `mimeType`). Подробности генерации можно получить через `GET /jobs/{jobId}`. URI файла Krea можно повторно использовать как вложение или открыть `url` сессии, чтобы посмотреть её файлы. Медиафайлы могут появляться, пока ход ещё выполняется.

## Ошибки

Ошибки эндпоинтов имеют формат `{ "error": "...", "code": "...", "allowedModels": ["..."] }`. Обязательно только поле `error`. Ход, завершившийся неудачей после отправки, отображается как `status: "failed"` в успешном ответе с сессией.

| HTTP-статус | Значение |
| - | - |
| `400` | Некорректное тело JSON. |
| `401` | Аутентификация отсутствует или недействительна. |
| `402` | Недостаточно compute-юнитов на балансе рабочего пространства (`compute_limit`) или достигнут лимит сообщений тарифа Free (`free_message_limit`). |
| `403` | Закреплённая модель не входит в тариф (`model_not_entitled`); `allowedModels` перечисляет разрешённые ID. |
| `404` | Сессия отсутствует или недоступна (`not_found`), либо вложение из Krea Files отсутствует или недоступно (`attachment_not_found`). |
| `409` | Ход уже выполняется (`conflict`). |
| `422` | Некорректные входные данные или выбранное десктопное приложение недоступно. |


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