Growth OS API
Referência da APIInterações

Listar interações (linha do tempo global por período)

Toda interação com contatos do workspace, mais recente primeiro (`createdAt DESC, id DESC`). Mensagem do inbox: `createdAt` é a data do ENVIO registrada pelo provedor — o histórico importado do GHL sai na data original, não na do import. No histórico importado, `actor` vem do `source` do CRM antigo quando não há carimbo de autor: workflow/campanha/disparo em massa = `automation`, api = `api`. paginada por cursor. Fontes: mensagens do inbox (WhatsApp/Instagram/Facebook, e as conversas de canal `phone` — importadas ou abertas pela telefonia), ligações, e-mails (resposta enviada pelo painel, resposta recebida do contato, e-mail de automação) e notas. `id` = `<fonte>:<id da linha>`. `actor` diz QUEM agiu: `user` = pessoa do time no app (só quando o `userId` de quem mandou está gravado); `contact` = o lead (toda interação `inbound`); `ia` / `automation` / `system` / `api` = robôs; `unknown` = mensagem outbound sem autor conhecido (histórico antigo, importado sem `source` reconhecido, ou sem carimbo). `userId` é o usuário do app que mandou — carimbado no MOMENTO DO ENVIO, imutável, e só preenchido com `actor=user`. Para o Speed-to-Lead, filtre `direction=outbound&actor=user`. Mensagem do inbox: `userId` NUNCA é inferido do responsável atual da conversa — antes de 0728 (issue #728) uma mensagem sem carimbo saía atribuída a quem estivesse dono do atendimento NA HORA DA CONSULTA, e o valor mudava sozinho quando a conversa era reatribuída (bug medido pelo cliente: pior que devolver vazio numa auditoria de comissão). Hoje, sem carimbo, `userId: null` e `actor: "unknown"`. `conversationAssigneeUserId` é o campo separado e honesto pra "quem é o dono do atendimento HOJE" — mutável, não é quem mandou. `channelInstanceId` (id da conexão) e `senderPhone` (o número/identificador dela) ajudam a resolver a autoria sem depender de quem digitou, quando a linha do SDR é separada da dos closers; `null` quando a mensagem não tem conexão associada ou a fonte não é mensagem de inbox. Ligação: `durationSec` (segundos) e `status` = `answered` | `no_answer` | demais estados crus do provedor (ex.: `ringing`). NÃO entram: campanhas de e-mail em massa, tarefas, reuniões (vivem em `/appointments`) e os marcadores internos do fio da conversa ("Automação X rodou", "Reunião cancelada", "Negócio foi de A para B", atribuição de atendente) — são anotação para quem atende, nunca chegam ao contato. `opportunityId` só vem preenchido na nota; nas demais o vínculo com o negócio é pelo `contactId`. Filtros: `contactId`, `userId`, `channel` (CSV de whatsapp,instagram,facebook,phone,call,email,note), `direction`, `actor`, `createdAfter` / `createdBefore` (ISO-8601, exclusivos). `limit` até 500.

GET
/interactions

Toda interação com contatos do workspace, mais recente primeiro (createdAt DESC, id DESC). Mensagem do inbox: createdAt é a data do ENVIO registrada pelo provedor — o histórico importado do GHL sai na data original, não na do import. No histórico importado, actor vem do source do CRM antigo quando não há carimbo de autor: workflow/campanha/disparo em massa = automation, api = api. paginada por cursor. Fontes: mensagens do inbox (WhatsApp/Instagram/Facebook, e as conversas de canal phone — importadas ou abertas pela telefonia), ligações, e-mails (resposta enviada pelo painel, resposta recebida do contato, e-mail de automação) e notas. id = <fonte>:<id da linha>.

actor diz QUEM agiu: user = pessoa do time no app (só quando o userId de quem mandou está gravado); contact = o lead (toda interação inbound); ia / automation / system / api = robôs; unknown = mensagem outbound sem autor conhecido (histórico antigo, importado sem source reconhecido, ou sem carimbo). userId é o usuário do app que mandou — carimbado no MOMENTO DO ENVIO, imutável, e só preenchido com actor=user. Para o Speed-to-Lead, filtre direction=outbound&actor=user.

Mensagem do inbox: userId NUNCA é inferido do responsável atual da conversa — antes de 0728 (issue #728) uma mensagem sem carimbo saía atribuída a quem estivesse dono do atendimento NA HORA DA CONSULTA, e o valor mudava sozinho quando a conversa era reatribuída (bug medido pelo cliente: pior que devolver vazio numa auditoria de comissão). Hoje, sem carimbo, userId: null e actor: "unknown". conversationAssigneeUserId é o campo separado e honesto pra "quem é o dono do atendimento HOJE" — mutável, não é quem mandou. channelInstanceId (id da conexão) e senderPhone (o número/identificador dela) ajudam a resolver a autoria sem depender de quem digitou, quando a linha do SDR é separada da dos closers; null quando a mensagem não tem conexão associada ou a fonte não é mensagem de inbox.

Ligação: durationSec (segundos) e status = answered | no_answer | demais estados crus do provedor (ex.: ringing).

NÃO entram: campanhas de e-mail em massa, tarefas, reuniões (vivem em /appointments) e os marcadores internos do fio da conversa ("Automação X rodou", "Reunião cancelada", "Negócio foi de A para B", atribuição de atendente) — são anotação para quem atende, nunca chegam ao contato. opportunityId só vem preenchido na nota; nas demais o vínculo com o negócio é pelo contactId.

Filtros: contactId, userId, channel (CSV de whatsapp,instagram,facebook,phone,call,email,note), direction, actor, createdAfter / createdBefore (ISO-8601, exclusivos). limit até 500.

AutorizaçãoBearer <token>

Chave de API (gos_…)

Em: header

Parâmetros de consulta

contactId?string
Length1 <= length <= 80
userId?string
Length1 <= length <= 80
channel?string
Length1 <= length <= 120
direction?string

Value in

  • "inbound"
  • "outbound"
actor?string

Value in

  • "user"
  • "contact"
  • "ia"
  • "automation"
  • "system"
  • "api"
  • "unknown"
createdAfter?string
createdBefore?string
cursor?string
limit?integer
Range1 <= value <= 500
Default100

Corpo da resposta

application/json

curl -X GET "https://example.com/interactions"
{  "data": [    {      "id": "string",      "kind": "message",      "channel": "string",      "direction": "inbound",      "actor": "user",      "userId": "string",      "contactId": "string",      "opportunityId": "string",      "conversationId": "string",      "conversationAssigneeUserId": "string",      "channelInstanceId": "string",      "senderPhone": "string",      "createdAt": "string",      "durationSec": -9007199254740991,      "status": "string",      "preview": "string"    }  ],  "nextCursor": "string"}