FFLASHAPI

Para clientes e desenvolvedores

Como integrar a FLASHAPI no CRM, SaaS ou white label.

O cliente nao usa painel da FLASHAPI. Ele usa as credenciais entregues pelo administrador e implementa as chamadas HTTP dentro do proprio sistema.

Autenticacao

Authorization: Bearer SUA_API_KEY
X-Secret-Key: SUA_SECRET_KEY
Content-Type: application/json

Credencial valida sem instancia nao e erro

Quando o CRM testa API Key e Secret Key, ele deve chamar GET /sessions. Se a resposta vier com success=true e items vazio, as credenciais estao corretas. Isso significa apenas que o cliente ainda nao criou nenhuma instancia WhatsApp.

GET /sessions
Authorization: Bearer SUA_API_KEY
X-Secret-Key: SUA_SECRET_KEY
{
  "success": true,
  "data": {
    "items": [],
    "limit": 100,
    "used": 0,
    "available": 100
  },
  "error": null
}

Nesse caso, o CRM deve mostrar o estado "Credenciais validas. Nenhuma instancia criada ainda" e liberar o botao Criar instancia. Nao deve mostrar erro 1003 nem dizer que falta credencial WhatsApp ativa.

Prompt rapido para Lovable

Atualize a integracao do CRM com a FLASHAPI.

Base URL: http://159.69.65.93
Documentacao: http://159.69.65.93/guia
Swagger: http://159.69.65.93/docs

As credenciais API Key e Secret Key pertencem a empresa/cliente. O CRM deve usar essas credenciais para listar e criar instancias WhatsApp.

Ao testar credenciais, chame GET /sessions com Authorization: Bearer API_KEY e X-Secret-Key: SECRET_KEY.

Se retornar success=true com items=[], isso nao e erro. Mostre: "Credenciais validas. Nenhuma instancia criada ainda." e exiba o botao Criar instancia.

Para criar instancia, chame POST /sessions com:
{
  "name": "Atendimento 1",
  "autoStart": true,
  "autoReconnect": true,
  "defaultDelayMs": 0
}

Depois use data.session.id para buscar QR Code em GET /sessions/{sessionId}/qrcode e status em GET /sessions/{sessionId}/status.

Nao trate lista vazia como erro 1003. Erro so deve aparecer para 401, 403, 429 ou success=false.

1. Criar instancia

POST /sessions
{
  "name": "Atendimento Principal",
  "defaultDelayMs": 0,
  "autoReconnect": true
}

Se o cliente comprou 10 instancias, a API permite criar ate 10. Ao passar do limite, retorna INSTANCE_LIMIT_REACHED.

2. QR Code no CRM do cliente

O CRM deve ter botoes: Criar instancia, Conectar WhatsApp, Mostrar QR Code e Atualizar status.

POST /sessions/{sessionId}/start
GET  /sessions/{sessionId}/qrcode
GET  /sessions/{sessionId}/status
{
  "success": true,
  "data": {
    "id": "SESSION_ID",
    "status": "pendente_qr",
    "rawStatus": "QRCODE",
    "hasQrCode": true,
    "updatedAt": "2026-07-04T00:00:00.000Z"
  },
  "error": null
}

O endpoint /qrcode retorna o texto do QR. O CRM renderiza esse texto com uma biblioteca de QR no frontend.

3. Enviar mensagem

POST /messages/text
{
  "sessionId": "ID_DA_INSTANCIA",
  "to": "559999999999",
  "message": "Ola, mensagem de teste",
  "delayMs": 0
}

A resposta retorna o registro da mensagem com id interno. Use GET /messages/{id} para consultar status.

4. Envio de midia

POST /messages/image
POST /messages/video
POST /messages/audio
POST /messages/document
{
  "sessionId": "ID_DA_INSTANCIA",
  "to": "559999999999",
  "url": "https://site.com/arquivo.jpg",
  "caption": "opcional",
  "fileName": "arquivo.pdf",
  "mimeType": "application/pdf",
  "delayMs": 0
}

Formato atual: URL publica. Base64, multipart e download de midia recebida ficam como fase 2.

5. Botao automatico para cadastrar webhook

O CRM do cliente deve ter um botao como "Conectar webhook". Ao clicar, o sistema dele chama POST /webhooks na FLASHAPI com a URL que vai receber os eventos.

POST /webhooks
{
  "name": "CRM Principal",
  "url": "https://crm-do-cliente.com/api/flashapi/webhook",
  "events": [
    "message.received",
    "message.sent",
    "message.failed",
    "qrcode.updated",
    "connection.open",
    "connection.close"
  ]
}

Assinatura do webhook

