CRM Oficina Martech
ReferênciaContatos

Buscar contatos por mensagens

GET /contacts/message-search — busca contatos que mencionaram termos específicos em mensagens.

GET/contacts/message-searchBeta

Escopos necessários: contacts:read + messages:read

Retorna contatos de uma organização que mencionaram um termo, frase ou lista de termos em mensagens. Suporta filtros por canal, direção, intervalo de tempo e modo de match (any/all).

Endpoint

GET https://crm.oficinamartech.com/api/v1/contacts/message-search

Query parameters

ParâmetroTipoObrigatórioPadrãoDescrição
organization_idUUID✅—Identificador da organização
qstring (até 200 chars)△—Termo único de busca
keywordsstring (até 1000 chars)△—Lista separada por vírgula, ponto-e-vírgula ou quebra de linha
keywordstring[] (repetível)△—Parâmetro repetível para frases que contêm vírgula
matchany | all❌anyModo de combinação dos termos
directioninbound | outbound | all❌inboundFiltra mensagens recebidas, enviadas ou ambas
channelwhatsapp | whatsapp_cloud_api | instagram | telegram | email❌—Filtra por canal
fromISO 8601 ou YYYY-MM-DD❌—Data inicial (inclusiva)
toISO 8601 ou YYYY-MM-DD❌—Data final (inclusiva)
limitint (1–100)❌50Tamanho da página
offsetint (≥0)❌0Offset de paginação
messages_limitint (0–20)❌3Quantas mensagens de contexto retornar por contato

△ = pelo menos um de q, keywords ou keyword é obrigatório.

Comportamento dos termos

  • Termos são normalizados (lowercase, sem acentos) antes da busca
  • Termos com menos de 2 caracteres são descartados
  • Termos com mais de 200 caracteres são truncados
  • Máximo de 10 termos por requisição; excedentes são ignorados
  • Termos duplicados são removidos

Resposta 200

{
  "data": [
    {
      "contact": {
        "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
        "organization_id": "...",
        "name": "Maria Silva",
        "phone": "+5511999999999",
        "email": "maria@example.com",
        "avatar_url": null,
        "source": "whatsapp"
      },
      "match_count": 3,
      "conversations_count": 2,
      "first_matched_at": "2026-05-15T14:23:00.000Z",
      "last_matched_at": "2026-05-19T18:42:00.000Z",
      "messages": [
        {
          "id": "...",
          "conversation_id": "...",
          "channel": "whatsapp",
          "direction": "inbound",
          "content": "Oi, gostaria de saber mais sobre o Plano Pro",
          "sent_at": "2026-05-19T18:42:00.000Z"
        }
      ]
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "count": 234,
    "has_more": true,
    "next_offset": 50
  },
  "query": {
    "organization_id": "...",
    "terms": ["plano pro"],
    "match": "any",
    "direction": "inbound",
    "channel": null,
    "from": null,
    "to": null
  }
}

Campos

CampoTipoDescrição
data[].contact.idUUIDIdentificador único do contato
data[].contact.namestring?Nome do contato (pode ser null se desconhecido)
data[].contact.phonestring?Telefone E.164 (+5511999999999)
data[].contact.emailstring?Email do contato
data[].contact.sourcestring?Canal de origem do contato
data[].match_countintTotal de mensagens do contato que casaram com os termos
data[].conversations_countintQuantas conversas diferentes contêm os termos
data[].first_matched_atISO 8601Primeira ocorrência dos termos nas mensagens do contato
data[].last_matched_atISO 8601Mais recente ocorrência
data[].messages[]arrayAté messages_limit mensagens mais recentes com o termo
paginationobjectVeja Paginação
queryobjectEco dos parâmetros normalizados

Exemplos

curl -G "https://crm.oficinamartech.com/api/v1/contacts/message-search" \
  -H "Authorization: Bearer $OFM_API_KEY" \
  --data-urlencode "organization_id=$ORG_ID" \
  --data-urlencode "q=orçamento" \
  --data-urlencode "direction=inbound" \
  --data-urlencode "channel=whatsapp" \
  --data-urlencode "from=2026-04-01" \
  --data-urlencode "to=2026-05-20" \
  --data-urlencode "limit=50" \
  --data-urlencode "messages_limit=5"

Múltiplos termos

# Modo "any" — pelo menos um termo
curl -G ".../message-search" \
  --data-urlencode "keywords=Plano Pro,Plano Premium,upgrade" \
  --data-urlencode "match=any"

# Modo "all" — todos os termos
curl -G ".../message-search" \
  --data-urlencode "keywords=preço,desconto" \
  --data-urlencode "match=all"

# Termo com vírgula — usa keyword repetível
curl -G ".../message-search" \
  --data-urlencode "keyword=R$ 1.500, 12x sem juros" \
  --data-urlencode "keyword=preço final"

Códigos de erro específicos

StatusCausa
400organization_id ausente ou não é UUID válido
400Nenhum termo informado (q, keywords e keyword todos vazios)
400from ou to em formato inválido
400from posterior a to
400limit, offset ou messages_limit fora dos limites permitidos
401API key ausente, inválida, revogada ou expirada
403API key sem escopo contacts:read ou messages:read
403API key autorizada mas organization_id é de outra organização
500Erro interno

Veja Códigos de erro para formato completo.

Notas

  • A busca é case-insensitive e diacritic-insensitive (orçamento ≡ Orcamento ≡ ORÇAMENTO)
  • from/to são inclusivos
  • Quando filtra por channel, apenas mensagens daquele canal são consideradas para o match — mas o contato pode ter mensagens em outros canais que não aparecem em messages[]
  • O array messages[] traz as mais recentes que casaram, ordenadas DESC por sent_at

Experimente

Use uma API key dedicada de teste com escopo mínimo. A chave fica em localStorage deste navegador até você remover ou trocar.

Playground · GET /contacts/message-search

Use uma chave de teste dedicada — a chave fica em localStorage deste navegador até você remover.

On this page