Sincro API

API REST para integrar sistemas externos à plataforma Sincro — envie mensagens via WhatsApp, consulte o CRM e verifique o status de conexão de forma programática.

💡 Todos os endpoints retornam JSON com o envelope padrão { "success": true, "data": ... } ou { "success": false, "error": "..." }. Sempre verifique o campo success antes de processar data.

⚙️ URL do Servidor

Configure o endereço do seu servidor Sincro. Todos os exemplos de código abaixo serão atualizados automaticamente. A URL fica salva no navegador.

⚠️ O servidor Sincro (Node.js + PM2) precisa estar acessível publicamente para a API funcionar com integrações externas. Use um domínio próprio, VPS com IP fixo, ou um túnel temporário como ngrok durante os testes.

🔑 Autenticação

A API usa API Keys geradas no painel Sincro (Configurações → API Keys). Cada chave pertence a uma empresa e só acessa dados dela. A chave é exibida uma única vez — salve imediatamente.

Como enviar a chave

# Recomendado
x-api-key: sk_live_SUA_CHAVE_AQUI
# Alternativa — Bearer padrão
Authorization: Bearer sk_live_SUA_CHAVE_AQUI
⚠️ Segurança: nunca exponha sua API key em código front-end ou repositórios públicos. Use variáveis de ambiente. Se comprometida, revogue no painel imediatamente.

⏱ Rate Limiting