Algoritmo: HMAC-SHA256. Encoding: hexadecimal. Segredo: campo secret do webhook retornado em POST /webhooks ou POST /webhooks/{id}/rotate-secret.

signedPayload = x-flashapi-timestamp + "." + rawBody
signature = HMAC_SHA256(webhookSecret, signedPayload).hex()
import crypto from "node:crypto";

function verifyFlashapi(req, rawBody, webhookSecret) {
  const timestamp = req.headers["x-flashapi-timestamp"];
  const signature = req.headers["x-flashapi-signature"];
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - Number(timestamp)) > 300) return false;
  const expected = crypto
    .createHmac("sha256", webhookSecret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

O CRM deve responder HTTP 200 imediatamente e processar em fila para nao atrasar recebimento/envio.

Payload oficial dos eventos atuais

// message.received
{
  "event": "message.received",
  "payload": {
    "messageId": "ID_INTERNO",
    "sessionId": "SESSION_ID",
    "phone": "559999999999",
    "type": "conversation|imageMessage|audioMessage|videoMessage|documentMessage",
    "body": "texto ou legenda"
  },
  "sentAt": "2026-07-04T00:00:00.000Z"
}

// message.sent
{
  "event": "message.sent",
  "payload": {
    "messageId": "ID_INTERNO",
    "sessionId": "SESSION_ID",
    "to": "559999999999",
    "providerMessageId": "ID_WHATSAPP"
  },
  "sentAt": "2026-07-04T00:00:00.000Z"
}

// message.failed
{
  "event": "message.failed",
  "payload": {
    "messageId": "ID_INTERNO",
    "sessionId": "SESSION_ID",
    "to": "559999999999",
    "error": "motivo"
  },
  "sentAt": "2026-07-04T00:00:00.000Z"
}

// qrcode.updated | connection.open | connection.close
{
  "event": "qrcode.updated",
  "payload": { "sessionId": "SESSION_ID" },
  "sentAt": "2026-07-04T00:00:00.000Z"
}

Endpoints complementares

GET /sessions/{id}/statusDELETE /sessions/{id}GET /messages/{id}GET /contacts/{jid}GET /contacts/{jid}/profile-pic

Confiabilidade, retry e limites

Webhook: timeout 8s, 3 tentativas, backoff fixo 2s. Nao ha garantia de ordem por conversa nesta versao; o CRM deve ordenar por timestamp/messageId se precisar. Rate limit HTTP atual: 240 requisicoes/minuto por IP. Envio de mensagens nao tem atraso escondido: MESSAGE_DEFAULT_DELAY_MS=0.

Roadmap para inbox avancado

Estes recursos podem ser preparados na interface do CRM, mas dependem de novos endpoints ou eventos da FlashAPI.

1. Presenca / ultima visualizacao
GET /contacts/{jid}/presence
Resposta desejada: { "online": true, "lastSeenAt": "2026-07-13T23:25:24.000Z" }
Webhook desejado: presence.updated

2. Enviar mensagem citando outra
Adicionar quotedMessageId aos endpoints:
POST /messages/text
POST /messages/image
POST /messages/video
POST /messages/audio
POST /messages/document

3. Encaminhar mensagem
POST /messages/forward
Body: { "sessionId": "ID_DA_INSTANCIA", "to": "5588999999999", "messageId": "ID_DA_MENSAGEM" }

4. Reagir a mensagem
POST /messages/reaction
Body: { "messageId": "ID_DA_MENSAGEM", "emoji": "👍" }
Webhook desejado: message.reaction

5. Excluir/apagar mensagem para todos
DELETE /messages/{id}
ou POST /messages/revoke

6. Mensagens de localizacao e contato
No webhook message.received, incluir tipos locationMessage e contactMessage.
Localizacao: lat, lng, name, address.
Contato: displayName e vcard.

7. Bandeira de mensagem encaminhada
No payload de mensagem recebida, incluir isForwarded: true.

8. Audio como nota de voz
POST /messages/audio com ptt: true.

Proximas etapas sugeridas para o CRM

A) UI/renderizacao
- audio player;
- documento/PDF;
- video;
- mensagem citada;
- acoes da mensagem;
- header expandido com etiquetas, responsavel e tempo.

B) Acoes client
- copiar mensagem;
- favoritar mensagem;
- marcar como importante.

Observacao: pode precisar de migracao no banco do CRM para campos como isStarred, isImportant e isForwarded.

C) IA
- traduzir;
- resumir;
- corrigir;
- reescrever;
- alterar tom;
- gerar resposta;
- transcrever audio;
- resumir/traduzir audio.

Fase 2

Ainda nao fechado: grupos, presenca, delivered/read/play reais, base64/multipart, download de midia recebida e URL temporaria de midia. HTTPS com dominio proprio deve ser configurado antes de producao publica.