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

> Kelola sesi Krea Agent melalui HTTP: mulai sesi, tunggu sebuah giliran, baca hasilnya, dan kirim tindak lanjut dengan API key Anda.

Gunakan Agent API untuk memberikan tugas kepada Krea Agent dari aplikasi Anda sendiri. Request dan response menggunakan field JSON berformat camelCase. Agent bekerja di latar belakang sementara aplikasi Anda membaca progres dan hasilnya.

| Endpoint | Tujuan |
| - | - |
| [`POST /agent/send-message`](/docs/api-reference/agent/send-agent-message) | Memulai sesi atau mengirim giliran tindak lanjut. |
| [`GET /agent/session/{sessionId}`](/docs/api-reference/agent/get-agent-session) | Membaca sesi saat ini tanpa menunggu. |
| [`POST /agent/wait-for-session`](/docs/api-reference/agent/wait-for-agent-session) | Menunggu sebuah giliran selesai, hingga batas timeout. |

<Warning>
  Agent bekerja di latar belakang. Agent tidak mengajukan pertanyaan, dan permintaan persetujuan biaya serta izin disetujui secara otomatis. Sertakan semua persyaratan dan batasan dalam prompt Anda. Tinjau tugas sebelum mengirimkannya.
</Warning>

## Autentikasi, akses, dan penagihan

Kirim `Authorization: Bearer KREA_API_KEY` di setiap request ke `https://api.krea.ai`. API key personal, service, dan legacy menggunakan [autentikasi API publik](/docs/id/developers/api-keys-and-billing) standar.

Anda hanya dapat membaca atau melanjutkan sesi yang dimiliki oleh pemanggil terautentikasi di workspace terautentikasi. Mengetahui ID sesi tidak memberikan akses. Lampiran file Krea juga harus dapat diakses oleh pemanggil tersebut di workspace tersebut.

<Info>
  Giliran Agent menggunakan saldo compute unit workspace. Giliran Agent **tidak** menggunakan saldo API. Hak paket Agent dan batas pesan paket Free tetap berlaku. Lihat [Paket, akses, dan credits Agent](/docs/id/user-guide/agent/plans-and-credits).
</Info>

Setiap response menyertakan `url` tempat Anda dapat membuka sesi di aplikasi Krea dengan akses akun dan workspace yang sesuai.

## Mulai sesi dan tunggu hasilnya

Atur `KREA_API_KEY` di environment Anda terlebih dahulu. Pilih Bash dengan `curl` dan `jq`, Python dengan `requests`, atau Node.js dengan `fetch` bawaan atau Krea SDK.

<Steps>
  <Step title="Kirim giliran pertama">
    Hilangkan `sessionId` untuk membuat sesi. Simpan `sessionId` dan `runId` yang dikembalikan. Response dikembalikan segera dengan `status: "running"`.
  </Step>

  <Step title="Tunggu giliran ini">
    Teruskan kedua ID ke `wait-for-session`. Jika `timedOut` bernilai `true`, panggil lagi dengan ID yang sama. Timeout tidak membatalkan giliran.
  </Step>

  <Step title="Baca hasilnya">
    Periksa `status` ketika `finished` bernilai `true`. Periksa `text`, `media`, dan `error` jika ada, atau buka `url` yang dikembalikan.
  </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>

Untuk Python, instal `requests` dengan `pip install requests`. Untuk Node.js, gunakan Node.js 22+ dan simpan contoh sebagai `example.mjs`. Contoh SDK memerlukan `npm install @krea-ai/sdk` dan menggunakan `requestRaw` untuk memanggil endpoint HTTP.

Contoh-contoh ini mengirim satu pesan dan menunggu hingga lima menit. Contoh-contoh ini berhenti pada error HTTP serta giliran yang gagal atau dibatalkan. Contoh-contoh ini tidak pernah mengulang pengiriman secara otomatis. Jika request pengiriman mengalami timeout, periksa sesi di Krea sebelum mengirim lagi; request pertama mungkin sudah memulai sebuah giliran.

Ketika anggaran waktu tunggu habis, giliran tetap berjalan di latar belakang. Simpan ID sesi dan ID run yang dicetak untuk melanjutkan menunggu nanti.

`timeoutSeconds` adalah bilangan bulat dari `1` hingga `300` dengan default `60`. Pastikan timeout klien HTTP Anda lebih lama daripada waktu tunggu yang diminta. Selalu teruskan `runId` terbaru saat menunggu setelah pengiriman, agar status terminal giliran sebelumnya tidak dikira sebagai giliran baru.

### Baca tanpa menunggu

Gunakan `GET /agent/session/{sessionId}` untuk mengambil snapshot sesi saat ini:

```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"
```

### Lanjutkan sesi

Setelah giliran selesai, kirim pesan lain dengan `sessionId`-nya:

```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')
```

Sebuah sesi menjalankan satu giliran dalam satu waktu. Mengirim pesan lain saat sebuah giliran sedang berjalan akan mengembalikan `409` dengan `code: "conflict"`.