EscopoLimiteJanela
Todos os endpoints /api/v1/*60 requisições1 minuto por IP

Ao exceder, a API retorna 429 Too Many Requests. Implemente exponential backoff.

⚠️ Códigos de Erro

HTTPCausaAção sugerida
400Campos obrigatórios ausentes ou inválidosVerifique o body/query
401API key ausente, inválida ou revogadaGere nova chave no painel
403Empresa não encontrada para esta chaveVerifique integridade da conta
429Rate limit excedidoAguarde com exponential backoff
500Erro interno do servidorTente novamente; contate suporte
503WhatsApp desconectadoReconecte via painel (QR)
401 Unauthorized — formato padrão de erro
{
  "success": false,
  "error":   "API key inválida ou revogada."
}

Endpoints

GET /api/v1/status Verifica conexão WhatsApp da empresa

Retorna o status do WhatsApp da empresa autenticada e se há sessão ativa pronta para envio.

Exemplos

curl -X GET {BASE_URL}/api/v1/status \
  -H "x-api-key: sk_live_SUA_CHAVE_AQUI"
const res = await fetch('{BASE_URL}/api/v1/status', {
  headers: { 'x-api-key': 'sk_live_SUA_CHAVE_AQUI' }
});
const json = await res.json();
console.log(json.data.whatsapp_conectado); // true | false
import requests

res = requests.get(
    "{BASE_URL}/api/v1/status",
    headers={"x-api-key": "sk_live_SUA_CHAVE_AQUI"}
)
print(res.json()["data"]["whatsapp_conectado"])

Resposta de sucesso

200 OK
{
  "success": true,
  "data": {
    "empresa":             "NR1 Doctor",
    "whatsapp_status":     "ONLINE",
    "whatsapp_conectado": true
  }
}
POST /api/v1/mensagem/enviar Envia mensagem WhatsApp

Envia uma mensagem de texto via WhatsApp pelo número conectado da empresa. O WhatsApp precisa estar ONLINE.

Body (JSON)

CampoTipoDescrição
numero obrigatório string DDI+DDD+número, somente dígitos. Ex: "5541999999999"
mensagem obrigatório string Texto a enviar. Máximo 4096 caracteres. Suporta emojis e \n

Exemplos

curl -X POST {BASE_URL}/api/v1/mensagem/enviar \
  -H "x-api-key: sk_live_SUA_CHAVE_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "numero":   "5541999999999",
    "mensagem": "Sua consulta foi confirmada para amanhã às 14h. 🩺"
  }'
const res = await fetch('{BASE_URL}/api/v1/mensagem/enviar', {
  method:  'POST',
  headers: {
    'x-api-key':     'sk_live_SUA_CHAVE_AQUI',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    numero:   '5541999999999',
    mensagem: 'Sua consulta foi confirmada para amanhã às 14h. 🩺'
  })
});
const json = await res.json();
if (!json.success) throw new Error(json.error);
console.log('Enviado para', json.data.numero);
import requests

res = requests.post(
    "{BASE_URL}/api/v1/mensagem/enviar",
    json={
        "numero":   "5541999999999",
        "mensagem": "Sua consulta foi confirmada para amanhã às 14h. 🩺"
    },
    headers={
        "x-api-key":     "sk_live_SUA_CHAVE_AQUI",
        "Content-Type": "application/json"
    }
)
data = res.json()
if not data["success"]: raise Exception(data["error"])
// Nó HTTP Request no n8n ou Make
Method: POST
URL: {BASE_URL}/api/v1/mensagem/enviar
Headers:
  x-api-key:     {{ $env.SINCRO_API_KEY }}
  Content-Type:  application/json
Body (JSON):
{
  "numero":   "{{ $json.telefone }}",
  "mensagem": "{{ $json.texto }}"
}

Resposta de sucesso

200 OK
{
  "success": true,
  "data": {
    "enviado": true,
    "numero":  "5541999999999"
  }
}

Possíveis erros

400 — número inválido
{ "success": false, "error": "numero inválido. Formato: DDI+DDD+número (ex: 5541999999999)." }
503 — WhatsApp desconectado
{ "success": false, "error": "WhatsApp desconectado. Conecte via painel." }
GET /api/v1/contatos Lista contatos do CRM

Retorna os contatos CRM da empresa, paginados, do mais recente ao mais antigo. Máximo 100 por página.

Query Parameters

ParâmetroTipoDescrição
limite opcionalintegerRegistros por página. Padrão: 50. Máximo: 100
pagina opcionalintegerPágina (começa em 1). Padrão: 1
curl -X GET "{BASE_URL}/api/v1/contatos?limite=20&pagina=1" \
  -H "x-api-key: sk_live_SUA_CHAVE_AQUI"
const params = new URLSearchParams({ limite: 20, pagina: 1 });
const res = await fetch(
  `{BASE_URL}/api/v1/contatos?${params}`,
  { headers: { 'x-api-key': 'sk_live_SUA_CHAVE_AQUI' } }
);
const json = await res.json();
// json.data → contatos | json.meta → { total, pagina, limite }
import requests

res = requests.get(
    "{BASE_URL}/api/v1/contatos",
    params={"limite": 20, "pagina": 1},
    headers={"x-api-key": "sk_live_SUA_CHAVE_AQUI"}
)
data = res.json()
print(data["meta"])  # {'total': 142, 'pagina': 1, 'limite': 20}

Resposta de sucesso

200 OK
{
  "success": true,
  "data": [
    {
      "numero":           "5541999999999",
      "nome":             "Maria Souza",
      "tags":             "HOT_LEAD",
      "ultima_interacao": "2026-05-09T11:00:00.000Z",
      "notas":            "Interessada no Plano Família"
    }
  ],
  "meta": { "total": 142, "pagina": 1, "limite": 20 }
}

👤 Pacientes

💡 Todos os endpoints de Pacientes operam sobre os dados da empresa autenticada via API key. O campo empresa_id é resolvido automaticamente — não é necessário enviá-lo.
GET /api/v1/pacientes Lista pacientes com filtros e paginação

Query Parameters

ParâmetroTipoDescrição
busca opcionalstringBusca por nome ou número (parcial, case-insensitive)
tag opcionalstringFiltra por tag. Ex: HOT_LEAD, gestante
pagina opcionalintegerPágina (começa em 1). Padrão: 1
limite opcionalintegerRegistros por página. Padrão: 50. Máximo: 100
curl -X GET "https://sincro.space/api/v1/pacientes?tag=gestante&limite=20" \
  -H "x-api-key: sk_live_SUA_CHAVE"
import requests
res = requests.get(
    "https://sincro.space/api/v1/pacientes",
    params={"tag": "gestante", "limite": 20},
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)
print(res.json()["meta"]["total"], "pacientes")

Resposta

200 OK
{"success": true, "data": [{"numero": "5541999999999", "nome": "Maria", "tags": "gestante HOT_LEAD", "notas": "DPP: 2026-11-15", "ultima_interacao": "2026-05-13T..."}], "meta": {"total": 42, "pagina": 1, "limite": 20}}
GET /api/v1/pacientes/:numero Retorna perfil completo de um paciente
curl https://sincro.space/api/v1/pacientes/5541999999999 \
  -H "x-api-key: sk_live_SUA_CHAVE"
import requests
res = requests.get(
    "https://sincro.space/api/v1/pacientes/5541999999999",
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)
paciente = res.json()["data"]
POST /api/v1/pacientes Cria ou atualiza (upsert) um paciente

Se o número já existir no CRM da empresa, atualiza os campos enviados. Se não existir, cria um novo registro.

Body (JSON)

CampoTipoDescrição
numero obrigatóriostringDDI+DDD+número. Ex: "5541999999999"
nome opcionalstringNome completo. Máx 200 caracteres
tags opcionalstringTags separadas por espaço. Ex: "gestante HOT_LEAD semana_12"
notas opcionalstringNotas clínicas iniciais. Máx 5000 caracteres
import requests
res = requests.post(
    "https://sincro.space/api/v1/pacientes",
    json={"numero": "5541999999999", "nome": "Ana Gestante", "tags": "gestante HOT_LEAD", "notas": "DPP estimada: 2026-11-15"},
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)
PATCH /api/v1/pacientes/:numero Atualiza campos específicos sem sobrescrever o restante
requests.patch(
    "https://sincro.space/api/v1/pacientes/5541999999999",
    json={"tags": "gestante HOT_LEAD semana_20"},
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)
DELETE /api/v1/pacientes/:numero Remove paciente do CRM (histórico de mensagens é preservado)
⚠️ Remove apenas o registro CRM. O histórico de conversas com a Helena é preservado.
curl -X DELETE https://sincro.space/api/v1/pacientes/5541999999999 \
  -H "x-api-key: sk_live_SUA_CHAVE"
GET /api/v1/pacientes/:numero/historico Histórico de conversa com a Helena (paginado, mais recente primeiro)

O campo autor_id é "HELENA" para mensagens da IA e o número do paciente para mensagens humanas.

200 OK
{"success": true, "data": [{"autor_id": "HELENA", "conteudo": "Olá! Em que posso ajudar?", "criado_em": "2026-05-13T..."}, {"autor_id": "5541999999999", "conteudo": "Quero agendar uma consulta", "criado_em": "2026-05-13T..."}], "meta": {"total": 48, "pagina": 1, "limite": 50}}
POST /api/v1/pacientes/:numero/notas Appenda nota clínica com timestamp automático

Adiciona nota ao final do campo notas com data/hora: [DD/MM/AAAA, HH:MM] texto. Não sobrescreve notas anteriores.

requests.post(
    "https://sincro.space/api/v1/pacientes/5541999999999/notas",
    json={"nota": "Paciente relatou enjoo matinal. Solicitado beta-HCG."},
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)
GET /api/v1/pacientes/:numero/alertas Lista alertas agendados para este paciente
🔔 Endpoint ativo. Módulo completo de Alertas disponível na v1.2.
GET /api/v1/pacientes/:numero/protocolos Lista protocolos clínicos ativos para este paciente
🧬 Endpoint ativo. Módulo completo de Protocolos disponível na v1.3.

🔔 Alertas Agendados

💡 O scheduler roda a cada 60 segundos e dispara automaticamente os alertas no horário agendado. Suporte a recorrência diária, semanal e mensal. Máximo 3 tentativas por alerta em caso de falha.
GET /api/v1/alertas Lista alertas com filtros

Query Parameters

ParâmetroTipoDescrição
status opcionalstringpendente · enviado · cancelado · falhou
numero opcionalstringFiltra por número do paciente
de / ate opcionalYYYY-MM-DDFiltro de período de agendado_para
POST /api/v1/alertas Cria alerta agendado (com recorrência opcional)

Body (JSON)

CampoTipoDescrição
numero obrigatóriostringDDI+DDD+número do paciente
mensagem obrigatóriostringTexto a enviar. Máx 4096 caracteres
agendado_para obrigatórioISO 8601Data/hora futura. Ex: "2026-05-20T14:00:00-03:00"
recorrencia opcionalstring | nulldiario · semanal · mensal
import requests
res = requests.post(
    "https://sincro.space/api/v1/alertas",
    json={
        "numero":        "5541999999999",
        "mensagem":      "Lembrete: sua consulta de pré-natal é amanhã às 14h. 🩺",
        "agendado_para": "2026-05-20T09:00:00-03:00"
    },
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)
print(res.json()["data"]["id"])
import requests
res = requests.post(
    "https://sincro.space/api/v1/alertas",
    json={
        "numero":        "5541999999999",
        "mensagem":      "Bom dia! Lembre de tomar o ácido fólico hoje. 💊",
        "agendado_para": "2026-05-15T08:00:00-03:00",
        "recorrencia":   "diario"
    },
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)
GET /api/v1/alertas/:id Retorna detalhes de um alerta específico
curl https://sincro.space/api/v1/alertas/UUID-DO-ALERTA \
  -H "x-api-key: sk_live_SUA_CHAVE"
PATCH /api/v1/alertas/:id Reagenda ou atualiza mensagem (só funciona com status pendente)
CampoTipoDescrição
mensagem opcionalstringNova mensagem
agendado_para opcionalISO 8601Nova data/hora (deve ser futura)
recorrencia opcionalstring | nullAlterar ou remover recorrência
⚠️ Retorna 409 Conflict se o alerta já foi enviado, cancelado ou falhou.
DELETE /api/v1/alertas/:id Cancela alerta pendente (preserva registro com status cancelado)
200 OK
{ "success": true, "data": { "id": "...", "numero": "5541999999999", "status": "cancelado" } }
POST /api/v1/alertas/:id/disparar-agora Força envio imediato, ignorando o horário agendado

Útil para retestes ou situações de emergência clínica. Se o alerta tiver recorrência, cria o próximo após o envio.

requests.post(
    "https://sincro.space/api/v1/alertas/UUID-DO-ALERTA/disparar-agora",
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)

🤰 Módulo Gestação

Endpoints para monitoramento obstétrico — cadastro de DUM, cálculo automático de IG/DPP, check-ins clínicos e alarmes. Segue o protocolo SUS de pré-natal (Previne Brasil).

POST /api/v1/pacientes/:numero/gestacao Cadastra ou atualiza a DUM da gestante (upsert)

Obrigatório antes de qualquer check-in. dum_operacional é a DUM corrigida por ultrassom.

requests.post(
    "https://sincro.space/api/v1/pacientes/5511999990000/gestacao",
    headers={"x-api-key": "sk_live_SUA_CHAVE"},
    json={"dum": "2026-01-15", "dum_operacional": "2026-01-12"}
)
{"success": true, "data": {"ig": {"semanas": 17, "dias": 4}, "dpp": "2026-10-19", "fase": "evolucao", "captacao": {"status": "tardia"}}}
GET /api/v1/pacientes/:numero/gestacao Retorna IG atual, DPP, fase e perguntas de check-in da semana

IG recalculada em tempo real. perguntas_da_semana retorna as perguntas adequadas à fase atual — use para montar o formulário no seu sistema.

requests.get(
    "https://sincro.space/api/v1/pacientes/5511999990000/gestacao",
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)
POST /api/v1/pacientes/:numero/checkins Registra resposta de check-in e avalia alarme clínico

O sistema avalia automaticamente o risco (normal / atencao / urgente) conforme o protocolo. Alarmes urgentes ativam o webhook alarme.risco_clinico (Grupo 5).

requests.post(
    "https://sincro.space/api/v1/pacientes/5511999990000/checkins",
    headers={"x-api-key": "sk_live_SUA_CHAVE"},
    json={"pergunta_chave": "sangramento", "resposta": "sim"}
)
GET /api/v1/pacientes/:numero/checkins Histórico completo de check-ins com paginação

Query params: limite (máx 200, default 50), pagina (base-1).

requests.get(
    "https://sincro.space/api/v1/pacientes/5511999990000/checkins",
    headers={"x-api-key": "sk_live_SUA_CHAVE"},
    params={"limite": 20}
)
GET /api/v1/pacientes/:numero/alarmes-gestacionais Computa alarmes clínicos ativos em tempo real

Avalia 4 categorias: vacina (dTpa ≥ 20sem), exame (1T após 12sem), risco_clinico (sintoma urgente), abandono (>35 dias sem check-in). Retorna resumo com contagem de urgentes e atenções.

requests.get(
    "https://sincro.space/api/v1/pacientes/5511999990000/alarmes-gestacionais",
    headers={"x-api-key": "sk_live_SUA_CHAVE"}
)

🪝 Webhooks de Saída

Configure endpoints externos para receber eventos em tempo real. Cada entrega inclui X-Sincro-Signature: sha256=<hmac> para verificação de autenticidade. Retry automático: 1min → 5min → 30min.

Eventos: checkin.resposta · alarme.risco_clinico · alarme.abandono · alarme.vacina · alarme.exame · mensagem.recebida · alerta.enviado · whatsapp.desconectado
GET /api/v1/webhooks Lista webhooks configurados
requests.get("https://sincro.space/api/v1/webhooks", headers={"x-api-key": "sk_live_SUA_CHAVE"})
POST /api/v1/webhooks Cria webhook com HMAC auto-gerado
requests.post(
    "https://sincro.space/api/v1/webhooks",
    headers={"x-api-key": "sk_live_SUA_CHAVE"},
    json={
        "url": "https://meu-sistema.com/hooks/sincro",
        "eventos": ["checkin.resposta", "alarme.risco_clinico"],
        "descricao": "Prontuário gestantes"
    }
)
import hmac, hashlib

def verificar(corpo: bytes, secret: str, header: str) -> bool:
    esperado = "sha256=" + hmac.new(secret.encode(), corpo, hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperado, header)
PATCH /api/v1/webhooks/:id Atualiza URL, eventos ou pausa (ativo: false)
requests.patch("https://sincro.space/api/v1/webhooks/UUID", headers={"x-api-key": "sk_live_SUA_CHAVE"}, json={"ativo": False})
DEL /api/v1/webhooks/:id Remove webhook e todos os logs
requests.delete("https://sincro.space/api/v1/webhooks/UUID", headers={"x-api-key": "sk_live_SUA_CHAVE"})
POST /api/v1/webhooks/:id/teste Dispara payload de teste — retorna HTTP status da URL configurada
requests.post("https://sincro.space/api/v1/webhooks/UUID/teste", headers={"x-api-key": "sk_live_SUA_CHAVE"})
GET /api/v1/webhooks/:id/logs Histórico de tentativas de entrega

Query params: status (sucesso | falhou | pendente | tentando), limite, pagina.

requests.get("https://sincro.space/api/v1/webhooks/UUID/logs", headers={"x-api-key": "sk_live_SUA_CHAVE"}, params={"status": "falhou"})

📊 Analytics

Métricas consolidadas da operação. Todos os endpoints aceitam ?periodo=hoje|7d|30d|90d (padrão: 30d).

GET /api/v1/analytics/resumo Snapshot do dashboard — pacientes, gestação, alertas, webhooks
requests.get("https://sincro.space/api/v1/analytics/resumo", headers={"x-api-key": "sk_live_SUA_CHAVE"})
{"data": {"pacientes": {"total": 142, "ativos_7d": 38}, "gestacao": {"gestantes": 27, "checkins_urgentes_30d": 2}, "alertas": {"pendentes": 5, "enviados_30d": 64}, "webhooks_24h": {"sucesso": 18, "falhou": 1, "taxa_sucesso": 95}}}
GET /api/v1/analytics/mensagens Volume por dia — recebidas vs enviadas pela Helena
requests.get("https://sincro.space/api/v1/analytics/mensagens", headers={"x-api-key": "sk_live_SUA_CHAVE"}, params={"periodo": "7d"})
GET /api/v1/analytics/pacientes Aquisição, distribuição de tags e inatividade
requests.get("https://sincro.space/api/v1/analytics/pacientes", headers={"x-api-key": "sk_live_SUA_CHAVE"})
GET /api/v1/analytics/gestacao Gestantes por fase, alarmes clínicos, abandono
requests.get("https://sincro.space/api/v1/analytics/gestacao", headers={"x-api-key": "sk_live_SUA_CHAVE"})
GET /api/v1/analytics/alertas Taxa de sucesso, breakdown por status e recorrência
requests.get("https://sincro.space/api/v1/analytics/alertas", headers={"x-api-key": "sk_live_SUA_CHAVE"}, params={"periodo": "90d"})

⚙️ Configurações

Gerencie perfil, comportamento da Helena e blacklist via API — sem precisar do painel.

GET /api/v1/configuracoes Perfil da clínica (sem tokens de pagamento)
requests.get("https://sincro.space/api/v1/configuracoes", headers={"x-api-key": "sk_live_SUA_CHAVE"})
PATCH /api/v1/configuracoes Atualiza campos do perfil — qualquer subconjunto

Campos: nome_fantasia, email, telefone, endereco, cep, logo_url, cor_hex, nome_agente, numero_admin, aviso_do_dia.

requests.patch("https://sincro.space/api/v1/configuracoes", headers={"x-api-key": "sk_live_SUA_CHAVE"}, json={"aviso_do_dia": "Feriado amanhã.", "nome_agente": "Dra. Helena"})
GET /api/v1/configuracoes/helena Prompt, horário de atendimento, escalada e comportamento da IA
requests.get("https://sincro.space/api/v1/configuracoes/helena", headers={"x-api-key": "sk_live_SUA_CHAVE"})
PATCH /api/v1/configuracoes/helena Atualiza IA — merge parcial, só altera o que foi enviado
requests.patch(
    "https://sincro.space/api/v1/configuracoes/helena",
    headers={"x-api-key": "sk_live_SUA_CHAVE"},
    json={
        "horario": {"ativo": True, "hora_inicio": "07:00", "hora_fim": "19:00"},
        "comportamento": {"escudo_turing": True, "tom_voz": "acolhedor"},
        "prompt": "Você é a Helena, especialista em gestação..."
    }
)
🧠
Prompt Base — Helena Gestantes
Prompt estrutural completo para clínicas de pré-natal · Protocolo SUS · Ministério da Saúde
⬇ Baixar .txt

Prompt estrutural pronto para carregar via PATCH /api/v1/configuracoes/helena. Inclui persona, roteamento por fase gestacional, motor de alarmes, uso da Base de Conhecimento (RAG) e tratamento de emergências — tudo alinhado ao Caderno de Atenção Básica nº 32 do MS.

Fases cobertas
Captação · Evolução · Reta Final · Pré-Parto
Perguntas
22 perguntas · 1 por mensagem · ordenadas por semana
Alarmes automáticos
Vacina · Exame 1T · Risco Clínico · Abandono
RAG
Base de Conhecimento obrigatória · nunca inventa
import requests, pathlib

prompt = pathlib.Path("prompt-helena-gestantes.txt").read_text(encoding="utf-8")

requests.patch(
    "https://sincro.space/api/v1/configuracoes/helena",
    headers={"Authorization": "Bearer sk_live_SUA_CHAVE"},
    json={"prompt": prompt}
)
GET /api/v1/configuracoes/blacklist Números bloqueados — Helena ignora mensagens desses contatos
requests.get("https://sincro.space/api/v1/configuracoes/blacklist", headers={"x-api-key": "sk_live_SUA_CHAVE"})
POST /api/v1/configuracoes/blacklist/:numero Bloqueia número (idempotente)
requests.post("https://sincro.space/api/v1/configuracoes/blacklist/5541999990001", headers={"x-api-key": "sk_live_SUA_CHAVE"})
DEL /api/v1/configuracoes/blacklist/:numero Remove número da blacklist
requests.delete("https://sincro.space/api/v1/configuracoes/blacklist/5541999990001", headers={"x-api-key": "sk_live_SUA_CHAVE"})

🧩 Exemplos de Integração

Disparar mensagem ao fechar negócio no CRM

const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhook/crm', async (req, res) => {
  const { telefone, nome, plano } = req.body;
  await fetch('{BASE_URL}/api/v1/mensagem/enviar', {
    method: 'POST',
    headers: {
      'x-api-key':     process.env.SINCRO_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      numero:   telefone,
      mensagem: `Olá ${nome}! 🎉 Seu plano ${plano} foi ativado. Bem-vindo!`
    })
  });
  res.sendStatus(200);
});

app.listen(4000);

Padrão robusto — verificar status antes de enviar

async function enviarComVerificacao(numero, mensagem) {
  const BASE = process.env.SINCRO_SERVER_URL;  // ex: https://seu-servidor.com
  const KEY  = process.env.SINCRO_API_KEY;

  // 1. Verifica se o WhatsApp está online
  const { data: status } = await fetch(`${BASE}/api/v1/status`, {
    headers: { 'x-api-key': KEY }
  }).then(r => r.json());

  if (!status.whatsapp_conectado) throw new Error('WhatsApp offline');

  // 2. Envia
  const result = await fetch(`${BASE}/api/v1/mensagem/enviar`, {
    method: 'POST',
    headers: { 'x-api-key': KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ numero, mensagem })
  }).then(r => r.json());

  if (!result.success) throw new Error(result.error);
  return result.data;
}

📋 Changelog

v1.5.0
13 de maio de 2026
  • ✅ Grupo 6 — Analytics (5 endpoints)
  • ✅ Resumo, Mensagens, Pacientes, Gestação, Alertas
  • ✅ Parâmetro ?periodo=hoje|7d|30d|90d
v1.4.0
13 de maio de 2026
  • ✅ Grupo 5 — Webhooks de Saída (7 endpoints)
  • ✅ HMAC-SHA256 em todos os payloads
  • ✅ Retry automático 1min → 5min → 30min
  • ✅ 8 eventos: checkin, alarmes, mensagem, alerta, desconexão
v1.3.0
13 de maio de 2026
  • ✅ Módulo Gestação — 5 endpoints clínicos
  • ✅ Calculadora obstétrica: IG, DPP, fase, status Previne Brasil
  • ✅ Protocolo SUS: 20+ perguntas em 4 fases
  • ✅ Alarmes automáticos: vacina, exame, risco clínico, abandono
v1.2.0
13 de maio de 2026
  • ✅ Grupo 3 — Alertas Agendados (6 endpoints)
  • ✅ Scheduler automático a cada 60s com retry (3 tentativas)
  • ✅ Recorrência diária, semanal e mensal
  • ✅ /pacientes/:numero/alertas retorna dados reais
v1.1.0
13 de maio de 2026
  • ✅ Grupo 1 — API completa de Pacientes (9 endpoints)
  • ✅ CORS: suporte a PATCH e DELETE
  • 🐛 Fix: status@broadcast não processado pela Helena
v1.0.0
9 de maio de 2026
  • ✅ Lançamento da API pública v1
  • ✅ Autenticação por API Key (SHA-256, geração client-side)
  • GET /api/v1/status
  • POST /api/v1/mensagem/enviar
  • GET /api/v1/contatos com paginação
  • ✅ Rate limiting: 60 req/min por IP
  • ✅ Documentação pública hospedada no Vercel