API do LYMOS CRM
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
- No CRM, abra Ajustes > Integrações e, em API, clique em Gerar token. Copie na hora: ele aparece uma vez só.
- Use a URL base
https://crm.lymos.com.br/api/v1com o cabeçalhoAuthorization: Bearer crm_SEU_TOKEN. - 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.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.
| Campo | Tipo | Descrição |
|---|---|---|
q | texto | Busca no nome, nome do WhatsApp, empresa e e-mail |
phone | texto | Telefone (só os dígitos contam; acha pelo final do número) |
tag | texto ou número | Nome ou id de uma etiqueta |
limit | número | Quantos devolver (padrão 50, máximo 500) |
offset | número | Pular 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'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts?tag=Lead%20quente&limit=20', {
method: 'GET',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN },
});
const dados = await res.json();import os, requests
r = requests.get(
"https://crm.lymos.com.br/api/v1/contacts?tag=Lead%20quente&limit=20",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
)
dados = r.json(){
"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'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts/128', {
method: 'GET',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN },
});
const dados = await res.json();import os, requests
r = requests.get(
"https://crm.lymos.com.br/api/v1/contacts/128",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
)
dados = r.json(){
"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.
| Campo | Tipo | Descrição |
|---|---|---|
phone | texto | WhatsApp com DDI, ex.: 5511999990000 |
name | texto | Nome |
email | texto | |
company | texto | Empresa |
role | texto | Cargo |
city | texto | Cidade |
birthday | texto | Aniversário: AAAA-MM-DD ou --MM-DD |
how_met | texto | Como conheceu / origem |
deal_value | número | Valor do negócio em centavos (49700 = R$ 497,00) |
cadence_days | número | Falar com ele a cada N dias |
stage_id | número | Etapa do funil (veja GET /stages) |
tags | lista | Etiquetas por nome (cria se não existir) ou id |
custom | objeto | Campos 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"}}'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN, 'Content-Type': 'application/json' },
body: JSON.stringify({"phone":"5511999990000","name":"Ana Souza","company":"Loja da Ana","tags":["Site","Lead quente"],"custom":{"plano_interesse":"Profissional"}}),
});
const dados = await res.json();import os, requests
r = requests.post(
"https://crm.lymos.com.br/api/v1/contacts",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
json={"phone":"5511999990000","name":"Ana Souza","company":"Loja da Ana","tags":["Site","Lead quente"],"custom":{"plano_interesse":"Profissional"}},
)
dados = r.json(){
"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}'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts/128', {
method: 'PATCH',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN, 'Content-Type': 'application/json' },
body: JSON.stringify({"stage_id":4,"deal_value":99700}),
});
const dados = await res.json();import os, requests
r = requests.patch(
"https://crm.lymos.com.br/api/v1/contacts/128",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
json={"stage_id":4,"deal_value":99700},
)
dados = r.json(){
"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
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'const res = await fetch('https://crm.lymos.com.br/api/v1/stages', {
method: 'GET',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN },
});
const dados = await res.json();import os, requests
r = requests.get(
"https://crm.lymos.com.br/api/v1/stages",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
)
dados = r.json(){
"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.
| Campo | Tipo | Descrição |
|---|---|---|
text obrigatório | texto | Mensagem |
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."}'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts/128/messages', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN, 'Content-Type': 'application/json' },
body: JSON.stringify({"text":"Oi, Ana! Seu pedido saiu para entrega."}),
});
const dados = await res.json();import os, requests
r = requests.post(
"https://crm.lymos.com.br/api/v1/contacts/128/messages",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
json={"text":"Oi, Ana! Seu pedido saiu para entrega."},
)
dados = r.json(){
"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.
| Campo | Tipo | Descrição |
|---|---|---|
limit | número | Quantas (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'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts/128/messages?limit=10', {
method: 'GET',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN },
});
const dados = await res.json();import os, requests
r = requests.get(
"https://crm.lymos.com.br/api/v1/contacts/128/messages?limit=10",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
)
dados = r.json(){
"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
| Campo | Tipo | Descrição |
|---|---|---|
body obrigatório | texto | Texto 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."}'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts/128/notes', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN, 'Content-Type': 'application/json' },
body: JSON.stringify({"body":"Pediu orçamento pelo site: 3 usuários."}),
});
const dados = await res.json();import os, requests
r = requests.post(
"https://crm.lymos.com.br/api/v1/contacts/128/notes",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
json={"body":"Pediu orçamento pelo site: 3 usuários."},
)
dados = r.json(){
"id": 902,
"contact_id": 128,
"body": "Pediu orçamento pelo site: 3 usuários.",
"pinned": 0
}POST/contacts/{id}/remindersCriar tarefa / lembrete
| Campo | Tipo | Descrição |
|---|---|---|
title obrigatório | texto | O que fazer |
due_at obrigatório | número ou data | Quando: 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"}'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts/128/reminders', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN, 'Content-Type': 'application/json' },
body: JSON.stringify({"title":"Ligar para fechar","due_at":"2026-10-20T14:00:00-03:00"}),
});
const dados = await res.json();import os, requests
r = requests.post(
"https://crm.lymos.com.br/api/v1/contacts/128/reminders",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
json={"title":"Ligar para fechar","due_at":"2026-10-20T14:00:00-03:00"},
)
dados = r.json(){
"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).
| Campo | Tipo | Descrição |
|---|---|---|
force | sim/não | Iniciar 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 '{}'const res = await fetch('https://crm.lymos.com.br/api/v1/contacts/128/flows/12', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN, 'Content-Type': 'application/json' },
body: JSON.stringify({}),
});
const dados = await res.json();import os, requests
r = requests.post(
"https://crm.lymos.com.br/api/v1/contacts/128/flows/12",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
json={},
)
dados = r.json(){
"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).
| Campo | Tipo | Descrição |
|---|---|---|
contact_id obrigatório | número | Contato |
data | objeto | Dados extras para as mensagens |
force | sim/não | Ignorar 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"}}'const res = await fetch('https://crm.lymos.com.br/api/v1/automations/5/run', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.LYMOS_TOKEN, 'Content-Type': 'application/json' },
body: JSON.stringify({"contact_id":128,"data":{"pedido":"1043"}}),
});
const dados = await res.json();import os, requests
r = requests.post(
"https://crm.lymos.com.br/api/v1/automations/5/run",
headers={"Authorization": "Bearer " + os.environ["LYMOS_TOKEN"]},
json={"contact_id":128,"data":{"pedido":"1043"}},
)
dados = r.json(){
"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.
| Evento | Quando |
|---|---|
message.received | Chegou mensagem de um contato |
message.sent | Uma mensagem foi enviada |
contact.created | Contato novo |
contact.updated | Ficha alterada |
contact.stage_changed | Mudou de etapa no funil |
contact.tag_added | Ganhou etiqueta |
contact.tag_removed | Perdeu etiqueta |
contact.assigned | Conversa atribuída a alguém da equipe |
reminder.created | Tarefa criada |
reminder.done | Tarefa concluída |
flow.completed | Contato terminou um fluxo |
flow.handoff | Fluxo ou IA pediu atendimento humano |
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"}.
| Status | Significado |
|---|---|
400 | Faltou um campo obrigatório ou ele veio errado. A mensagem diz qual. |
401 | Sem token ou token inválido. |
404 | Contato, fluxo ou automação não existe nesta conta. |
409 | Não deu para fazer agora (ex.: fluxo não iniciado, automação desligada). A mensagem diz o motivo. |
5xx | Erro do nosso lado. Tente de novo em alguns segundos. |
Boas práticas
- Use
POST /contactspara criar ou atualizar pelo telefone: não precisa buscar antes. - O envio de mensagens segue o ritmo e o limite por contato da conta, para proteger o número. Disparo em massa é com Campanhas, dentro do CRM.
- Prefira webhooks de saída a consultar a API em intervalos curtos.
- Dúvidas: abra um ticket em Ajuda dentro do CRM ou escreva para contato@lymos.com.br.