Autenticação
Toda requisição é autenticada por uma chave de API enviada no header Authorization,
no esquema Bearer.
curl https://api.joinotify.com/templates \
-H 'Authorization: Bearer sk_live_xxx'
Formato do token
sk_live_AbCdEf0123456789abcdefgh
│ │ └── 32 caracteres aleatórios (192 bits de entropia)
│ └── ambiente: live ou test
└── prefixo fixo
Os primeiros 14 caracteres formam o prefixo (sk_live_AbCdEf). Ele é exibido no
painel e nas listagens para você identificar a chave sem revelar o segredo.
A documentação da Meta mostra exemplos com ?access_token= na query string. No
Joinotify isso não funciona e nunca vai funcionar — parâmetros de URL vazam em logs de
servidor, históricos de navegador e cabeçalhos Referer.
# Correto
curl https://api.joinotify.com/v1/{WABA_ID} \
-H 'Authorization: Bearer sk_live_xxx'
# Não funciona
curl 'https://api.joinotify.com/v1/{WABA_ID}?access_token=sk_live_xxx'
Criando uma chave
Pelo painel, em Chaves de API, ou pela própria API com uma chave existente:
curl -X POST https://api.joinotify.com/keys \
-H 'Authorization: Bearer sk_live_xxx' \
-H 'Content-Type: application/json' \
-d '{ "name": "integracao-erp", "environment": "live" }'
{
"data": {
"id": "key_01J8ZK...",
"name": "integracao-erp",
"prefix": "sk_live_AbCdEf",
"environment": "live",
"createdAt": "2026-07-27T14:02:11.482Z",
"secret": "sk_live_AbCdEf0123456789abcdefgh"
},
"warning": "Store the \"secret\" now — it will not be shown again."
}
O campo secret aparece apenas nessa resposta. Guardamos só o hash SHA-256 do
segredo — não temos como recuperá-lo depois.
Editando uma chave
Renomear a chave ou mudar quais números ela alcança, sem trocar o segredo:
curl -X PATCH https://api.joinotify.com/keys/key_01J8ZK... -H 'Authorization: Bearer sk_live_xxx' -H 'Content-Type: application/json' -d '{ "allowedPhoneNumberIds": ["1555000111", "1555000222"] }'
É o caminho de quem conectou um segundo WhatsApp e quer que a chave que já está em
produção passe a enviar por ele também: o sk_… continua o mesmo, então nenhum .env,
plugin ou fluxo no-code precisa ser atualizado. O novo alcance vale já na requisição
seguinte.
allowedPhoneNumberIds substitui a lista inteira — mande os números que a chave deve
alcançar, não só os novos. Lista vazia devolve a chave a todos os números da conta,
inclusive os que você conectar depois. Omitir o campo não mexe no alcance.
O environment não é editável: ele está gravado no próprio segredo (sk_live_… /
sk_test_…). Para trocar de ambiente, crie outra chave. Chave já revogada responde
409 key_revoked — revogação não tem desfazer.
Listando e revogando
# Listar (nunca retorna segredos)
curl https://api.joinotify.com/keys \
-H 'Authorization: Bearer sk_live_xxx'
# Revogar
curl -X DELETE https://api.joinotify.com/keys/key_01J8ZK... \
-H 'Authorization: Bearer sk_live_xxx'
A revogação é imediata: a próxima requisição com aquela chave já recebe
401 authentication. Revogar uma chave já revogada devolve 200 — a operação é
idempotente, então repetir não quebra nada.
Boas práticas
Uma chave por integração. ERP, e-commerce e chatbot com chaves separadas. Quando uma vaza, você revoga só ela.
Rotacione periodicamente. Crie a nova chave, publique-a, confirme que o tráfego
migrou (o painel mostra lastUsedAt por chave) e só então revogue a antiga. Como as
duas convivem, a rotação não tem janela de indisponibilidade.
Nunca no front-end. A chave dá acesso total à sua conta. Ela vive no servidor, em variável de ambiente ou cofre de segredos — jamais em código de navegador, app mobile ou repositório.
Vazou? Revogue primeiro. Revogar leva um segundo; investigar pode levar horas.
Erros de autenticação
| Código HTTP | type | Causa |
|---|---|---|
401 | authentication | Header ausente, formato inválido, chave desconhecida ou revogada. |
403 | tenant_inactive | A conta está suspensa ou cancelada. Fale com o suporte. |
{
"error": {
"message": "Invalid API key.",
"type": "authentication"
}
}
Ambientes live e test
Chaves podem ser criadas como live ou test. Hoje o prefixo serve para você
distinguir credenciais nos seus próprios sistemas e logs.
Não existe ambiente de testes isolado: uma chave sk_test_ envia mensagens reais e é
cobrada como qualquer outra. Para testar sem impacto, use um número de destino próprio.