{"id":11267,"date":"2026-11-09T08:00:00","date_gmt":"2026-11-09T11:00:00","guid":{"rendered":"https:\/\/z-api.io\/blog\/?p=11267"},"modified":"2026-11-09T15:22:20","modified_gmt":"2026-11-09T18:22:20","slug":"como-enviar-textos-audios-e-pdfs-pela-api-do-whatsapp","status":"publish","type":"post","link":"https:\/\/z-api.io\/blog\/como-enviar-textos-audios-e-pdfs-pela-api-do-whatsapp\/","title":{"rendered":"Como enviar textos, \u00e1udios e PDFs via API de mensagens"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Enviar uma mensagem pelo smartphone manualmente \u00e9 simples. J\u00e1 integrar esse envio a um sistema exige alguns cuidados: <strong>autentica\u00e7\u00e3o, formato do payload, endpoint correto, identifica\u00e7\u00e3o do destinat\u00e1rio, hospedagem de arquivos, acompanhamento de status e tratamento de falhas<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Com a API do Z-API, sua aplica\u00e7\u00e3o pode enviar textos, \u00e1udios e documentos para contatos ou grupos por meio de requisi\u00e7\u00f5es HTTP.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A documenta\u00e7\u00e3o apresenta endpoints RESTful espec\u00edficos para cada tipo de conte\u00fado, <strong>com autentica\u00e7\u00e3o por Client-Token e par\u00e2metros de inst\u00e2ncia e token na URL<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Neste tutorial, voc\u00ea ver\u00e1 como realizar os primeiros envios usando <strong>cURL<\/strong> e <strong>JavaScript com fetch<\/strong>, seguindo a estrutura apresentada na documenta\u00e7\u00e3o utilizada como base para este conte\u00fado. Como APIs podem receber atualiza\u00e7\u00f5es, confirme os campos e par\u00e2metros no endpoint correspondente antes de colocar a integra\u00e7\u00e3o em produ\u00e7\u00e3o.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>A seguir, voc\u00ea vai ver como:<\/li>\n\n\n\n<li>Preparar uma inst\u00e2ncia do Z-API;<\/li>\n\n\n\n<li>Montar a URL base da requisi\u00e7\u00e3o;<\/li>\n\n\n\n<li>Autenticar chamadas com Client-Token;<\/li>\n\n\n\n<li>Enviar texto simples;<\/li>\n\n\n\n<li>Enviar \u00e1udio por link ou Base64;<\/li>\n\n\n\n<li>Enviar PDF por link ou Base64;<\/li>\n\n\n\n<li>Interpretar respostas com zaapId, messageId e id;<\/li>\n\n\n\n<li>Acompanhar processamento, entrega e leitura;<\/li>\n\n\n\n<li>Diagnosticar erros comuns;<\/li>\n\n\n\n<li>Estruturar o envio com mais seguran\u00e7a para produ\u00e7\u00e3o.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Importante<\/strong>: os exemplos usam placeholders como {<strong>instanceId<\/strong>}, {<strong>token<\/strong>}, &lt;<strong>api-key<\/strong>> e <strong>5511999999999<\/strong>. Substitua esses valores pelas credenciais e pelo telefone de teste da sua pr\u00f3pria inst\u00e2ncia.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Como enviar textos, \u00e1udios e PDFs pela API?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">O envio de uma mensagem passa por algumas etapas:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Sua aplica\u00e7\u00e3o<br><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u2193 POST autenticado<br><br>API do Z-API<br><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u2193 retorna IDs<br><br>Fila da inst\u00e2ncia<br><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u2193<br><br>App de mensagens<br><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u2193 webhooks<br><br>Processamento, entrega e leitura<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Na documenta\u00e7\u00e3o de quickstart, o Z-API descreve um fluxo em que a aplica\u00e7\u00e3o envia a mensagem, a API adiciona o pedido a uma fila e retorna um identificador. <strong>A inst\u00e2ncia ent\u00e3o processa a fila, enquanto os webhooks informam a evolu\u00e7\u00e3o do envio<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Isso cria uma distin\u00e7\u00e3o importante:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A resposta HTTP confirma que a API recebeu a requisi\u00e7\u00e3o;<\/li>\n\n\n\n<li>O webhook de delivery informa o processamento ou uma eventual falha;<\/li>\n\n\n\n<li>O webhook de status informa mudan\u00e7as posteriores, como recebimento e leitura.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Portanto, n\u00e3o considere uma resposta HTTP 200 como prova de que o destinat\u00e1rio j\u00e1 recebeu ou leu a mensagem<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Preparando sua inst\u00e2ncia<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Antes de fazer a primeira chamada, voc\u00ea precisa ter uma inst\u00e2ncia configurada no Z-API.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Crie ou selecione uma inst\u00e2ncia<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No painel do Z-API, localize o identificador da inst\u00e2ncia. A documenta\u00e7\u00e3o informa que o instanceId est\u00e1 dispon\u00edvel na \u00e1rea de inst\u00e2ncias.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Conecte o app de mensagens<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Siga o procedimento indicado no painel para conectar a sess\u00e3o. A inst\u00e2ncia precisa estar dispon\u00edvel para processar as mensagens.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Se a inst\u00e2ncia estiver desconectada, a requisi\u00e7\u00e3o poder\u00e1 falhar ou a mensagem n\u00e3o avan\u00e7ar\u00e1 para o processamento. A documenta\u00e7\u00e3o de webhooks tamb\u00e9m descreve um evento de desconex\u00e3o quando h\u00e1 indisponibilidade na comunica\u00e7\u00e3o entre telefone, aplicativo e Z-API.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Obtenha o token da inst\u00e2ncia<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">O token \u00e9 utilizado na URL dos endpoints de envio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Trate esse valor como segredo<\/strong>. N\u00e3o publique o token no frontend, em reposit\u00f3rios, exemplos reais de c\u00f3digo ou mensagens de suporte.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4. Tenha um Client-Token<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Os exemplos atuais dos endpoints utilizam o cabe\u00e7alho:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Client-Token: <strong>&lt;api-key&gt;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mantenha esse valor em uma vari\u00e1vel de ambiente ou em um gerenciador de segredos.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5. Separe um n\u00famero de teste<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Fa\u00e7a os primeiros envios para um contato sob seu controle. Teste o conte\u00fado, os status, os webhooks e o comportamento de erro antes de incluir clientes na opera\u00e7\u00e3o.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Estrutura da URL e dos cabe\u00e7alhos<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Os endpoints seguem a estrutura:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>https:\/\/api.z-api.io\/instances\/{instanceId}\/token\/{token}\/{endpoint}<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nos exemplos deste artigo:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>instanceId = ID da inst\u00e2ncia<br>token \u00a0 \u00a0 = token da inst\u00e2ncia<br>api-key\u00a0 \u00a0 = Client-Token da conta<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Os cabe\u00e7alhos b\u00e1sicos s\u00e3o:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Content-Type: application\/json<br>Client-Token: &lt;api-key><\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">O corpo da requisi\u00e7\u00e3o deve ser enviado em JSON. Em uma aplica\u00e7\u00e3o real, valide o destinat\u00e1rio e trate corretamente caracteres especiais antes de enviar a requisi\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aproveite e conhe\u00e7a a nova funcionalidade do Z-API: <a href=\"https:\/\/z-api.io\/blog\/nova-funcionalidade-do-z-api-protecao-antifraude-em-grupos-de-whatsapp\/\" target=\"_blank\" rel=\"noreferrer noopener\">prote\u00e7\u00e3o antifraude em grupos de avisos.<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Envio de texto pela API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">O endpoint documentado para texto simples \u00e9:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>POST \/instances\/{instanceId}\/token\/{token}\/send-text<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Os principais campos s\u00e3o:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>phone: n\u00famero do destinat\u00e1rio ou identificador do grupo, em formato num\u00e9rico;<\/li>\n\n\n\n<li>message: conte\u00fado do texto.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A documenta\u00e7\u00e3o orienta enviar o telefone somente com n\u00fameros, sem m\u00e1scara ou formata\u00e7\u00e3o, como:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>5511999999999<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Envio de texto com cURL<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>curl &#8211;request POST \\<br>\u00a0\u00a0&#8211;url https:\/\/api.z-api.io\/instances\/{instanceId}\/token\/{token}\/send-text \\<br>\u00a0\u00a0&#8211;header &#8216;Client-Token: &lt;api-key>&#8217; \\<br>\u00a0\u00a0&#8211;header &#8216;Content-Type: application\/json&#8217; \\<br>\u00a0\u00a0&#8211;data &#8216;{<br>\u00a0\u00a0\u00a0\u00a0&#8220;phone&#8221;: &#8220;5511999999999&#8221;,<br>\u00a0\u00a0\u00a0\u00a0&#8220;message&#8221;: &#8220;Ol\u00e1! Seu pedido foi confirmado.&#8221;<br>\u00a0\u00a0}&#8217;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Substitua:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>{instanceId} pelo ID da inst\u00e2ncia;<\/li>\n\n\n\n<li>{token} pelo token da inst\u00e2ncia;<\/li>\n\n\n\n<li>&lt;api-key&gt; pelo Client-Token;<\/li>\n\n\n\n<li>5511999999999 pelo n\u00famero utilizado no teste.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Envio de texto com JavaScript<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>const instanceId = process.env.ZAPI_INSTANCE_ID;<br>const token = process.env.ZAPI_TOKEN;<br>const clientToken = process.env.ZAPI_CLIENT_TOKEN;<br><br>const url = `https:\/\/api.z-api.io\/instances\/instanceId\/token\/{token}\/send-text`;<br><br>const response = await fetch(url, {<br>&nbsp;&nbsp;method: &#8220;POST&#8221;,<br>&nbsp;&nbsp;headers: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Client-Token&#8221;: clientToken,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Content-Type&#8221;: &#8220;application\/json&#8221;<br>&nbsp;&nbsp;},<br>&nbsp;&nbsp;body: JSON.stringify({<br>&nbsp;&nbsp;&nbsp;&nbsp;phone: &#8220;5511999999999&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;message: &#8220;Ol\u00e1! Seu pedido foi confirmado.&#8221;<br>&nbsp;&nbsp;})<br>});<br><br>const body = await response.json();<br><br>if (!response.ok) {<br>&nbsp;&nbsp;throw new Error(<br>&nbsp;&nbsp;&nbsp;&nbsp;`Falha ao enviar texto: ${response.status} ${JSON.stringify(body)}`<br>&nbsp;&nbsp;);<br>}<br><br>console.log(&#8220;Mensagem aceita pela API:&#8221;, body);<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Resposta esperada<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A documenta\u00e7\u00e3o apresenta uma resposta 200 com identificadores como:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>{<br>&nbsp;&nbsp;&#8220;zaapId&#8221;: &#8220;3999984263738042930CD6ECDE9VDWSA&#8221;,<br>&nbsp;&nbsp;&#8220;messageId&#8221;: &#8220;D241XXXX732339502B68&#8221;,<br>&nbsp;&nbsp;&#8220;id&#8221;: &#8220;D241XXXX732339502B68&#8221;<br>}<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Salve o messageId no seu banco de dados. Ele permite relacionar o envio inicial aos eventos posteriores de delivery e status.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Recursos opcionais no texto<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A documenta\u00e7\u00e3o tamb\u00e9m apresenta op\u00e7\u00f5es para adicionar atraso antes do envio e atraso relacionado ao estado de digita\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esses recursos podem ser \u00fateis em fluxos conversacionais, mas devem ser utilizados com crit\u00e9rio. <strong>O objetivo n\u00e3o deve ser esconder a lat\u00eancia de uma integra\u00e7\u00e3o lenta<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Voc\u00ea tamb\u00e9m pode utilizar formata\u00e7\u00e3o de texto, emojis e quebras de linha. Mensagens longas devem ser revisadas para leitura em telas pequenas e para n\u00e3o esconder a a\u00e7\u00e3o principal.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Envio de \u00e1udio pela API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">O endpoint documentado para \u00e1udio \u00e9:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>POST \/instances\/{instanceId}\/token\/{token}\/send-audio<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Os principais campos s\u00e3o:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>phone: destinat\u00e1rio;<\/li>\n\n\n\n<li>audio: URL p\u00fablica do \u00e1udio ou conte\u00fado em Base64.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A documenta\u00e7\u00e3o apresenta duas formas de enviar o arquivo:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>por link<\/strong>, quando o \u00e1udio est\u00e1 hospedado em uma URL acess\u00edvel;<\/li>\n\n\n\n<li><strong>por Base64<\/strong>, quando a aplica\u00e7\u00e3o envia o conte\u00fado codificado.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Envio de \u00e1udio por link com cURL<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>curl &#8211;request POST \\<br>&nbsp;&nbsp;&#8211;url https:\/\/api.z-api.io\/instances\/{instanceId}\/token\/{token}\/send-audio \\<br>&nbsp;&nbsp;&#8211;header &#8216;Client-Token: &lt;api-key&gt;&#8217; \\<br>&nbsp;&nbsp;&#8211;header &#8216;Content-Type: application\/json&#8217; \\<br>&nbsp;&nbsp;&#8211;data &#8216;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;phone&#8221;: &#8220;5511999999999&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;audio&#8221;: &#8220;https:\/\/example.com\/audio.mp3&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;viewOnce&#8221;: false,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;waveform&#8221;: true<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A URL precisa estar acess\u00edvel pela infraestrutura respons\u00e1vel pelo processamento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Evite links que dependam de login, cookies ou autentica\u00e7\u00e3o exclusiva do navegador.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Envio de \u00e1udio por link com JavaScript<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>const instanceId = process.env.ZAPI_INSTANCE_ID;<br>const token = process.env.ZAPI_TOKEN;<br>const clientToken = process.env.ZAPI_CLIENT_TOKEN;<br><br>const url = `https:\/\/api.z-api.io\/instances\/instanceId\/token\/{token}\/send-audio`;<br><br>const payload = {<br>&nbsp;&nbsp;phone: &#8220;5511999999999&#8221;,<br>&nbsp;&nbsp;audio: &#8220;https:\/\/example.com\/audio.mp3&#8221;,<br>&nbsp;&nbsp;viewOnce: false,<br>&nbsp;&nbsp;waveform: true<br>};<br><br>const response = await fetch(url, {<br>&nbsp;&nbsp;method: &#8220;POST&#8221;,<br>&nbsp;&nbsp;headers: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Client-Token&#8221;: clientToken,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Content-Type&#8221;: &#8220;application\/json&#8221;<br>&nbsp;&nbsp;},<br>&nbsp;&nbsp;body: JSON.stringify(payload)<br>});<br><br>const body = await response.json();<br><br>if (!response.ok) {<br>&nbsp;&nbsp;throw new Error(<br>&nbsp;&nbsp;&nbsp;&nbsp;`Falha ao enviar \u00e1udio: ${response.status} ${JSON.stringify(body)}`<br>&nbsp;&nbsp;);<br>}<br><br>console.log(&#8220;\u00c1udio aceito pela API:&#8221;, body);<br><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Envio de \u00e1udio em Base64<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Quando a aplica\u00e7\u00e3o j\u00e1 possui o arquivo localmente, voc\u00ea pode codific\u00e1-lo e montar um Data URL. Exemplo em Node.js:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>import { readFile } from &#8220;node:fs\/promises&#8221;;<br><br>const audioBuffer = await readFile(&#8220;.\/audio.mp3&#8221;);<br>const base64 = audioBuffer.toString(&#8220;base64&#8221;);<br>const audioDataUrl = `data:audio\/mpeg;base64,base64`;consturl=`https:\/\/api.z-api.io\/instances\/{process.env.ZAPI_INSTANCE_ID}` +<br>&nbsp;&nbsp;`\/token\/${process.env.ZAPI_TOKEN}\/send-audio`;<br><br>const response = await fetch(url, {<br>&nbsp;&nbsp;method: &#8220;POST&#8221;,<br>&nbsp;&nbsp;headers: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Client-Token&#8221;: process.env.ZAPI_CLIENT_TOKEN,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Content-Type&#8221;: &#8220;application\/json&#8221;<br>&nbsp;&nbsp;},<br>&nbsp;&nbsp;body: JSON.stringify({<br>&nbsp;&nbsp;&nbsp;&nbsp;phone: &#8220;5511999999999&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;audio: audioDataUrl,<br>&nbsp;&nbsp;&nbsp;&nbsp;waveform: true<br>&nbsp;&nbsp;})<br>});<br><br>const result = await response.json();<br><br>if (!response.ok) {<br>&nbsp;&nbsp;throw new Error(JSON.stringify(result));<br>}<br><br>console.log(result);<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">O Base64 aumenta o tamanho da requisi\u00e7\u00e3o. Para arquivos maiores ou fluxos frequentes, um link est\u00e1vel pode ser mais eficiente, desde que o arquivo permane\u00e7a dispon\u00edvel durante o processamento.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Op\u00e7\u00f5es de \u00e1udio<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A documenta\u00e7\u00e3o apresenta campos opcionais para:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>viewOnce: enviar como visualiza\u00e7\u00e3o \u00fanica;<\/li>\n\n\n\n<li>waveform: exibir ondas de \u00e1udio;<\/li>\n\n\n\n<li>delayMessage: aguardar antes de enviar;<\/li>\n\n\n\n<li>delayTyping: simular o estado de grava\u00e7\u00e3o;<\/li>\n\n\n\n<li>processamento em segundo plano, quando suportado pelo endpoint.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use essas op\u00e7\u00f5es apenas quando fizerem sentido para a experi\u00eancia. O estado de grava\u00e7\u00e3o, por exemplo, n\u00e3o deve ser utilizado para mascarar a lat\u00eancia de um sistema lento.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Resposta do envio de \u00e1udio<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">O retorno de sucesso segue a mesma estrutura de identificadores:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>{&nbsp;&nbsp;<br>&#8220;zaapId&#8221;: &#8220;3999984263738042930CD6ECDE9VDWSA&#8221;,&nbsp;&nbsp;<br>&#8220;messageId&#8221;: &#8220;D241XXXX732339502B68&#8221;,&nbsp;&nbsp;<br>&#8220;id&#8221;: &#8220;D241XXXX732339502B68&#8221;<br>}<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Salve o messageId e acompanhe os webhooks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O fato de o arquivo ter sido aceito pela API n\u00e3o significa que o \u00e1udio j\u00e1 foi entregue ao destinat\u00e1rio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aproveite e confira tamb\u00e9m: <a href=\"https:\/\/z-api.io\/blog\/carrosseis-no-whatsapp-saiba-como-criar\/\" target=\"_blank\" rel=\"noreferrer noopener\">como enviar carross\u00e9is de produtos por mensagem com o Z-API.<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Envio de PDF pela API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">O endpoint documentado para documentos \u00e9:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>POST \/instances\/{instanceId}\/token\/{token}\/send-document\/{extension}<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para um PDF, substitua {extension} por pdf:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>POST \/instances\/{instanceId}\/token\/{token}\/send-document\/pdf<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Os principais campos s\u00e3o:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>phone: destinat\u00e1rio;<\/li>\n\n\n\n<li>document: URL p\u00fablica ou conte\u00fado em Base64;<\/li>\n\n\n\n<li>fileName: nome apresentado ao destinat\u00e1rio, quando utilizado.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A extens\u00e3o do arquivo faz parte do caminho do endpoint. Portanto, quando o endpoint exigir \/send-document\/pdf, n\u00e3o utilize apenas \/send-document.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Envio de PDF por link com cURL<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>curl &#8211;request POST \\<br>&nbsp;&nbsp;&#8211;url https:\/\/api.z-api.io\/instances\/{instanceId}\/token\/{token}\/send-document\/pdf \\<br>&nbsp;&nbsp;&#8211;header &#8216;Client-Token: &lt;api-key&gt;&#8217; \\<br>&nbsp;&nbsp;&#8211;header &#8216;Content-Type: application\/json&#8217; \\<br>&nbsp;&nbsp;&#8211;data &#8216;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;phone&#8221;: &#8220;5511999999999&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;document&#8221;: &#8220;https:\/\/example.com\/arquivos\/contrato.pdf&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;fileName&#8221;: &#8220;Contrato.pdf&#8221;<br>&nbsp;&nbsp;}&#8217;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Use uma URL que entregue o arquivo correto e permane\u00e7a dispon\u00edvel pelo tempo necess\u00e1rio para o processamento.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Envio de PDF por link com JavaScript<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>const instanceId = process.env.ZAPI_INSTANCE_ID;<br>const token = process.env.ZAPI_TOKEN;<br>const clientToken = process.env.ZAPI_CLIENT_TOKEN;<br><br>const url =<br>&nbsp;&nbsp;`https:\/\/api.z-api.io\/instances\/instanceId`+`\/token\/{token}\/send-document\/pdf`;<br><br>const payload = {<br>&nbsp;&nbsp;phone: &#8220;5511999999999&#8221;,<br>&nbsp;&nbsp;document: &#8220;https:\/\/example.com\/arquivos\/contrato.pdf&#8221;,<br>&nbsp;&nbsp;fileName: &#8220;Contrato.pdf&#8221;,<br>&nbsp;&nbsp;caption: &#8220;Segue o documento solicitado.&#8221;<br>};<br>const response = await fetch(url, {<br>&nbsp;&nbsp;method: &#8220;POST&#8221;,<br>&nbsp;&nbsp;headers: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Client-Token&#8221;: clientToken,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Content-Type&#8221;: &#8220;application\/json&#8221;<br>&nbsp;&nbsp;},<br>&nbsp;&nbsp;body: JSON.stringify(payload)<br>});<br><br>const body = await response.json();<br><br>if (!response.ok) {<br>&nbsp;&nbsp;throw new Error(<br>&nbsp;&nbsp;&nbsp;&nbsp;`Falha ao enviar PDF: ${response.status} ${JSON.stringify(body)}`<br>&nbsp;&nbsp;);<br>}<br><br>console.log(&#8220;PDF aceito pela API:&#8221;, body);<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A documenta\u00e7\u00e3o apresenta fileName e descri\u00e7\u00e3o do documento como atributos opcionais. Consulte o endpoint utilizado para confirmar o nome exato do campo de legenda ou descri\u00e7\u00e3o dispon\u00edvel na sua vers\u00e3o.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Envio de PDF em Base64<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Voc\u00ea tamb\u00e9m pode converter um arquivo local para Base64:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>import { readFile } from &#8220;node:fs\/promises&#8221;;<br><br>const pdfBuffer = await readFile(&#8220;.\/contrato.pdf&#8221;);<br>const pdfBase64 = pdfBuffer.toString(&#8220;base64&#8221;);<br>const documentDataUrl = `data:application\/pdf;base64,pdfBase64`;consturl=`https:\/\/api.z-api.io\/instances\/{process.env.ZAPI_INSTANCE_ID}` +<br>&nbsp;&nbsp;`\/token\/${process.env.ZAPI_TOKEN}\/send-document\/pdf`;<br><br>const response = await fetch(url, {<br>&nbsp;&nbsp;method: &#8220;POST&#8221;,<br>&nbsp;&nbsp;headers: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Client-Token&#8221;: process.env.ZAPI_CLIENT_TOKEN,<br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Content-Type&#8221;: &#8220;application\/json&#8221;<br>&nbsp;&nbsp;},<br>&nbsp;&nbsp;body: JSON.stringify({<br>&nbsp;&nbsp;&nbsp;&nbsp;phone: &#8220;5511999999999&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;document: documentDataUrl,<br>&nbsp;&nbsp;&nbsp;&nbsp;fileName: &#8220;Contrato.pdf&#8221;<br>&nbsp;&nbsp;})<br>});<br><br>const result = await response.json();<br><br>if (!response.ok) {<br>&nbsp;&nbsp;throw new Error(JSON.stringify(result));<br>}<br><br>console.log(result);<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Use Base64 com cuidado. Arquivos grandes aumentam o tamanho do payload e o consumo de mem\u00f3ria no processo que prepara a requisi\u00e7\u00e3o. Para uma opera\u00e7\u00e3o de maior escala, considere uma hospedagem controlada e URLs com validade adequada.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Resposta do envio de PDF<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Em uma resposta bem-sucedida, a documenta\u00e7\u00e3o apresenta os IDs da mensagem:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>{&nbsp;&nbsp;<br>&#8220;zaapId&#8221;: &#8220;3999984263738042930CD6ECDE9VDWSA&#8221;,&nbsp;&nbsp;<br>&#8220;messageId&#8221;: &#8220;D241XXXX732339502B68&#8221;,&nbsp;&nbsp;<br>&#8220;id&#8221;: &#8220;D241XXXX732339502B68&#8221;<br>}<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">N\u00e3o descarte esses valores depois do console.log. Em produ\u00e7\u00e3o, grave o messageId junto ao pedido, cliente ou atendimento que originou o envio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Como validar o status da mensagem?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A documenta\u00e7\u00e3o de webhooks do Z-API apresenta quatro grupos de eventos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Delivery<\/strong>: informa quando a mensagem foi processada ou quando ocorreu uma falha no processamento;<\/li>\n\n\n\n<li><strong>Receive<\/strong>: ocorre quando algu\u00e9m interage com seu n\u00famero;<\/li>\n\n\n\n<li><strong>Status<\/strong>: informa mudan\u00e7as como received, read, replied e deleted;<\/li>\n\n\n\n<li><strong>Disconnected<\/strong>: indica indisponibilidade na comunica\u00e7\u00e3o entre telefone, aplicativo e Z-API.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esses eventos permitem acompanhar a mensagem depois da requisi\u00e7\u00e3o inicial.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Configure uma URL HTTPS<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A aplica\u00e7\u00e3o deve disponibilizar endpoints HTTPS para receber os POSTs do Z-API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uma estrutura poss\u00edvel \u00e9:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>POST https:\/\/app.exemplo.com\/webhooks\/zapi\/delivery<br><br>POST https:\/\/app.exemplo.com\/webhooks\/zapi\/status<br><br>POST https:\/\/app.exemplo.com\/webhooks\/zapi\/receive<br><br>POST https:\/\/app.exemplo.com\/webhooks\/zapi\/disconnected<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Consulte a documenta\u00e7\u00e3o do painel e do endpoint de configura\u00e7\u00e3o para definir as rotas corretas na sua inst\u00e2ncia.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Registre o ID da mensagem<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">O fluxo de valida\u00e7\u00e3o deve relacionar o evento recebido ao messageId salvo na resposta inicial.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>app.post(&#8220;\/webhooks\/zapi\/status&#8221;, async (req, res) =&gt; {<br>&nbsp;&nbsp;const event = req.body;<br><br>&nbsp;&nbsp;\/\/ Responda rapidamente ao provedor.<br>&nbsp;&nbsp;res.sendStatus(200);<br><br>&nbsp;&nbsp;if (!event.messageId) {<br>&nbsp;&nbsp;&nbsp;&nbsp;console.warn(&#8220;Status sem messageId&#8221;, event);<br>&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;await messages.updateByMessageId(event.messageId, {<br>&nbsp;&nbsp;&nbsp;&nbsp;status: event.status,<br>&nbsp;&nbsp;&nbsp;&nbsp;receivedAt: new Date()<br>&nbsp;&nbsp;});<br>});<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Em produ\u00e7\u00e3o, valide a autenticidade do webhook, trate duplicidades e mova o processamento pesado para uma fila.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Estados n\u00e3o s\u00e3o equivalentes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Evite tratar todos os retornos como se representassem o mesmo estado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uma estrutura poss\u00edvel \u00e9:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>REQUEST_ACCEPTED<br><br>PROCESSING<br><br>SENT_TO_WHATSAPP<br><br>RECEIVED<br><br>READ<br><br>FAILED<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A resposta 200 da requisi\u00e7\u00e3o inicial pode representar REQUEST_ACCEPTED.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O webhook de delivery pode atualizar o registro para SENT_TO_WHATSAPP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O webhook de status pode atualizar o estado para RECEIVED ou READ.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Essa separa\u00e7\u00e3o permite identificar em qual etapa ocorreu uma falha e evita que o sistema apresente uma mensagem como entregue antes de existir confirma\u00e7\u00e3o correspondente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quanto custa a automa\u00e7\u00e3o de mensagens para pequenas empresas em 2026? <a href=\"https:\/\/z-api.io\/blog\/quanto-custa-a-automacao-de-whatsapp-para-pequenas-empresas-em-2026\/\" target=\"_blank\" rel=\"noreferrer noopener\">Acesse e confira tudo sobre o investimento em API de mensagens.<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10 erros comuns e como corrigir<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. URL com instanceId ou token incorreto<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: erro de autentica\u00e7\u00e3o ou inst\u00e2ncia n\u00e3o encontrada.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verifique se os valores foram copiados do painel correto e se n\u00e3o h\u00e1 espa\u00e7os, aspas ou caracteres extras.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Client-Token ausente<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: a chamada chega ao endpoint, mas \u00e9 rejeitada.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inclua o cabe\u00e7alho exatamente como documentado:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Client-Token: <strong>&lt;api-key&gt;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">N\u00e3o confunda o Client-Token com o token da inst\u00e2ncia. Eles aparecem em lugares diferentes da requisi\u00e7\u00e3o.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Telefone com m\u00e1scara<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: destinat\u00e1rio inv\u00e1lido ou envio n\u00e3o processado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Utilize somente n\u00fameros no formato indicado pela documenta\u00e7\u00e3o, sem +, espa\u00e7os, par\u00eanteses ou h\u00edfens:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>5511999999999<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para grupos, use o identificador de grupo quando o endpoint permitir.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4. Endpoint de PDF sem extens\u00e3o<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: rota n\u00e3o encontrada ou requisi\u00e7\u00e3o inv\u00e1lida.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\/send-document\/pdf<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">e n\u00e3o apenas:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\/send-document<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">quando o endpoint exigir a extens\u00e3o.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5. URL do arquivo inacess\u00edvel<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: texto funciona, mas \u00e1udio ou PDF falha.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Teste a URL fora da sua rede. Verifique se:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ela responde sem login;<\/li>\n\n\n\n<li>entrega o arquivo correto;<\/li>\n\n\n\n<li>o certificado \u00e9 v\u00e1lido;<\/li>\n\n\n\n<li>n\u00e3o expira antes do processamento.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">6. Base64 malformado<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: arquivo corrompido ou erro no processamento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Confirme o MIME type e a estrutura do Data URL:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>data:audio\/mpeg;base64,&#8230;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>data:application\/pdf;base64,&#8230;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Evite quebras de linha acidentais ou a duplica\u00e7\u00e3o do prefixo.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">7. JSON inv\u00e1lido<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: erro 400 ou corpo n\u00e3o interpretado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No JavaScript, utilize <strong>JSON.stringify<\/strong>. No cURL, confira aspas e caracteres especiais.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ao inserir vari\u00e1veis dinamicamente, valide quebras de linha e caracteres especiais.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">8. Confundir resposta com entrega<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: o sistema marca a mensagem como entregue assim que recebe a resposta da API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A resposta inicial deve ser tratada como aceite ou processamento inicial. Atualize o estado com os webhooks de delivery e status.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">9. Inst\u00e2ncia desconectada<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma<\/strong>: mensagens n\u00e3o avan\u00e7am ou os webhooks informam indisponibilidade.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verifique o painel da inst\u00e2ncia, a conex\u00e3o do aplicativo de mensagens e o evento de desconex\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Evite criar novas tentativas em loop sem entender a causa da falha.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">10. Credenciais expostas<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sintoma:<\/strong> chamadas inesperadas ou risco de uso indevido.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Revogue e substitua as chaves comprometidas. Mantenha as credenciais no backend e nunca no c\u00f3digo JavaScript executado no navegador.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Envio seguro em produ\u00e7\u00e3o<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Depois que o primeiro envio funcionar, a prioridade deve ser transformar o exemplo em uma integra\u00e7\u00e3o controlada.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Use vari\u00e1veis de ambiente<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>ZAPI_INSTANCE_ID=seu_instance_id<br><br>ZAPI_TOKEN=seu_token<br><br>ZAPI_CLIENT_TOKEN=sua_client_token<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">No c\u00f3digo, leia essas vari\u00e1veis pelo ambiente de execu\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>N\u00e3o envie os valores para o frontend<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Crie uma camada de servi\u00e7o<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Em vez de espalhar URLs e credenciais pela aplica\u00e7\u00e3o, centralize o envio em uma camada de servi\u00e7o:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>async function sendText({ phone, message }) {<br>&nbsp;&nbsp;const url =<br>&nbsp;&nbsp;&nbsp;&nbsp;`https:\/\/api.z-api.io\/instances\/process.env.ZAPIINSTANCEID`+`\/token\/{process.env.ZAPI_TOKEN}\/send-text`;<br><br>&nbsp;&nbsp;const response = await fetch(url, {<br>&nbsp;&nbsp;&nbsp;&nbsp;method: &#8220;POST&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;headers: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Client-Token&#8221;: process.env.ZAPI_CLIENT_TOKEN,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Content-Type&#8221;: &#8220;application\/json&#8221;<br>&nbsp;&nbsp;&nbsp;&nbsp;},<br>&nbsp;&nbsp;&nbsp;&nbsp;body: JSON.stringify({ phone, message })<br>&nbsp;&nbsp;});<br><br>&nbsp;&nbsp;const result = await response.json();<br><br>&nbsp;&nbsp;if (!response.ok) {<br>&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Z-API ${response.status}: ${JSON.stringify(result)}`<br>&nbsp;&nbsp;&nbsp;&nbsp;);<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;return result;<br>}<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A mesma camada pode ter m\u00e9todos para sendAudio e sendDocument. Isso facilita:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>testes;<\/li>\n\n\n\n<li>logs;<\/li>\n\n\n\n<li>tratamento de erros;<\/li>\n\n\n\n<li>padroniza\u00e7\u00e3o;<\/li>\n\n\n\n<li>manuten\u00e7\u00e3o;<\/li>\n\n\n\n<li>eventual altera\u00e7\u00e3o do fornecedor.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Use filas e idempot\u00eancia<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Se um evento do seu sistema gerar uma mensagem, registre uma chave de opera\u00e7\u00e3o antes de enviar. Assim, uma retentativa de webhook ou de workflow n\u00e3o cria duas mensagens para o mesmo pedido ou evento.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Monitore tudo<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Registre, no m\u00ednimo:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>tipo de mensagem;<\/li>\n\n\n\n<li>destinat\u00e1rio;<\/li>\n\n\n\n<li>origem do evento;<\/li>\n\n\n\n<li>hor\u00e1rio da chamada;<\/li>\n\n\n\n<li>status HTTP;<\/li>\n\n\n\n<li>messageId;<\/li>\n\n\n\n<li>status posterior;<\/li>\n\n\n\n<li>erro retornado;<\/li>\n\n\n\n<li>n\u00famero de tentativas.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">N\u00e3o armazene conte\u00fado sens\u00edvel sem necessidade. Proteja os logs e limite o acesso \u00e0s informa\u00e7\u00f5es.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checklist para o primeiro envio<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Antes de colocar a integra\u00e7\u00e3o para funcionar, confirme:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Criar ou selecionar uma inst\u00e2ncia;<\/li>\n\n\n\n<li>conectar a inst\u00e2ncia;<\/li>\n\n\n\n<li>obter instanceId e token;<\/li>\n\n\n\n<li>obter o Client-Token;<\/li>\n\n\n\n<li>definir um n\u00famero de teste;<\/li>\n\n\n\n<li>montar a URL correta;<\/li>\n\n\n\n<li>usar Content-Type: application\/json;<\/li>\n\n\n\n<li>enviar o telefone sem m\u00e1scara;<\/li>\n\n\n\n<li>testar primeiro o envio de texto;<\/li>\n\n\n\n<li>salvar zaapId e messageId;<\/li>\n\n\n\n<li>testar \u00e1udio por link;<\/li>\n\n\n\n<li>testar \u00e1udio em Base64, se necess\u00e1rio;<\/li>\n\n\n\n<li>testar PDF com \/send-document\/pdf;<\/li>\n\n\n\n<li>configurar webhooks HTTPS;<\/li>\n\n\n\n<li>diferenciar aceite, processamento, entrega e leitura;<\/li>\n\n\n\n<li>simular erros de URL e credenciais;<\/li>\n\n\n\n<li>implementar logs e idempot\u00eancia;<\/li>\n\n\n\n<li>validar pol\u00edticas e consentimento antes de escalar.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Envie textos, \u00e1udios e PDFs integrando seu sistema com o Z-API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Enviar textos, \u00e1udios e PDFs pela API de mensagens envolve mais do que copiar um endpoint. \u00c9 preciso preparar a inst\u00e2ncia, autenticar a chamada, montar o payload correto, hospedar arquivos quando optar por link, interpretar a resposta e acompanhar os eventos posteriores.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para texto, o endpoint utilizado \u00e9 <strong>\/send-text<\/strong>. Para \u00e1udio, <strong>\/send-audio<\/strong>, com possibilidade de utilizar link ou Base64. Para PDF, <strong>\/send-document\/pdf<\/strong>, com a extens\u00e3o no caminho e o documento enviado por link ou Base64.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Em todos os casos, <strong>salve o<\/strong> <strong>messageId<\/strong>. A resposta inicial indica que a requisi\u00e7\u00e3o foi aceita, mas os webhooks permitem acompanhar o processamento, o recebimento e a leitura.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Comece com um contato de teste, valide os tr\u00eas tipos de conte\u00fado e s\u00f3 depois conecte os endpoints a pedidos, leads, notifica\u00e7\u00f5es ou atendimentos reais.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fa\u00e7a seu primeiro envio pela API: <strong>configure uma inst\u00e2ncia, execute um dos exemplos deste tutorial e acompanhe o resultado pelos webhooks do Z-API<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-right kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;right&quot;,&quot;id&quot;:&quot;11267&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;5&quot;,&quot;greet&quot;:&quot;Avalie este post&quot;,&quot;legend&quot;:&quot;0\\\/5 - (0 voto)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;Como enviar textos, \u00e1udios e PDFs via API de mensagens&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\">\n            <span class=\"kksr-muted\">Avalie este post<\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Aprenda a enviar textos, \u00e1udios e PDFs pela API de mensagens com cURL, JavaScript, autentica\u00e7\u00e3o, endpoints e webhooks do Z-API.<\/p>\n","protected":false},"author":16,"featured_media":11861,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"content-type":"","footnotes":""},"categories":[2,5],"tags":[],"class_list":["post-11267","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-api-rest-mensageria","category-tutoriais"],"_links":{"self":[{"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/posts\/11267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/comments?post=11267"}],"version-history":[{"count":3,"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/posts\/11267\/revisions"}],"predecessor-version":[{"id":11454,"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/posts\/11267\/revisions\/11454"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/media\/11861"}],"wp:attachment":[{"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/media?parent=11267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/categories?post=11267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/z-api.io\/blog\/wp-json\/wp\/v2\/tags?post=11267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}