LYMOS CRM · API

API do LYMOS CRM

Versão 1 · atualizada em 12 de outubro de 2026

Ligue o CRM ao seu site, loja virtual, ERP, planilha, n8n ou Make. Cadastre contatos, mude etapas, ponha etiquetas, mande mensagens de WhatsApp e dispare fluxos e automações. Quando algo acontece no CRM, ele avisa o seu sistema por webhook.

Primeiros passos

  1. No CRM, abra Ajustes > Integrações e, em API, clique em Gerar token. Copie na hora: ele aparece uma vez só.
  2. Use a URL base https://crm.lymos.com.br/api/v1 com o cabeçalho Authorization: Bearer crm_SEU_TOKEN.
  3. Teste listando as etapas do funil:
curl 'https://crm.lymos.com.br/api/v1/stages' -H 'Authorization: Bearer crm_SEU_TOKEN'

Corpo e respostas em JSON. Datas em milissegundos (Unix ms). Telefones só com dígitos, com DDI e DDD: 5511999990000.

Integrar com IA (ChatGPT, Claude, Gemini, Cursor)

A documentação inteira está num arquivo pensado para IA: https://crm.lymos.com.br/llms-full.txt. Cole este pedido na sua IA e troque o trecho entre colchetes:

Quero integrar meu sistema ao LYMOS CRM. Leia a documentação completa em https://crm.lymos.com.br/llms-full.txt (é a referência oficial da API REST) e me ajude a: [descreva aqui, ex.: "mandar para o CRM todo lead do formulário do meu site, com a etiqueta Site"]. Use o token pela variável de ambiente LYMOS_TOKEN e nunca o escreva no código.

Também há o llms.txt (índice) e o OpenAPI 3.1 para Postman, Insomnia ou gerar cliente.

Autenticação

Toda chamada leva o token no cabeçalho Authorization: Bearer <token> (ou X-API-Key: <token>). Cada token é de uma conta e só enxerga os dados dela. Guarde o token numa variável de ambiente e nunca o coloque em código que roda no navegador. Se vazar, apague-o em Ajustes > Integrações e gere outro.

Contatos

GET/contactsListar e buscar contatos

Devolve os contatos não arquivados, do mais recente para o mais antigo.

Parâmetros de consulta

CampoTipoDescrição
qtextoBusca no nome, nome do WhatsApp, empresa e e-mail
phonetextoTelefone (só os dígitos contam; acha pelo final do número)
tagtexto ou númeroNome ou id de uma etiqueta
limitnúmeroQuantos devolver (padrão 50, máximo 500)
offsetnúmeroPular os primeiros N (paginação)
curl -X GET 'https://crm.lymos.com.br/api/v1/contacts?tag=Lead%20quente&limit=20' \
  -H 'Authorization: Bearer crm_SEU_TOKEN'

Resposta

{
  "items": [
    {
      "id": 128,
      "name": "Ana Souza",
      "display_name": "Ana Souza",
      "phone": "5511999990000",
      "email": "ana@exemplo.com.br",
      "company": "Loja da Ana",
      "role": "Sócia",
      "city": "São Paulo",
      "birthday": "1990-05-14",
      "how_met": "Instagram",
      "stage_id": 3,
      "deal_value": 49700,
      "cadence_days": 15,
      "starred": false,
      "archived": false,
      "custom": {
        "plano_interesse": "Profissional"
      },
      "tags": [
        {
          "id": 7,
          "name": "Lead quente",
          "color": "#e5484d"
        }
      ],
      "last_message_at": 1791846000000,
      "created_at": 1791800000000,
      "updated_at": 1791846000000
    }
  ]
}

GET/contacts/{id}Ver um contato

Ficha completa do contato, com etiquetas e campos personalizados.

curl -X GET 'https://crm.lymos.com.br/api/v1/contacts/128' \
  -H 'Authorization: Bearer crm_SEU_TOKEN'

Resposta

{
  "id": 128,
  "name": "Ana Souza",
  "display_name": "Ana Souza",
  "phone": "5511999990000",
  "email": "ana@exemplo.com.br",
  "company": "Loja da Ana",
  "role": "Sócia",
  "city": "São Paulo",
  "birthday": "1990-05-14",
  "how_met": "Instagram",
  "stage_id": 3,
  "deal_value": 49700,
  "cadence_days": 15,
  "starred": false,
  "archived": false,
  "custom": {
    "plano_interesse": "Profissional"
  },
  "tags": [
    {
      "id": 7,
      "name": "Lead quente",
      "color": "#e5484d"
    }
  ],
  "last_message_at": 1791846000000,
  "created_at": 1791800000000,
  "updated_at": 1791846000000
}

