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

> Gerencie sessões do Krea Agent via HTTP: inicie uma sessão, aguarde um turno, leia os resultados e envie mensagens de acompanhamento com sua chave de API.

Use a Agent API para passar uma tarefa ao Krea Agent a partir da sua própria aplicação. Requisições e respostas usam campos JSON em camelCase. O Agent trabalha em segundo plano enquanto sua aplicação lê o progresso e os resultados.

| Endpoint | Finalidade |
| - | - |
| [`POST /agent/send-message`](/docs/api-reference/agent/send-agent-message) | Iniciar uma sessão ou enviar um turno de acompanhamento. |
| [`GET /agent/session/{sessionId}`](/docs/api-reference/agent/get-agent-session) | Ler a sessão atual sem esperar. |
| [`POST /agent/wait-for-session`](/docs/api-reference/agent/wait-for-agent-session) | Aguardar a conclusão de um turno, até um tempo limite. |

<Warning>
  O Agent trabalha em segundo plano. Ele não faz perguntas, e as solicitações de confirmação de custo e permissão são aprovadas automaticamente. Inclua todos os requisitos e restrições no seu prompt. Revise a tarefa antes de enviá-la.
</Warning>

## Autenticação, acesso e cobrança

Envie `Authorization: Bearer KREA_API_KEY` em toda requisição para `https://api.krea.ai`. Chaves de API pessoais, de serviço e legadas usam a [autenticação padrão da API pública](/docs/pt-BR/developers/api-keys-and-billing).

Você só pode ler ou continuar sessões que pertencem ao chamador autenticado no workspace autenticado. Conhecer o ID de uma sessão não concede acesso. Arquivos anexados do Krea também precisam estar acessíveis a esse chamador nesse workspace.

<Info>
  Os turnos do Agent usam o saldo de unidades de computação do workspace. Eles **não** usam o saldo de API. Os direitos do plano do Agent e os limites de mensagens do plano Free continuam valendo. Veja [Planos, acesso e créditos do Agent](/docs/pt-BR/user-guide/agent/plans-and-credits).
</Info>

Cada resposta inclui uma `url` onde você pode abrir a sessão no app do Krea com o acesso adequado à conta e ao workspace.

## Inicie uma sessão e aguarde o resultado

Primeiro, defina `KREA_API_KEY` no seu ambiente. Escolha Bash com `curl` e `jq`, Python com `requests` ou Node.js com o `fetch` nativo ou o SDK do Krea.

<Steps>
  <Step title="Envie o primeiro turno">
    Omita `sessionId` para criar uma sessão. Salve o `sessionId` e o `runId` retornados. A resposta volta imediatamente com `status: "running"`.
  </Step>

  <Step title="Aguarde este turno">
    Passe os dois IDs para `wait-for-session`. Se `timedOut` for `true`, chame novamente com os mesmos IDs. Um tempo limite esgotado não cancela o turno.
  </Step>

  <Step title="Leia o resultado">
    Verifique `status` quando `finished` for `true`. Inspecione `text`, `media` e qualquer `error`, ou abra a `url` retornada.
  </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>

Para Python, instale o `requests` com `pip install requests`. Para Node.js, use Node.js 22+ e salve o exemplo como `example.mjs`. O exemplo com SDK requer `npm install @krea-ai/sdk` e usa `requestRaw` para chamar os endpoints HTTP.

Esses exemplos enviam uma mensagem e aguardam por até cinco minutos. Eles param em erros HTTP e em turnos que falharam ou foram cancelados. Eles nunca repetem um envio automaticamente. Se uma requisição de envio atingir o tempo limite, verifique a sessão no Krea antes de enviar novamente; a primeira requisição pode ter iniciado um turno.

Quando o tempo de espera se esgota, o turno continua em segundo plano. Salve os IDs de sessão e de execução exibidos para retomar a espera depois.

`timeoutSeconds` é um inteiro de `1` a `300` e o padrão é `60`. Mantenha o tempo limite do seu cliente HTTP maior que a espera solicitada. Sempre passe o `runId` mais recente ao aguardar após um envio, para que o status final de um turno anterior não seja confundido com o do novo turno.

### Ler sem esperar

Use `GET /agent/session/{sessionId}` para obter um snapshot da sessão atual:

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

### Continuar a sessão

Depois que o turno terminar, envie outra mensagem com o `sessionId` dele:

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

Uma sessão executa um turno por vez. Enviar outra mensagem enquanto um turno está em execução retorna `409` com `code: "conflict"`.

## Entradas e anexos

