Guias · · 6 min de leitura · Time Catcher Agents

Embuta um agente em 3 chamadas:
runtime token, sessão, mensagem

O agente — modelo, prompt, ferramentas, base de conhecimento — vive no Console. O seu app só o dirige: um runtime token, uma sessão por cliente final, uma mensagem. Este guia percorre o fluxo completo contra a API real, incluindo a variante em streaming que entrega token a token e fecha com o custo do turno.

A credencial escolhe o agente; a sessão escolhe a memória; a mensagem dispara o turno.

Contrato mínimo

Três passos, três fronteiras claras

  1. 1 · TokenCredencial prt_ guardada no backend.
  2. 2 · Sessãoend_user_external_id separa a memória.
  3. 3 · MensagemResposta normal ou eventos SSE ao vivo.

Embutir IA num produto costuma virar projeto de meses: orquestração de LLM, memória por usuário, RAG, execução de ferramentas, medição de custo. Na Catcher Agents esse trabalho fica do lado da plataforma. Você monta o agente no Console e o seu backend conversa com ele pela superfície de runtime — /v1/agent-runtime/{id}, na base https://agents-api.catcher.one. O contrato é JSON, a autenticação é um header, e a integração inteira cabe em três chamadas: o token (uma vez, no Console), a sessão e a mensagem.

As duas últimas são HTTP puro e são o que o seu código repete em produção. Nada de SDK obrigatório, nada de webhook para configurar antes do primeiro turno.

Chamada 1 — o agente e o token de runtime (Console, uma vez)

Crie a conta em agents-app.catcher.one/register e monte o agente: nome, modelo, prompt do sistema, ferramentas e base de conhecimento (suba um PDF e a busca híbrida entra automaticamente no turno). Copie o AGENT_ID da URL da página do agente. Depois, na aba de tokens de runtime, gere um token — ele tem prefixo prt_ e aparece uma única vez; guarde num secret manager.

Por que um prt_ e não a API key da conta? Escopo. A API key (ctc_) autentica como a sua conta inteira; o runtime token é preso a um agente. Se vazar, o estrago se limita àquele agente — e você o revoga sem trocar mais nada. A autenticação é pelo header X-Agent-Token, sem cookie e sem CSRF, porque o fluxo é servidor-a-servidor: o token vive no seu backend, nunca no navegador.

Chamada 2 — abra uma sessão por cliente final

Uma sessão é uma conversa. O campo que importa é o end_user_external_id: o identificador estável do seu cliente no seu sistema (o id do usuário no seu banco, por exemplo). Registrá-lo cria ou atualiza o usuário final do agente — e é ele que separa a memória de um cliente da do outro.

curl -X POST https://agents-api.catcher.one/v1/agent-runtime/AGENT_ID/sessions \
  -H "X-Agent-Token: prt_SEU_RUNTIME_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "end_user_external_id": "cliente-42", "title": "Atendimento" }'

A resposta é um 201 Created com o id da sessão:

{ "id": "sess_a1b2c3", "agent_id": "AGENT_ID", "title": "Atendimento", "created_at": "2026-07-02T01:00:00Z" }

O end_user_external_id é a fronteira da memória. Ids diferentes nunca compartilham o que o agente lembra; o mesmo id, semanas depois, reencontra os fatos e preferências consolidados sobre aquela pessoa.

Guarde o sess_…. Você pode manter uma sessão longa por cliente ou abrir uma por atendimento; o title é opcional e serve só para organizar. Se o seu produto é multi-tenant, esse isolamento por usuário final se soma ao isolamento por schema de banco dedicado por tenant.

Chamada 3 — mande a mensagem

curl -X POST https://agents-api.catcher.one/v1/agent-runtime/AGENT_ID/sessions/sess_a1b2c3/messages \
  -H "X-Agent-Token: prt_SEU_RUNTIME_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Qual foi o último pedido do cliente?" }'

É essa chamada que roda o turno completo: o agente recupera a memória daquele cliente, busca na base de conhecimento e executa as ferramentas que precisar antes de responder. Por isso o grupo /v1/agent-runtime roda com timeout estendido de 5 minutos — um turno agêntico pode encadear várias chamadas de LLM. E a posse da sessão é validada a cada request: um token não lê sessões de outro agente.

Pronto — o agente está embutido. Sessão e mensagem são as duas chamadas que o seu backend repete; o histórico fica disponível em GET /v1/agent-runtime/{id}/sessions/{sid}/messages.

A variante para interfaces: streaming (SSE)

A resposta síncrona serve para automações. Numa UI de chat, o usuário quer ver o texto nascendo — e você quer mostrar o que o agente está fazendo enquanto pensa. O mesmo endpoint tem a variante /stream, que responde text/event-stream:

curl -N -X POST \
  https://agents-api.catcher.one/v1/agent-runtime/AGENT_ID/sessions/sess_a1b2c3/messages/stream \
  -H "X-Agent-Token: prt_SEU_RUNTIME_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Resuma os 3 últimos pedidos." }'

O stream abre com um start (a mensagem do usuário ecoada) e fecha com um complete (a resposta final montada). Entre os dois, o agente emite os eventos ao vivo: tool_call_start / tool_call_result (os chips de ferramenta — executando, ok, erro), text_delta (o texto do assistente, aos poucos), round_usage e o done do engine (com o custo agregado). O nome do evento de texto é text_delta, não "token":

event: start
data: {"run_id":"9f2c…","user_message":{"role":"user","content":"Resuma os 3 últimos pedidos."}}

event: tool_call_start
data: {"type":"tool_call_start","tool_call":{"index":0,"id":"tc_1","name":"brain_search","arguments":"{\"q\":\"últimos pedidos\"}"}}