POST/contactsCriar ou atualizar pelo telefone

Se já existe um contato com esse WhatsApp, ele é atualizado (resposta 200); senão, é criado (201) e as automações de "Contato novo" rodam. Mande phone com DDI e DDD. Sem phone, name é obrigatório e o contato é criado sem WhatsApp.

Corpo (JSON)

CampoTipoDescrição
phonetextoWhatsApp com DDI, ex.: 5511999990000
nametextoNome
emailtextoE-mail
companytextoEmpresa
roletextoCargo
citytextoCidade
birthdaytextoAniversário: AAAA-MM-DD ou --MM-DD
how_mettextoComo conheceu / origem
deal_valuenúmeroValor do negócio em centavos (49700 = R$ 497,00)
cadence_daysnúmeroFalar com ele a cada N dias
stage_idnúmeroEtapa do funil (veja GET /stages)
tagslistaEtiquetas por nome (cria se não existir) ou id
customobjetoCampos personalizados: { "campo": "valor" }
curl -X POST 'https://crm.lymos.com.br/api/v1/contacts' \
  -H 'Authorization: Bearer crm_SEU_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"phone":"5511999990000","name":"Ana Souza","company":"Loja da Ana","tags":["Site","Lead quente"],"custom":{"plano_interesse":"Profissional"}}'

Resposta

{
  "id": 128,
  "name": "Ana Souza",
  "display_name": "Ana Souza",
  "phone": "5511999990000",
  "email": "ana@exemplo.com.br",
  "company": "Loja da Ana",
  "role": "Sócia",
  "city": "São Paulo",
  "birthday": "1990-05-14",
  "how_met": "Instagram",
  "stage_id": 3,
  "deal_value": 49700,
  "cadence_days": 15,
  "starred": false,
  "archived": false,
  "custom": {
    "plano_interesse": "Profissional"
  },
  "tags": [
    {
      "id": 7,
      "name": "Lead quente",
      "color": "#e5484d"
    }
  ],
  "last_message_at": 1791846000000,
  "created_at": 1791800000000,
  "updated_at": 1791846000000
}

PATCH/contacts/{id}Atualizar um contato

Mude só os campos que mandar (os mesmos do POST, menos phone). Mandar "" apaga o campo.

curl -X PATCH 'https://crm.lymos.com.br/api/v1/contacts/128' \
  -H 'Authorization: Bearer crm_SEU_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"stage_id":4,"deal_value":99700}'

Resposta

{
  "id": 128,
  "name": "Ana Souza",
  "display_name": "Ana Souza",
  "phone": "5511999990000",
  "email": "ana@exemplo.com.br",
  "company": "Loja da Ana",
  "role": "Sócia",
  "city": "São Paulo",
  "birthday": "1990-05-14",
  "how_met": "Instagram",
  "stage_id": 3,
  "deal_value": 49700,
  "cadence_days": 15,
  "starred": false,
  "archived": false,
  "custom": {
    "plano_interesse": "Profissional"
  },
  "tags": [
    {
      "id": 7,
      "name": "Lead quente",
      "color": "#e5484d"
    }
  ],
  "last_message_at": 1791846000000,
  "created_at": 1791800000000,
  "updated_at": 1791846000000
}

Etiquetas

POST/contacts/{id}/tagsPôr uma etiqueta

Por nome (cria a etiqueta se não existir) ou por id. Pode disparar automações de "Tag adicionada".

Corpo (JSON)

CampoTipoDescrição
nametextoNome da etiqueta
tag_idnúmeroOu o id de uma etiqueta existente
curl -X POST 'https://crm.lymos.com.br/api/v1/contacts/128/tags' \
  -H 'Authorization: Bearer crm_SEU_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Cliente"}'

Resposta

{
  "id": 128,
  "name": "Ana Souza",
  "display_name": "Ana Souza",
  "phone": "5511999990000",
  "email": "ana@exemplo.com.br",
  "company": "Loja da Ana",
  "role": "Sócia",
  "city": "São Paulo",
  "birthday": "1990-05-14",
  "how_met": "Instagram",
  "stage_id": 3,
  "deal_value": 49700,
  "cadence_days": 15,
  "starred": false,
  "archived": false,
  "custom": {
    "plano_interesse": "Profissional"
  },
  "tags": [
    {
      "id": 7,
      "name": "Lead quente",
      "color": "#e5484d"
    }
  ],
  "last_message_at": 1791846000000,
  "created_at": 1791800000000,
  "updated_at": 1791846000000
}

DELETE/contacts/{id}/tags/{tagId}Tirar uma etiqueta

curl -X DELETE 'https://crm.lymos.com.br/api/v1/contacts/128/tags/7' \
  -H 'Authorization: Bearer crm_SEU_TOKEN'