## Input dan lampiran

`send-message` menerima field berikut. Lihat [referensi](/docs/api-reference/agent/send-agent-message) untuk enum model dan skema lengkap.

| Field | Perilaku |
| - | - |
| `sessionId` | UUID opsional. Hilangkan untuk sesi baru; sertakan untuk melanjutkan sesi milik Anda. |
| `prompt` | String, hingga 100.000 karakter. Default `""`. Diperlukan prompt yang tidak kosong atau setidaknya satu lampiran. |
| `attachments` | Hingga 20 lampiran. Default `[]`. Setiap lampiran memerlukan `url` dan dapat menyertakan `name` dan `contentType`. |
| `model` | ID LLM Agent opsional. Hilangkan untuk Auto. Model yang dipilih secara tetap harus termasuk dalam paket workspace. |
| `effort` | Opsional: `fast`, `default`, `high`, atau `xhigh`. Sesi baru menggunakan default `default`; hilangkan untuk mempertahankan effort sesi yang sudah ada. |
| `name` | Nama sesi opsional, hanya untuk sesi baru. Dipangkas, tidak kosong, dan hingga 120 karakter. |
| `desktopAppId` | UUID opsional yang mengidentifikasi aplikasi desktop yang terhubung. Menjalankan giliran ini di dalam aplikasi tersebut. Aplikasi harus tersedia bagi pemanggil dan workspace terautentikasi. |

`url` lampiran menerima URL HTTP(S) yang dapat diakses atau URI Krea Files yang diotorisasi seperti `file:550e8400-e29b-41d4-a716-446655440000`. `name` dan `contentType` opsional berupa string yang dipangkas, tidak kosong, dan hingga 255 karakter. Path lokal pemanggil dan ID `file_` OpenAI tidak didukung. Transfer file sebenarnya terlebih dahulu; ID di dalam teks prompt tidak mentransfer isinya.

Agent tidak mewarisi percakapan atau lampiran aplikasi Anda. Lampirkan file referensi yang tidak dapat diakses dengan cara lain. Anda tidak perlu mengulang URL yang dapat digunakan di dalam prompt, context Krea yang sudah ada, atau file sesi sebelumnya.

## Hasil sesi

`send-message` mengembalikan `sessionId`, `threadId`, `runId`, `status` (selalu `"running"`), dan `url`.

`GET /agent/session/{sessionId}` dan `wait-for-session` mengembalikan tampilan sesi berikut. Hanya `wait-for-session` yang menambahkan field wajib `timedOut`.

| Field | Arti |
| - | - |
| `sessionId`, `threadId` | Identifier sesi dan thread root. |
| `runId` | Identifier giliran saat ini, jika tersedia. |
| `status` | `not_started`, `running`, `completed`, `failed`, atau `cancelled`. |
| `finished` | `true` untuk giliran terminal. Jika `runId` diberikan pada wait, giliran terminal juga harus cocok dengan ID tersebut. |
| `text` | Teks pesan asisten terbaru. |
| `media` | Array media yang dihasilkan oleh sesi. Urutannya tidak signifikan. |
| `error` | Teks error opsional untuk sesi. |
| `url` | Tautan ke sesi di aplikasi Krea. |
| `timedOut` | Hanya pada response wait: `true` jika tenggat waktu terlewati sebelum giliran yang diminta selesai. |

Setiap item `media` dapat mewakili sebuah generasi (`jobId` dan `mediaKind` opsional: `image`, `video`, `audio`, atau `3d`), media yang di-rehost (`url`, dengan `mimeType` opsional), atau file Krea (`uri`, `name`, `mimeType`). Ambil detail generasi melalui `GET /jobs/{jobId}`. Anda dapat menggunakan kembali URI file Krea sebagai lampiran atau membuka `url` sesi untuk melihat file-filenya. Media dapat muncul saat giliran masih berjalan.

## Error

Error endpoint menggunakan `{ "error": "...", "code": "...", "allowedModels": ["..."] }`. Hanya `error` yang wajib. Giliran yang gagal setelah dikirim akan muncul sebagai `status: "failed"` di response sesi yang berhasil.

| Status HTTP | Arti |
| - | - |
| `400` | Body JSON tidak valid formatnya. |
| `401` | Autentikasi tidak ada atau tidak valid. |
| `402` | Saldo compute unit di workspace tidak mencukupi (`compute_limit`) atau batas pesan paket Free telah tercapai (`free_message_limit`). |
| `403` | Model yang dipilih secara tetap tidak termasuk dalam hak Anda (`model_not_entitled`); `allowedModels` mencantumkan ID yang diizinkan. |
| `404` | Sesi tidak ada atau tidak dapat diakses (`not_found`), atau lampiran file Krea tidak ada atau tidak dapat diakses (`attachment_not_found`). |
| `409` | Sebuah giliran sedang berlangsung (`conflict`). |
| `422` | Input tidak valid, atau aplikasi desktop yang dipilih tidak tersedia. |


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