event: tool_call_result
data: {"type":"tool_call_result","tool_result":{"id":"tc_1","name":"brain_search","is_error":false,"duration_ms":142}}

event: text_delta
data: {"type":"text_delta","text":"Os três últimos"}

event: done
data: {"type":"done","rounds":2,"cost":{"total_cost_usd":0.0144},"usage":{"input_tokens":812,"output_tokens":143,"total_tokens":955}}

event: complete
data: {"run_id":"9f2c…","assistant_message":{"role":"assistant","content":"Os três últimos pedidos…"},"usage":{…},"tool_calls":[…]}

Dois detalhes de produção. Primeiro: no fim de um turno bem-sucedido você recebe dois sinais terminais — o done do engine (com o custo agregado em cost.total_cost_usd) e o complete da API (com a assistant_message montada). Pode fechar em qualquer um dos dois. Segundo: uma desconexão do consumidor cancela apenas a cauda do stream — nunca o run, que termina e fica no histórico da sessão. Para logar o custo por cliente com precisão, leia o cost_usd persistido em GET /v1/agents/{id}/runs/{run_id} — o corpo do POST …/messages (sem streaming) não traz o custo inline.

O mesmo fluxo em Node.js

Sem SDK e sem dependências — fetch nativo (Node 18+):

const BASE = 'https://agents-api.catcher.one';
const AGENT_ID = process.env.AGENT_ID;
const TOKEN = process.env.AGENT_RUNTIME_TOKEN; // prt_...

async function api(path, body) {
  const res = await fetch(`${BASE}${path}`, {
    method: 'POST',
    headers: {
      'X-Agent-Token': TOKEN,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  });
  if (!res.ok) {
    const err = await res.json(); // { error_code, message, trace_id }
    throw new Error(`${err.error_code}: ${err.message} (trace ${err.trace_id})`);
  }
  return res.json();
}

// chamada 2 — sessão isolada por cliente final
const session = await api(`/v1/agent-runtime/${AGENT_ID}/sessions`, {
  end_user_external_id: 'cliente-42',
  title: 'Atendimento',
});

// chamada 3 — o turno completo: memória, conhecimento, ferramentas
const reply = await api(
  `/v1/agent-runtime/${AGENT_ID}/sessions/${session.id}/messages`,
  { content: 'Qual foi o último pedido do cliente?' },
);

console.log(reply);

Para consumir o streaming, aponte para .../messages/stream e leia res.body como stream, parseando as linhas event: e data:. O envelope de erro é o mesmo nos dois modos.

Produção: idempotência, envelope de erro e a trava de 402

Três contratos da API seguram a integração em produção:

  • Retry seguro. A API aceita o header Idempotency-Key (é reservado no contrato), mas esta versão não deduplica no servidor — não confie nele para evitar duplicatas. A idempotência que importa aqui é sua: reuse a mesma sessão por cliente (guarde o session.id associado ao seu end_user_external_id) em vez de abrir uma sessão nova a cada mensagem, e trate o reenvio de uma mensagem como uma decisão explícita do seu backend.
  • Envelope de erro com trace_id. Todo erro volta no mesmo formato: um error_code estável para o seu código tratar, uma message legível e um trace_id que casa com o header X-Trace-ID e com a linha de log do lado da plataforma. Guarde o trace_id no seu log — é o identificador que encurta qualquer chamado de suporte.
  • A trava de 402. Orçamento é teto duro, por conta e por agente. Atingiu o teto, a próxima execução para com HTTP 402 e error_code: BUDGET_EXCEEDED (ou AGENT_BUDGET_EXCEEDED no nível do agente) — sem estouro silencioso de custo. Trate 402 como um estado do produto ("assistente pausado por orçamento"), não como erro genérico.
{
  "error_code": "AGENT_INACTIVE",
  "message": "agent is paused",
  "trace_id": "2a62142c-f55f-4db4-8c7b-060018e3ef48",
  "error": "agent is paused"
}

Outros códigos que merecem um caso no seu handler: 404 AGENT_NOT_FOUND (agente inexistente ou fora do escopo do token), 409 AGENT_INACTIVE (agente pausado no Console), 429 RATE_LIMITED e 400 BAD_REQUEST (content vazio, por exemplo). E como cada execução é medida, o custo que aparece no done também aparece agregado nas janelas de 7, 30 e 90 dias da conta — o post sobre quanto custa um agente de IA detalha o metering.

Perguntas frequentes

Posso usar o runtime token no frontend?

Não. O prt_ é uma credencial de servidor: quem o tem dirige o agente. Ele fica no seu backend (variável de ambiente ou secret manager), e o seu frontend fala com o seu backend, que fala com a API de runtime. A autenticação por header sem CSRF existe exatamente para esse fluxo servidor-a-servidor.

O que o end_user_external_id faz exatamente?

Ele registra (ou atualiza) o usuário final do agente e é a chave da memória. Use o id estável do seu cliente no seu sistema. Cada id tem memória isolada: o agente lembra de cada cliente separadamente, entre sessões e entre dias.

O que acontece quando o orçamento estoura?

A próxima execução para com HTTP 402. O teto da conta é configurado em GET e PUT /v1/agents/budget; o teto de um agente fica no campo monthly_budget_usd da configuração dele. Ajustado o cap correto, o próximo turno passa. Não existe estouro silencioso de custo.

Embutir é o caminho curto

A superfície /v1/agent-runtime está em produção, com um SaaS real dirigindo agentes por ela. A referência completa — sessões, streaming, conhecimento, uso e budget — está na documentação da API.

Continue lendo

Arquitetura

Agentes multi-tenant com schema dedicado

Cada cliente final do seu produto num schema de banco próprio — o isolamento que software houses precisam.

Operação

Quanto custa um agente de IA?

Metering por execução, cost_usd por turno e o budget que para tudo com 402.