API.

Recebe a telemetria dos seus agentes e coordena a execução deles.

base https://api2.hobots.appauth Bearer <client secret>corpo JSON

Autenticação

Toda requisição autenticada usa o client secret do agente no header Authorization. A mesma chave vale para a telemetria (ingestão) e para as tasks (execução sob demanda).

Header
Authorization: Bearer hb_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Onde encontrar

No app, em Configurações → Agentes. O formato é hb_ seguido de 64 caracteres hexadecimais. Uma chave inativa ou inválida retorna 401.

As chaves são validadas contra o banco e ficam em cache por até 60 segundos. Ao rotacionar ou desativar uma chave, aguarde esse intervalo para a propagação completa.

Convenções

  • Corpo e resposta sempre em JSON.
  • Datas no formato ISO 8601 com offset (ex. 2026-07-23T14:30:00-03:00).
  • A ingestão (/v1/ingest) tem CORS aberto (Access-Control-Allow-Origin: *) e responde ao preflight OPTIONS com 204.
  • Nenhuma resposta é cacheada — todos os endpoints são dinâmicos.

Telemetria

Ingestão de sinais de observabilidade: erros, performance, check-ins de cron e heartbeats de uptime.

POST/v1/ingestTelemetriaBearer

Recebe um envelope com até 50 itens. Cada item é processado de forma independente — falhas isoladas não derrubam o lote.

Corpo — Envelope
{
  "sdk":     { "name": "hobots", "version": "2.0.0" },
  "sent_at": "2026-07-23T14:30:00-03:00",
  "items":   [ /* 1 a 50 itens */ ]
}
Tipos de item
typeO que registra
eventErro ou log. Agrupa por fingerprint, incrementa ocorrências e reabre issues resolvidas como regressão.
transactionMedição de performance com spans.
heartbeatPresença de um agente de uptime.
Exemplo de item — event
{
  "type": "event",
  "payload": {
    "event_id":  "a1b2c3d4e5f6",
    "timestamp": "2026-07-23T14:30:00-03:00",
    "type":      "error",
    "message":   "Falha ao emitir nota fiscal",
    "exception": { "type": "TimeoutError", "value": "gateway não respondeu" },
    "environment": "production"
  }
}
Resposta · 202
{ "accepted": 3 }
Limites & erros

Corpo máx. 1 MB (413) · 1 a 50 itens · JSON inválido 400 · chave inválida 401 · validação 422 { error, details }.

Tasks — execução sob demanda

Coordenação de execuções sob demanda: os agentes buscam trabalho e reportam o andamento de cada rodada.

POST/v1/tasks/pollTasksBearer

O agente anuncia presença e reivindica execuções pendentes. A reivindicação é atômica — cada run vai para um único agente.

Corpo (todos os campos opcionais)
{
  "agent": {
    "instance_id": "worker-01",
    "name":        "Emissor de NF",
    "version":     "1.4.0",
    "host":        "srv-fiscal",
    "tasks":       ["emitir-nf", "conciliar"]
  },
  "max":   1,                       // 1 a 5 · padrão 1
  "tasks": ["emitir-nf"]            // filtra por slugs de tarefa
}
Resposta · 200
{
  "runs": [
    {
      "id":         "run_123",
      "task":       "emitir-nf",
      "params":     { "competencia": "2026-07" },
      "form":       { "id": "form_1", "name": "Dados da NF" },
      "source":     "schedule",
      "created_at": "2026-07-23T14:30:00-03:00"
    }
  ]
}
Limites & erros

Corpo máx. 256 KB (413) · JSON inválido 400 · chave inválida 401 · validação 422.

PATCH/v1/tasks/runs/:idTasksBearer

O agente reporta o andamento de uma execução. running é repetível para enviar logs incrementais; succeeded e failed encerram a run.

Corpo
{
  "status": "failed",              // running · succeeded · failed
  "error":  {                       // apenas com "failed"
    "type":    "TimeoutError",
    "message": "gateway não respondeu",
    "stack":   "..."
  },
  "logs": [                         // até 100 · anexados no servidor
    { "ts": "2026-07-23T14:30:01-03:00", "level": "info", "message": "iniciando" },
    { "ts": "2026-07-23T14:30:04-03:00", "level": "info", "message": "portal carregado",
      "attachments": ["<32 hex>"] } // opcional · até 4 ids de anexo por linha
  ]
}
Resposta · 200
{ "ok": true }
Limites & erros

