DocumentaçãoEnviar dados

API REST

Envie eventos de qualquer stack com POST /api/v1/events: envelope, autenticação, envio em lote e deduplicação idempotente.

Toda entrada de dados na Holdy converge em um endpoint HTTP. Se o SDK não cobre a sua stack, fale direto com ele.

Endpoint

POST https://holdy.chat/api/v1/events
Authorization: Bearer hol_live_...
Content-Type: application/json

Sucesso responde 202 com { ok, event_id, ingested_at }. Erros seguem RFC 7807 (problem+json) com status 400, 401 ou 500.

Envelope

CampoTipoObrigatórioSemântica
eventstringsimNome do evento, sem canonicalização ("invite_sent", "workflow.blocked").
occurred_atISO 8601—Quando ocorreu no seu produto. Default: horário do servidor. Mande sempre que usar external_id: a deduplicação compara os dois.
user_idstring ≤200—ID do usuário final no seu produto.
anonymous_idstring ≤200—ID persistido no browser antes do login.
propertiesobject—Propriedades livres do evento. Default {}.
contextobject—Metadata (página, device). Use context.account_external_id para associar a conta pela chave do seu produto.
external_idstring ≤200—ID do evento na origem, para deduplicação idempotente.

Exemplo

curl -X POST https://holdy.chat/api/v1/events \
  -H "Authorization: Bearer hol_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "event": "invite_sent",
    "occurred_at": "2026-10-05T14:32:00Z",
    "user_id": "user_42",
    "properties": { "plan": "pro" },
    "context": { "account_external_id": "acme-inc" },
    "external_id": "invite-8812"
  }'

Envio em lote

POST /api/v1/events/bulk aceita um array de até 500 envelopes. A aceitação é parcial: eventos inválidos voltam em rejected com o índice, os demais entram. Reenviar o batch inteiro após uma falha é seguro.

Deduplicação

Envie external_id e occurred_at juntos: o mesmo evento reenviado com os dois iguais responde 202 com deduped: true em vez de duplicar, o que deixa retries e backfills seguros. Use o horário em que o evento aconteceu no seu produto, guardado junto do registro, e não o horário do envio.

Sem occurred_at, cada envio recebe o horário do servidor e o reenvio entra como evento novo, mesmo com o mesmo external_id. Eventos sem external_id nunca colidem entre si.

Identidade

Envie os IDs que você tem (user_id, anonymous_id, properties.email, context.account_external_id) e a Holdy resolve usuário e conta do lado dela. Você nunca precisa conhecer IDs internos da Holdy.

Lendo o que a Holdy encontrou

O que entra por eventos sai por oportunidades e sinais. Use a chave secreta (escopo behavior:read) para levar o resultado pro seu CRM, planilha ou job — a organização vem da chave, nunca do parâmetro.

curl https://holdy.chat/api/v1/opportunities?status=open \
  -H "Authorization: Bearer hol_live_..."

Aceita status, since (ISO 8601), limit (até 200) e cursor. A resposta traz next_cursor enquanto houver página seguinte — o cursor é keyset sobre data e id, então nenhuma linha se perde entre páginas mesmo com registros criados no mesmo instante.

GET /api/v1/signals segue as mesmas regras e aceita ainda type e severity. Sinal é mudança e expira: cada um traz expires_at, e por padrão só vêm os ativos. Sinal com advisory: true informa e nunca vira oportunidade.

Toda oportunidade e todo sinal trazem evidence_ref. Para abrir a prova por trás do achado, chame GET /api/v1/evidence/opportunity/{id} — a resposta resolve as referências em evidência completa.

Atualizado em 27 de agosto de 2026