`send-message` aceita estes campos. Veja a [referência](/docs/api-reference/agent/send-agent-message) para o enum completo de modelos e os schemas.

| Campo | Comportamento |
| - | - |
| `sessionId` | UUID opcional. Omita para uma nova sessão; inclua para continuar uma sessão sua. |
| `prompt` | String com até 100.000 caracteres. O padrão é `""`. É obrigatório um prompt não vazio ou pelo menos um anexo. |
| `attachments` | Até 20 anexos. O padrão é `[]`. Cada um precisa de `url` e pode incluir `name` e `contentType`. |
| `model` | ID opcional de LLM do Agent. Omita para usar Auto. Um modelo fixado precisa estar incluído no plano do workspace. |
| `effort` | Opcional: `fast`, `default`, `high` ou `xhigh`. Novas sessões usam `default` por padrão; omita para manter o effort de uma sessão existente. |
| `name` | Nome opcional da sessão, apenas para novas sessões. Sem espaços nas extremidades, não vazio e com até 120 caracteres. |
| `desktopAppId` | UUID opcional que identifica um app desktop conectado. Executa este turno dentro desse app. O app precisa estar disponível para o chamador autenticado e o workspace. |

A `url` do anexo aceita uma URL HTTP(S) acessível ou um URI autorizado do Krea Files, como `file:550e8400-e29b-41d4-a716-446655440000`. Os campos opcionais `name` e `contentType` são strings sem espaços nas extremidades, não vazias e com até 255 caracteres. Caminhos locais do chamador e IDs `file_` da OpenAI não são suportados. Transfira o arquivo real primeiro; um ID no texto do prompt não transfere o conteúdo.

O Agent não herda a conversa nem os anexos da sua aplicação. Anexe arquivos de referência que não estejam acessíveis de outra forma. Você não precisa repetir URLs utilizáveis que já estejam no prompt, no contexto existente do Krea ou em arquivos de sessões anteriores.

## Resultados da sessão

`send-message` retorna `sessionId`, `threadId`, `runId`, `status` (sempre `"running"`) e `url`.

`GET /agent/session/{sessionId}` e `wait-for-session` retornam a seguinte visão da sessão. Somente `wait-for-session` adiciona o campo obrigatório `timedOut`.

| Campo | Significado |
| - | - |
| `sessionId`, `threadId` | Identificadores da sessão e da thread raiz. |
| `runId` | Identificador do turno atual, quando disponível. |
| `status` | `not_started`, `running`, `completed`, `failed` ou `cancelled`. |
| `finished` | `true` para um turno finalizado. Com `runId` informado em uma espera, o turno finalizado também precisa corresponder a esse ID. |
| `text` | Texto da mensagem mais recente do assistente. |
| `media` | Array de mídias produzidas pela sessão. A ordem não é significativa. |
| `error` | Texto de erro opcional da sessão. |
| `url` | Link para a sessão no app do Krea. |
| `timedOut` | Apenas em respostas de espera: `true` se o prazo terminou antes de o turno solicitado ser concluído. |

Cada item de `media` pode representar uma geração (`jobId` e `mediaKind` opcional: `image`, `video`, `audio` ou `3d`), uma mídia rehospedada (`url`, com `mimeType` opcional) ou um arquivo do Krea (`uri`, `name`, `mimeType`). Obtenha os detalhes da geração por meio de `GET /jobs/{jobId}`. Você pode reutilizar o URI de um arquivo do Krea como anexo ou abrir a `url` da sessão para ver os arquivos. As mídias podem aparecer enquanto o turno ainda está em execução.

## Erros

Os erros dos endpoints usam `{ "error": "...", "code": "...", "allowedModels": ["..."] }`. Apenas `error` é obrigatório. Um turno que falha após o envio aparece como `status: "failed"` em uma resposta de sessão bem-sucedida.

| Status HTTP | Significado |
| - | - |
| `400` | Corpo JSON malformado. |
| `401` | Autenticação ausente ou inválida. |
| `402` | Saldo de unidades de computação insuficiente no workspace (`compute_limit`) ou limite de mensagens do plano Free atingido (`free_message_limit`). |
| `403` | O modelo fixado não está incluído nos direitos do plano (`model_not_entitled`); `allowedModels` lista os IDs permitidos. |
| `404` | A sessão não existe ou está inacessível (`not_found`), ou um arquivo do Krea anexado não existe ou está inacessível (`attachment_not_found`). |
| `409` | Já há um turno em andamento (`conflict`). |
| `422` | Entrada inválida, ou o app desktop selecionado está indisponível. |


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