Corpo máx. 1 MB (413) · run inexistente neste agente 404 · transição inválida (ex. run cancelada) 409 · validação 422. Horários e duration_ms são definidos pelo relógio do servidor.

O campo result foi removido do protocolo por conter dados sensíveis. Se enviado por SDKs antigos, ele é aceito na validação e descartado.

POST/v1/tasks/runs/:id/itemsTasksBearer

Registra em lote os itens processados/gerados pela execução (a entrega do bot — ctx.items no SDK). Insert-only: cada item chega com o status final; id repetido na mesma run é ignorado (retry idempotente).

Corpo
{
  "items": [                           // 1..500 por request
    {
      "id":      "12345",              // identidade do item na run (ex. nº da nota) ou uuid do SDK
      "seq":     0,                    // ordem de emissão no agente
      "status":  "succeeded",          // succeeded · failed · occurrence
      "message": "...",                // opcional · motivo (failed/occurrence) · máx. 2100
      "payload": { "numero_nota": "12345", "cnpj_prestador": "..." }, // opcional · máx. 16 KB
      "ts":      "2026-07-23T14:30:04-03:00" // opcional · relógio do agente, só exibição
    }
  ]
}
Resposta · 200
{ "accepted": 1, "duplicates": 0 }
Limites & erros

Corpo máx. 1 MB (413) · 500 itens por request · 10.000 itens por execução (429, lote inteiro rejeitado) · run inexistente neste agente 404 · validação 422.

Diferente do PATCH de status, uma run cancelada ou finalizada aceita itens (200) — item é fato de trabalho já feito. Esta rota não tem 409. O insert e os contadores da run (items_total/succeeded/failed/occurrence) são atualizados num único statement atômico.

POST/v1/tasks/runs/:id/attachmentsTasksBearer

Registra um anexo de imagem (screenshot) da execução e devolve uma URL assinada de upload (PUT). O binário não passa por esta API — o agente envia direto para o armazenamento de arquivos.

Corpo
{
  "id":           "<32 hex>",     // gerado pelo agente · já citado na linha de log
  "content_type": "image/png",    // image/png | image/jpeg | image/webp
  "size_bytes":   184320,         // exato · entra na assinatura da URL
  "caption":      "portal após o login",   // opcional · máx. 500
  "log_ts":       "2026-07-23T14:30:04-03:00", // opcional
  "width":        1920,           // opcional
  "height":       1080            // opcional
}
Resposta · 200
{
  "id":         "<32 hex>",
  "upload_url": "https://...",    // PUT direto nesta URL · SEM header Authorization
  "headers":    { "content-type": "image/png", "content-length": "184320" },
  "expires_in": 900
}
Limites & erros

PNG, JPEG ou WEBP · 5 MB por imagem · 20 anexos por execução (429) · corpo máx. 8 KB (413) · run inexistente neste agente 404 · id já registrado 409 · validação 422 · anexos não habilitados nesta instalação 503.

O PUT precisa enviar exatamente os headers devolvidos — eles fazem parte da assinatura. O content-length é assinado de propósito: sem ele a URL aceitaria um upload de qualquer tamanho.

PATCH/v1/tasks/runs/:id/attachments/:attachmentIdTasksBearer

Confirma o upload do anexo. É conforto de exibição: enquanto não confirmado, o app mostra a miniatura como “enviando imagem…”.

Corpo
{
  "status":     "uploaded",   // uploaded | failed
  "size_bytes": 184320,       // opcionais · corrigem os metadados do registro
  "width":      1920,
  "height":     1080
}
Resposta · 200
{ "ok": true }
Limites & erros

Anexo inexistente nesta run/agente 404 · validação 422.

Sistema

GET/v1/health

Health check. Sem autenticação.

Resposta · 200
{ "ok": true, "service": "hobots-api" }

Códigos de status

CódigoSignificado
200Sucesso (poll, patch de run, health).
202Envelope aceito para processamento.
204Preflight CORS (OPTIONS).
400JSON inválido.
401Client secret ausente, inválido ou inativo.
404Run ou anexo não encontrado para este agente.
409Transição de status inválida, ou anexo já registrado.
413Corpo acima do limite.
422Falha de validação do schema.
429Limite de anexos por execução atingido.
503Anexos não habilitados nesta instalação (armazenamento de arquivos não configurado).