Resposta

{
  "id": 128,
  "name": "Ana Souza",
  "display_name": "Ana Souza",
  "phone": "5511999990000",
  "email": "ana@exemplo.com.br",
  "company": "Loja da Ana",
  "role": "Sócia",
  "city": "São Paulo",
  "birthday": "1990-05-14",
  "how_met": "Instagram",
  "stage_id": 3,
  "deal_value": 49700,
  "cadence_days": 15,
  "starred": false,
  "archived": false,
  "custom": {
    "plano_interesse": "Profissional"
  },
  "tags": [
    {
      "id": 7,
      "name": "Lead quente",
      "color": "#e5484d"
    }
  ],
  "last_message_at": 1791846000000,
  "created_at": 1791800000000,
  "updated_at": 1791846000000
}

GET/tagsListar etiquetas

curl -X GET 'https://crm.lymos.com.br/api/v1/tags' \
  -H 'Authorization: Bearer crm_SEU_TOKEN'

Resposta

{
  "items": [
    {
      "id": 7,
      "name": "Lead quente",
      "color": "#e5484d"
    }
  ]
}

Funil

GET/stagesListar etapas do funil

kind: open (em andamento), won (ganho) ou lost (perdido).

curl -X GET 'https://crm.lymos.com.br/api/v1/stages' \
  -H 'Authorization: Bearer crm_SEU_TOKEN'

Resposta

{
  "items": [
    {
      "id": 3,
      "name": "Proposta",
      "kind": "open"
    }
  ]
}

Conversa

POST/contacts/{id}/messagesEnviar mensagem de WhatsApp

Manda um texto pelo WhatsApp conectado, como se fosse você. Respeita os limites de envio da conta. No WhatsApp oficial (API da Meta), fora da janela de 24 horas só modelos aprovados são entregues: use um fluxo ou automação com modelo.

Corpo (JSON)

CampoTipoDescrição
text obrigatóriotextoMensagem
curl -X POST 'https://crm.lymos.com.br/api/v1/contacts/128/messages' \
  -H 'Authorization: Bearer crm_SEU_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"text":"Oi, Ana! Seu pedido saiu para entrega."}'

Resposta

{
  "id": 5521,
  "contact_id": 128,
  "from_me": true,
  "type": "text",
  "body": "Oi, Ana! Seu pedido saiu para entrega.",
  "sent_by": "api",
  "status": "pending"
}

GET/contacts/{id}/messagesLer as últimas mensagens

Da mais nova para a mais antiga. ts em milissegundos.

Parâmetros de consulta

CampoTipoDescrição
limitnúmeroQuantas (padrão 50, máximo 500)
curl -X GET 'https://crm.lymos.com.br/api/v1/contacts/128/messages?limit=10' \
  -H 'Authorization: Bearer crm_SEU_TOKEN'

Resposta

{
  "items": [
    {
      "id": 5520,
      "wa_id": "3EB0…",
      "from_me": false,
      "type": "text",
      "body": "Qual o prazo de entrega?",
      "status": null,
      "sent_by": null,
      "ts": 1791845900000
    }
  ]
}

POST/contacts/{id}/notesAnotar na ficha

Corpo (JSON)

CampoTipoDescrição
body obrigatóriotextoTexto da nota
curl -X POST 'https://crm.lymos.com.br/api/v1/contacts/128/notes' \
  -H 'Authorization: Bearer crm_SEU_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"body":"Pediu orçamento pelo site: 3 usuários."}'

Resposta

{
  "id": 902,
  "contact_id": 128,
  "body": "Pediu orçamento pelo site: 3 usuários.",
  "pinned": 0
}

POST/contacts/{id}/remindersCriar tarefa / lembrete

Corpo (JSON)

CampoTipoDescrição
title obrigatóriotextoO que fazer
due_at obrigatórionúmero ou dataQuando: milissegundos ou data ISO (2026-10-20T14:00:00-03:00)
curl -X POST 'https://crm.lymos.com.br/api/v1/contacts/128/reminders' \
  -H 'Authorization: Bearer crm_SEU_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Ligar para fechar","due_at":"2026-10-20T14:00:00-03:00"}'

Resposta

{
  "id": 77,
  "contact_id": 128,
  "title": "Ligar para fechar",
  "due_at": 1792515600000
}

Fluxos e automações

POST/contacts/{id}/flows/{flowId}Iniciar um fluxo de atendimento

O id do fluxo aparece no endereço da tela do fluxo. Responde 409 com o motivo quando o contato não pode entrar (ex.: já está nesse fluxo).

Corpo (JSON)

