Conecte o WhatsApp ao seu produto com uma API previsível.
Um contrato previsível, adaptado à segurança, aos escopos e à arquitetura multiempresa do HypeConversa.
Credenciais para experimentar
Os valores ficam apenas nesta aba durante a sessão e são usados somente ao clicar em Experimentar.
Comece aqui
Visão geral
Todas as requisições usam HTTPS e corpos JSON. A URL abaixo mostra onde o token da instância entra no caminho:
https://api.hypeconversa.com/instances/{INSTANCE_TOKEN}Experimentar. As credenciais preenchidas acima serão inseridas na URL e no header somente no momento da chamada.Mensagens
Texto, mídia, botões, listas, localização, contatos e reações.
Grupos
Criação, participantes, administradores e configurações.
Comunidades
Crie comunidades e organize grupos vinculados.
Newsletter
Crie e administre canais de transmissão.
Contatos
Consulte números, fotos e preferências de bloqueio.
Webhooks
Entregue eventos do WhatsApp ao seu sistema.
Segurança
Autenticação em duas camadas
Cada chamada combina exatamente dois segredos: o token da conta no header e o token da instância na URL. Os dois precisam estar ativos e pertencer ao mesmo tenant.
Client-TokenAutoriza o tenant e pode ser rotacionado globalmente.
INSTANCE_TOKENIdentifica a conexão e aplica seus escopos exclusivos.
Envie o token da conta sem Bearer:
Client-Token: hca_SEU_TOKEN_DE_CONTAE monte a rota da instância neste formato:
/instances/INSTANCE_TOKEN/send-text/instances/. O HypeConversa já remove esse valor dos próprios logs de aplicação.Destinatário
Nos envios, phone é o número de destino em formato internacional, somente com dígitos: DDI + DDD + número. Não inclua +, espaços ou traços. Exemplo: 5511999999999.
Para grupos, use o jid devolvido pela API, como [email protected].
Paginação por página
Listas longas usam os parâmetros page e pageSize. A primeira página é 1 e cada página pode conter até 100 itens.
{
"items": [ ... ],
"page": 1,
"pageSize": 20,
"total": 42,
"totalPages": 3
}Para carregar a próxima página, incremente page até alcançar totalPages.
Idempotência sem duplicidade
Em POSTs de envio, use uma chave única por operação. O valor deve ter entre 8 e 128 caracteres alfanuméricos e pode conter ponto, sublinhado, dois-pontos ou hífen.
Idempotency-Key: pedido:12345409. Uma repetição simultânea também recebe 409 com Retry-After: 1.Limites de uso
Cada token de instância aceita até 120 requisições por minuto. Há também uma proteção global por IP contra abuso.
429 e informa Retry-After. Respeite também o ritmo do WhatsApp para reduzir risco de bloqueio da conta.Erros consistentes
Erros usam um código estável e uma mensagem legível por máquina:
{
"code": "VALIDATION_ERROR",
"message": "VALIDATION_ERROR",
"fieldErrors": {}
}400requisição inválida ou conexão desconectada.401credenciais ausentes, inválidas, revogadas ou incompatíveis.403o token da instância não possui o escopo necessário.404recurso não encontrado dentro da conta autenticada.409conflito de idempotência ou estado.422corpo ou parâmetros fora do contrato.429limite de uso atingido.503gateway do WhatsApp temporariamente indisponível.
HypeCom
Identificar o usuário logado
O HypeCom é instalado com uma linha no HTML. A chave pública da conexão sai no painel, em Conexões:
<script
src="function(){throw Error("Attempted to call HYPECOM_EDGE_URL() from the server but HYPECOM_EDGE_URL is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")}/widget.js"
data-public-key="CHAVE_PUBLICA_DA_CONEXAO"
></script>Para abrir ou fechar com um botão do próprio site, use a API pública do widget:
window.hypecom('open');
window.hypecom('close');
window.hypecom('toggle');Se o atendimento deve aparecer somente por esse gatilho, oculte o botão flutuante na instalação:
<script
src="function(){throw Error("Attempted to call HYPECOM_EDGE_URL() from the server but HYPECOM_EDGE_URL is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")}/widget.js"
data-public-key="CHAVE_PUBLICA_DA_CONEXAO"
data-hide-launcher="true"
></script>Assim ele já atende visitante anônimo. O que muda bastante é a continuidade da conversa, e os dois modos convivem na mesma instalação:
Continuidade por navegador
Visitante anônimo
- A credencial fica no armazenamento do seu site, em primeira parte.
- Vale 270 dias e é renovada a cada visita.
- Presa à origem exata e trocada por sessão só no bootstrap.
- Não recupera a conversa em outro dispositivo: não existe identidade para ligar os dois.
Identidade da conta
Usuário logado
- A âncora é o sub do token que o seu backend assina.
- A mesma pessoa reencontra as conversas em qualquer dispositivo onde esteja logada.
- Não depende de cookie nem de armazenamento do navegador.
- E-mail e telefone do token chegam como dados verificados, não como algo que o visitante digitou.
Para identificar, o seu backend assina um JWT HS256 com o segredo da conexão. Ele nasce em Conexões, na conexão do HypeCom, no bloco Verificação de identidade, botão Gerar segredo. É exibido uma única vez, ali: o banco guarda a versão cifrada e nem o painel consegue lê-la de volta. Enquanto não houver segredo gerado, a conexão recusa qualquer token com WEB_CHAT_IDENTITY_VERIFICATION_DISABLED.
import { createHmac, randomUUID } from 'node:crypto';
const secret = process.env.HYPECOM_IDENTITY_SECRET; // whs_...
const part = (value) => Buffer.from(JSON.stringify(value)).toString('base64url');
export function hypecomIdentityToken(user) {
const now = Math.floor(Date.now() / 1000);
const header = part({ alg: 'HS256', typ: 'JWT' });
const payload = part({
sub: user.id, // id interno e estável. Nunca o e-mail: e-mail muda.
name: user.name,
email: user.email, // opcional, e chega como dado verificado
phone: user.phone, // opcional
iat: now,
exp: now + 3600,
jti: randomUUID(), // um por token: é o que barra reuso
});
const signature = createHmac('sha256', secret)
.update(`${header}.${payload}`)
.digest('base64url');
return `${header}.${payload}.${signature}`;
}Renderize um token novo em cada carga de página:
<script
src="function(){throw Error("Attempted to call HYPECOM_EDGE_URL() from the server but HYPECOM_EDGE_URL is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")}/widget.js"
data-public-key="CHAVE_PUBLICA_DA_CONEXAO"
data-identity-token="<%= hypecomIdentityToken(currentUser) %>"
></script>E cubra os dois momentos que não passam por uma nova carga, o login numa aplicação de página única e o logout:
// Login sem recarregar a página
const { token } = await fetch('/api/hypecom/identity-token').then((r) => r.json());
window.hypecom('identify', { identityToken: token });
// Logout, sempre
window.hypecom('shutdown');Claims aceitas no token:
subobrigatório. O identificador estável do usuário no seu sistema, e é ele que amarra a mesma pessoa entre dispositivos.expobrigatório, com validade máxima de 24 horas. Token de identificação sem prazo vira credencial eterna se vazar do HTML.jtirecomendado, único por emissão. É o que impede o reuso do mesmo token.email,phoneenameopcionais. Como vêm assinados, são tratados como verificados, e o vínculo automático com um contato existente só acontece quando exatamente um contato casa com eles.
shutdown no logout. Sem ele a sessão continua válida e, num computador compartilhado, o próximo usuário abre o HypeCom na conversa de quem saiu.jti repetido é recusado, e o HypeCom não cai para anônimo em silêncio: degradar caladinho faria o seu site acreditar que está identificando o usuário com a integração quebrada. Confira também se a origem exata do site, com esquema e porta, está na lista de sites permitidos da conexão.A recusa é avisada à sua página, com o motivo. A conversa que já estava acontecendo continua de pé como visitante anônimo, porque derrubá-la deixaria quem estava escrevendo sem resposta nenhuma:
window.addEventListener('message', (event) => {
if (event.origin !== 'function(){throw Error("Attempted to call HYPECOM_EDGE_URL() from the server but HYPECOM_EDGE_URL is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")}') return;
if (event.data?.type !== 'hypecom:identify-failed') return;
// event.data.code diz o motivo, por exemplo:
// WEB_CHAT_IDENTITY_VERIFICATION_DISABLED segredo nao gerado na conexao
// WEB_CHAT_IDENTITY_TOKEN_INVALID assinatura, prazo ou jti repetido
console.error('Hypecom: identidade recusada', event.data.code);
});