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

> Faça a gestão de sessões do Krea Agent por HTTP: inicie uma sessão, aguarde um turno, leia os resultados e envie mensagens de seguimento com a sua chave de API.

Utilize a Agent API para atribuir uma tarefa ao Krea Agent a partir da sua própria aplicação. Os pedidos e as respostas utilizam campos JSON em camelCase. O agente trabalha em segundo plano enquanto a 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 submeter um turno de seguimento. |
| [`GET /agent/session/{sessionId}`](/docs/api-reference/agent/get-agent-session) | Ler a sessão atual sem aguardar. |
| [`POST /agent/wait-for-session`](/docs/api-reference/agent/wait-for-agent-session) | Aguardar que um turno termine, até um tempo limite. |

<Warning>
  O agente trabalha em segundo plano. Não faz perguntas, e os pedidos de confirmação de custos e permissões são aprovados automaticamente. Inclua todos os requisitos e restrições no seu prompt. Reveja a tarefa antes de a submeter.
</Warning>

## Autenticação, acesso e faturação

Envie `Authorization: Bearer KREA_API_KEY` em todos os pedidos para `https://api.krea.ai`. As chaves de API pessoais, de serviço e legadas utilizam a [autenticação padrão da API pública](/docs/pt/developers/api-keys-and-billing).

Só pode ler ou continuar sessões que pertençam ao autor da chamada autenticado, na workspace autenticada. Conhecer o ID de uma sessão não concede acesso. Os anexos de ficheiros da Krea também têm de estar acessíveis a esse autor da chamada nessa workspace.

<Info>
  Os turnos do agente utilizam o saldo de unidades de computação da workspace. **Não** utilizam o saldo de API. Os direitos do plano do agente e os limites de mensagens do plano Free continuam a aplicar-se. Consulte [Planos, acesso e créditos do agente](/docs/pt/user-guide/agent/plans-and-credits).
</Info>

Cada resposta inclui um `url` onde pode abrir a sessão na aplicação Krea com o acesso adequado à conta e à workspace.

## Iniciar uma sessão e aguardar o resultado

Defina primeiro `KREA_API_KEY` no seu ambiente. Escolha Bash com `curl` e `jq`, Python com `requests` ou Node.js com o `fetch` integrado ou o SDK da Krea.

<Steps>
  <Step title="Submeter o primeiro turno">
    Omita `sessionId` para criar uma sessão. Guarde o `sessionId` e o `runId` devolvidos. A resposta é devolvida de imediato com `status: "running"`.
  </Step>

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

  <Step title="Ler o resultado">
    Verifique `status` quando `finished` for `true`. Analise `text`, `media` e qualquer `error`, ou abra o `url` devolvido.
  </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 `requests` com `pip install requests`. Para Node.js, utilize o Node.js 22+ e guarde o exemplo como `example.mjs`. O exemplo do SDK requer `npm install @krea-ai/sdk` e utiliza `requestRaw` para chamar os endpoints HTTP.

Estes exemplos submetem uma mensagem e aguardam até cinco minutos. Param perante erros HTTP e turnos falhados ou cancelados. Nunca repetem um envio automaticamente. Se um pedido de envio exceder o tempo limite, verifique a sessão na Krea antes de submeter novamente; o primeiro pedido pode ter iniciado um turno.

Quando o tempo de espera disponível se esgota, o turno continua em segundo plano. Guarde os IDs de sessão e de execução apresentados para retomar a espera mais tarde.

`timeoutSeconds` é um número inteiro de `1` a `300` e o valor predefinido é `60`. Mantenha o tempo limite do seu cliente HTTP superior à espera pedida. Passe sempre o `runId` mais recente ao aguardar após um envio, para que o estado terminal de um turno anterior não seja confundido com o do novo turno.

### Ler sem aguardar

Utilize `GET /agent/session/{sessionId}` para obter um instantâneo 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 de o turno terminar, envie outra mensagem com o respetivo `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')
```

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

## Entradas e anexos

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

| Campo | Comportamento |
| - | - |
| `sessionId` | UUID opcional. Omita para uma nova sessão; inclua para continuar uma sessão que lhe pertence. |
| `prompt` | String com até 100 000 caracteres. O valor predefinido é `""`. É necessário um prompt não vazio ou pelo menos um anexo. |
| `attachments` | Até 20 anexos. O valor predefinido é `[]`. Cada um precisa de `url` e pode incluir `name` e `contentType`. |
| `model` | ID opcional do LLM do agente. Omita para Auto. Um modelo fixado tem de estar incluído no plano da workspace. |
| `effort` | Opcional: `fast`, `default`, `high` ou `xhigh`. As novas sessões utilizam `default` por predefiniçã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 uma aplicação de desktop ligada. Executa este turno dentro dessa aplicação. A aplicação tem de estar disponível para o autor da chamada autenticado e para a workspace. |

O `url` do anexo aceita um 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. Os caminhos locais do autor da chamada e os IDs `file_` da OpenAI não são suportados. Transfira primeiro o ficheiro real; um ID no texto do prompt não transfere o seu conteúdo.

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

## Resultados da sessão

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

`GET /agent/session/{sessionId}` e `wait-for-session` devolvem a seguinte vista da sessão. Apenas `wait-for-session` acrescenta o campo obrigatório `timedOut`.

| Campo | Significado |
| - | - |
| `sessionId`, `threadId` | Identificadores da sessão e do thread raiz. |
| `runId` | Identificador do turno atual, quando disponível. |
| `status` | `not_started`, `running`, `completed`, `failed` ou `cancelled`. |
| `finished` | `true` para um turno terminal. Se for indicado `runId` numa espera, o turno terminal também tem de corresponder a esse ID. |
| `text` | Texto da mensagem mais recente do assistente. |
| `media` | Array de media produzida pela sessão. A ordem não é significativa. |
| `error` | Texto de erro opcional da sessão. |
| `url` | Ligação para a sessão na aplicação Krea. |
| `timedOut` | Apenas nas respostas de espera: `true` se o prazo terminou antes de o turno pedido terminar. |

Cada item de `media` pode representar uma geração (`jobId` e `mediaKind` opcional: `image`, `video`, `audio` ou `3d`), media realojada (`url`, com `mimeType` opcional) ou um ficheiro da Krea (`uri`, `name`, `mimeType`). Obtenha os detalhes da geração através de `GET /jobs/{jobId}`. Pode reutilizar o URI de um ficheiro da Krea como anexo ou abrir o `url` da sessão para ver os respetivos ficheiros. A media pode aparecer enquanto o turno ainda está em execução.

## Erros

Os erros dos endpoints utilizam `{ "error": "...", "code": "...", "allowedModels": ["..."] }`. Apenas `error` é obrigatório. Um turno que falhe após a submissão aparece, em vez disso, como `status: "failed"` numa resposta de sessão bem-sucedida.

| Estado HTTP | Significado |
| - | - |
| `400` | Corpo JSON mal formado. |
| `401` | Autenticação em falta ou inválida. |
| `402` | Saldo de unidades de computação insuficiente na workspace (`compute_limit`) ou limite de mensagens do plano Free atingido (`free_message_limit`). |
| `403` | Não tem direito ao modelo fixado (`model_not_entitled`); `allowedModels` lista os IDs permitidos. |
| `404` | A sessão não existe ou está inacessível (`not_found`), ou um anexo de ficheiro da Krea não existe ou está inacessível (`attachment_not_found`). |
| `409` | Já existe um turno em curso (`conflict`). |
| `422` | Entrada inválida, ou a aplicação de desktop selecionada não está disponível. |


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