CampoTipoDescrição
forcesim/nãoIniciar mesmo se ele já passou por esse fluxo
curl -X POST 'https://crm.lymos.com.br/api/v1/contacts/128/flows/12' \
  -H 'Authorization: Bearer crm_SEU_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{}'

Resposta

{
  "ok": true
}

POST/automations/{id}/runRodar uma automação para um contato

Roda as ações da automação agora. O que mandar em data fica disponível nas mensagens como {{dados.campo}}. status volta ok, ou skipped com o motivo em detail (ex.: condições não atendidas).

Corpo (JSON)

CampoTipoDescrição
contact_id obrigatórionúmeroContato
dataobjetoDados extras para as mensagens
forcesim/nãoIgnorar condições e limite de repetição
curl -X POST 'https://crm.lymos.com.br/api/v1/automations/5/run' \
  -H 'Authorization: Bearer crm_SEU_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"contact_id":128,"data":{"pedido":"1043"}}'

Resposta

{
  "status": "ok",
  "detail": "Enviou a mensagem \"Seu pedido 1043 foi confirmado\""
}

Webhooks de saída

O CRM avisa o seu sistema quando algo acontece. Cadastre a URL em Ajustes > Integrações > Webhooks e escolha os eventos (ou todos). Chega um POST em JSON:

{
  "event": "contact.tag_added",
  "sent_at": "2026-10-12T20:15:00.000Z",
  "tagId": 7,
  "contact": {
    "id": 128,
    "name": "Ana Souza",
    "display_name": "Ana Souza",
    "phone": "5511999990000",
    "email": "ana@exemplo.com.br",
    "company": "Loja da Ana",
    "role": "Sócia",
    "city": "São Paulo",
    "birthday": "1990-05-14",
    "how_met": "Instagram",
    "stage_id": 3,
    "deal_value": 49700,
    "cadence_days": 15,
    "starred": false,
    "archived": false,
    "custom": {
      "plano_interesse": "Profissional"
    },
    "tags": [
      {
        "id": 7,
        "name": "Lead quente",
        "color": "#e5484d"
      }
    ],
    "last_message_at": 1791846000000,
    "created_at": 1791800000000,
    "updated_at": 1791846000000
  }
}

Cabeçalhos: X-CRM-Event (o evento) e X-CRM-Signature: sha256=<hmac>, o HMAC-SHA256 do corpo cru com o segredo do webhook. Responda 2xx em até 15 segundos. Falhas de rede, 5xx e 429 são tentadas de novo até 3 vezes.

EventoQuando
message.receivedChegou mensagem de um contato
message.sentUma mensagem foi enviada
contact.createdContato novo
contact.updatedFicha alterada
contact.stage_changedMudou de etapa no funil
contact.tag_addedGanhou etiqueta
contact.tag_removedPerdeu etiqueta
contact.assignedConversa atribuída a alguém da equipe
reminder.createdTarefa criada
reminder.doneTarefa concluída
flow.completedContato terminou um fluxo
flow.handoffFluxo ou IA pediu atendimento humano

Conferir a assinatura (Node.js)

import crypto from 'node:crypto';

// corpo = o texto cru recebido (antes do JSON.parse); segredo = o do webhook no CRM
function assinaturaOk(corpo, cabecalho, segredo) {
  const esperado = 'sha256=' + crypto.createHmac('sha256', segredo).update(corpo).digest('hex');
  return cabecalho && crypto.timingSafeEqual(Buffer.from(cabecalho), Buffer.from(esperado));
}

Webhook de entrada

Para o seu sistema disparar uma automação sem token: em Automação > Automações, crie uma automação com o gatilho Outro sistema chamou. Ela ganha uma URL secreta. Mande phone (ou contact_id), name e o que mais quiser: cada campo vira {{dados.campo}} nas mensagens. Contato que não existe é criado. Use dedupe_key para não rodar duas vezes o mesmo evento.

curl -X POST 'https://crm.lymos.com.br/hooks/in/SEU_SEGREDO' \
  -H 'Content-Type: application/json' \
  -d '{"phone":"5511999990000","name":"Ana Souza","pedido":"1043","dedupe_key":"pedido-1043"}'

Resposta 200 com o resultado, ou 202 {"status":"queued"} quando o envio ainda está acontecendo.

Erros

Status HTTP mais {"error": "mensagem em português"}.

StatusSignificado
400Faltou um campo obrigatório ou ele veio errado. A mensagem diz qual.
401Sem token ou token inválido.
404Contato, fluxo ou automação não existe nesta conta.
409Não deu para fazer agora (ex.: fluxo não iniciado, automação desligada). A mensagem diz o motivo.
5xxErro do nosso lado. Tente de novo em alguns segundos.

Boas práticas