> ## 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

> 通过 HTTP 管理 Krea Agent 会话：使用你的 API 密钥启动会话、等待一轮完成、读取结果并发送后续消息。

使用 Agent API，你可以从自己的应用中向 Krea Agent 下达任务。请求和响应均使用 camelCase 格式的 JSON 字段。Agent 在后台工作，你的应用可以读取其进度和结果。

| 端点 | 用途 |
| - | - |
| [`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>
  Agent 在后台工作。它不会提出问题，费用和权限确认会被自动批准。请在提示词中写明所有要求和约束。提交前请仔细检查任务。
</Warning>

## 认证、访问权限与计费

向 `https://api.krea.ai` 发送的每个请求都需携带 `Authorization: Bearer KREA_API_KEY`。个人、服务和旧版 API 密钥均使用标准的[公共 API 认证](/docs/cn/developers/api-keys-and-billing)。

你只能读取或继续由已认证调用方在已认证工作区中拥有的会话。仅知道会话 ID 并不能获得访问权限。Krea 文件附件也必须可供该调用方在该工作区中访问。

<Info>
  Agent 的每一轮使用工作区的计算单元余额，**不**使用 API 余额。Agent 套餐权益和 Free 套餐的消息限制仍然适用。请参阅 [Agent 套餐、访问权限与积分](/docs/cn/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 时，请通过 `pip install requests` 安装 `requests`。使用 Node.js 时，请使用 Node.js 22+，并将示例保存为 `example.mjs`。SDK 示例需要 `npm install @krea-ai/sdk`，并使用 `requestRaw` 调用 HTTP 端点。

这些示例会提交一条消息并最多等待五分钟。遇到 HTTP 错误以及失败或已取消的轮次时会停止。它们从不自动重试发送。如果发送请求超时，请先在 Krea 中检查该会话再重新提交；第一个请求可能已经启动了一轮。

等待时间预算用尽后，该轮仍会在后台继续运行。请保存打印出的会话 ID 和运行 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` 接受以下字段。完整的模型枚举和 schema 请参阅[参考文档](/docs/api-reference/agent/send-agent-message)。

| 字段 | 行为 |
| - | - |
| `sessionId` | 可选 UUID。新建会话时省略；继续自己拥有的会话时填写。 |
| `prompt` | 字符串，最多 100,000 个字符。默认为 `""`。必须提供非空提示词或至少一个附件。 |
| `attachments` | 最多 20 个附件。默认为 `[]`。每个附件都需要 `url`，并可包含 `name` 和 `contentType`。 |
| `model` | 可选的 Agent LLM ID。省略则使用 Auto。固定指定的模型必须包含在工作区套餐中。 |
| `effort` | 可选：`fast`、`default`、`high` 或 `xhigh`。新会话默认为 `default`；省略则保留现有会话的 effort。 |
| `name` | 可选的会话名称，仅适用于新会话。会去除首尾空白，不能为空，最多 120 个字符。 |
| `desktopAppId` | 可选 UUID，用于标识已连接的桌面应用。在该应用内运行这一轮。该应用必须对已认证的调用方和工作区可用。 |

附件的 `url` 接受可访问的 HTTP(S) URL，或已授权的 Krea Files URI，例如 `file:550e8400-e29b-41d4-a716-446655440000`。可选的 `name` 和 `contentType` 为去除首尾空白后非空、最多 255 个字符的字符串。不支持调用方本地路径和 OpenAI 的 `file_` ID。请先传输实际文件；提示词文本中的 ID 不会传输其内容。

Agent 不会继承你的应用中的对话或附件。请附加无法通过其他方式访问的参考文件。对于提示词中、现有 Krea 上下文中或之前会话文件中已可用的 URL，无需重复提供。

## 会话结果

`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}` 获取生成详情。你可以将 Krea 文件 URI 复用为附件，或打开会话的 `url` 查看其文件。轮次仍在运行时，媒体也可能已经出现。

## 错误

端点错误使用 `{ "error": "...", "code": "...", "allowedModels": ["..."] }` 格式。只有 `error` 是必填的。提交后失败的轮次则会在成功的会话响应中显示为 `status: "failed"`。

| HTTP 状态码 | 含义 |
| - | - |
| `400` | JSON 请求体格式错误。 |
| `401` | 缺少认证或认证无效。 |
| `402` | 工作区计算单元余额不足（`compute_limit`），或已达到 Free 套餐消息限制（`free_message_limit`）。 |
| `403` | 无权使用固定指定的模型（`model_not_entitled`）；`allowedModels` 列出了允许的 ID。 |
| `404` | 会话不存在或无法访问（`not_found`），或 Krea 文件附件不存在或无法访问（`attachment_not_found`）。 |
| `409` | 已有一轮正在进行（`conflict`）。 |
| `422` | 输入无效，或所选桌面应用不可用。 |


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