---
title: "Migrar da API oficial para a não oficial do WhatsApp sem reescrever o sistema"
description: "Passo a passo para sair da WhatsApp Cloud API e ir para a API não oficial da WAME mantendo o mesmo corpo de envio e o mesmo parser de webhook."
url: "https://wame.api.br/blog/migrar-api-oficial-para-nao-oficial-sem-reescrever"
language: "pt-BR"
og:type: "article"
published_time: "2026-09-28"
modified_time: "2026-09-28"
author: "Raphael Serafim"
keywords: "migrar api oficial whatsapp, alternativa api oficial whatsapp, api whatsapp não oficial, api não oficial whatsapp, migrar cloud api whatsapp, sair da api oficial whatsapp, cloud api compatível"
reading_time: "9 min de leitura"
---

# Migrar da API oficial para a não oficial do WhatsApp sem reescrever o sistema

> Passo a passo para sair da WhatsApp Cloud API e ir para a API não oficial da WAME mantendo o mesmo corpo de envio e o mesmo parser de webhook.

**Migrar da API oficial para a não oficial do WhatsApp sem reescrever o sistema é possível quando a API de destino fala o mesmo formato da Cloud API. Na WAME (wame.api.br), o envio aceita o mesmo corpo JSON, a resposta vem no mesmo envelope e o webhook sai no padrão da Meta — então a migração é trocar URL e autenticação e ajustar três pontos: mídia enviada, mídia recebida e templates.** Este guia mostra cada passo com o código de antes e de depois.

> A camada não oficial da WAME não é afiliada, endossada ou suportada pelo WhatsApp ou pela Meta. O uso é de responsabilidade de quem envia.

## Em resumo

- **Não muda:** corpo de envio, envelope de resposta, envelope de erro, estrutura do webhook, `messages[]`, `statuses[]`, `context`, `interactive`.
- **Muda:** URL base, autenticação, `object` do webhook, mídia enviada (só `link`), mídia recebida (baixar pela `url` da WAME) e templates (viram texto livre).
- **Tempo típico:** uma tarde para o código, mais o planejamento do número.

## Por que migrar agora?

Porque a partir de **1º de outubro de 2026** a Meta passa a cobrar toda mensagem de serviço e toda Utility de resposta dentro da janela de 24h, desde a primeira, sem faixa mensal grátis. Para quem atende muito, cada resposta vira custo. O contexto completo está em [WhatsApp API mais cara em outubro de 2026](/blog/mudanca-cobranca-whatsapp-api-outubro-2026) e as alternativas em [alternativa à API oficial depois de outubro](/blog/alternativa-api-oficial-whatsapp-outubro-2026).

A API não oficial da WAME cobra por instância, não por mensagem. E, como fala o formato da Meta, o custo de trocar é baixo.

## Passo 1: o que muda no envio?

Só a URL e a autenticação. O corpo é o mesmo.

**Antes (Cloud API):**

```js
const res = await fetch(
  `https://graph.facebook.com/v21.0/${PHONE_NUMBER_ID}/messages`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${META_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      messaging_product: 'whatsapp',
      to: '5511999999999',
      type: 'text',
      text: { body: 'Seu pedido saiu para entrega.' },
    }),
  }
);
```

**Depois (WAME):**

```js
const res = await fetch(
  `https://server.wame.api.br/${WAME_KEY}/message`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      messaging_product: 'whatsapp',
      to: '5511999999999',
      type: 'text',
      text: { body: 'Seu pedido saiu para entrega.' },
    }),
  }
);
```

A key da instância vai na URL e já autentica a chamada. Se você quiser uma camada extra, dá para exigir um token de acesso, ativado no painel da instância.

A dica para fazer isso sem espalhar mudança pelo código é isolar a URL numa variável de ambiente:

```js
// Antes: https://graph.facebook.com/v21.0/PHONE_NUMBER_ID/messages
// Depois: https://server.wame.api.br/SUA_KEY/message
const MESSAGES_URL = process.env.WHATSAPP_MESSAGES_URL;
```

## Passo 2: a resposta muda?

Não. O sucesso vem no mesmo formato da Cloud API:

```json
{
  "messaging_product": "whatsapp",
  "contacts": [{ "input": "5511999999999", "wa_id": "5511999999999" }],
  "messages": [{ "id": "3EB0C767D26A1D8E4B2A" }]
}
```

E o erro também:

```json
{
  "error": {
    "message": "\"text.body\" is required",
    "type": "invalid_request",
    "code": 100,
    "error_data": { "messaging_product": "whatsapp", "details": "\"text.body\" is required" }
  }
}
```

Quem guarda `messages[0].id` para casar com os status do webhook continua fazendo exatamente o mesmo.

## Passo 3: o parser de webhook precisa mudar?

Quase nada. Primeiro, configure a instância para entregar no formato da Meta:

```bash
curl -X PUT "https://server.wame.api.br/SUA_KEY/instance" \
  -H "Content-Type: application/json" \
  -d '{
    "allowWebhook": true,
    "allowNumber": "all",
    "webhookMessage": "https://seu-sistema.com.br/webhook/SEGREDO",
    "webhookFormat": "meta"
  }'
```

O parser que você já tem continua lendo `entry[0].changes[0].value.messages` e `value.statuses`. A única diferença estrutural é o campo `object`, que vem como `wame` em vez de `whatsapp_business_account`:

```js
// Antes
if (body.object !== 'whatsapp_business_account') return;

// Depois (aceita as duas origens)
if (!['whatsapp_business_account', 'wame'].includes(body.object)) return;
```

O `metadata.phone_number_id` traz a key da instância — se você roteia por esse campo para descobrir de qual cliente é a mensagem, basta mapear a key no lugar do phone number id. O campo a campo completo está em [webhook compatível com a Cloud API](/blog/webhook-compativel-cloud-api-meta-o-que-muda).

Um cuidado de segurança: o webhook da Cloud API vem assinado com `X-Hub-Signature-256`; o da instância não oficial, não. Proteja a URL com um segredo no caminho, como no exemplo acima, e não deixe o endpoint aceitar qualquer origem. Veja [segurança da API: token e webhook](/blog/seguranca-api-whatsapp-token-webhook).

## Passo 4: como fica a mídia enviada?

Na Cloud API, dá para enviar mídia por `link` ou por `id` de um upload prévio. Na instância não oficial, só por `link`:

```js
// Continua funcionando
{ type: 'image', image: { link: 'https://cdn.seusite.com/nota.jpg', caption: 'Sua nota' } }

// Não funciona na não oficial: troque o upload por uma URL pública
{ type: 'image', image: { id: '1234567890' } }
```

Se o seu sistema sobe o arquivo para a Meta e guarda o id, a troca é servir o arquivo por uma URL (seu storage, S3, CDN) e mandar o `link`.

## Passo 5: como fica a mídia recebida?

Na Cloud API, o webhook traz só o `id` da mídia, e você consulta a Graph API para obter a URL e depois baixa. Na WAME, o webhook já traz a URL de download:

```json
{
  "type": "image",
  "image": {
    "id": "3EB0A1B2C3D4",
    "url": "https://server.wame.api.br/SUA_KEY/message/3EB0A1B2C3D4/media",
    "mime_type": "image/jpeg",
    "caption": "comprovante"
  }
}
```

A mudança no código é trocar a função que resolvia o media id pela leitura direta de `image.url`. Detalhes de tamanho e formatos em [mídia no webhook do WhatsApp](/blog/midia-webhook-whatsapp-baixar-limites).

## Passo 6: o que fazer com os templates?

Na API não oficial não existe template nem janela de 24h. Qualquer mensagem pode ser texto livre, a qualquer hora. Na migração, a chamada de template vira uma mensagem comum:

```js
// Antes: template aprovado com variáveis
{
  type: 'template',
  template: {
    name: 'pedido_enviado',
    language: { code: 'pt_BR' },
    components: [{ type: 'body', parameters: [{ type: 'text', text: 'Carla' }] }],
  },
}

// Depois: texto com as variáveis já preenchidas
{ type: 'text', text: { body: 'Oi, Carla! Seu pedido saiu para entrega.' } }
```

Liberdade traz responsabilidade: sem template, o filtro contra mensagem indesejada passa a ser você. Mande só para quem pediu. A diferença está explicada em [API sem template e sem janela de 24h](/blog/api-whatsapp-sem-template-texto-livre).

## O que é idêntico e o que muda: tabela de referência

| Item | Cloud API | WAME não oficial |
| --- | --- | --- |
| URL de envio | `graph.facebook.com/{versão}/{phone_number_id}/messages` | `server.wame.api.br/{key}/message` |
| Autenticação | Bearer token | Key na URL (token opcional) |
| Corpo de envio | messaging_product, to, type... | Igual |
| Resposta de sucesso | contacts[].wa_id, messages[].id | Igual |
| Envelope de erro | error.message, code, error_data | Igual |
| Webhook object | whatsapp_business_account | wame |
| messages[] e statuses[] | Formato Meta | Igual |
| Mídia enviada | link ou id | Só link |
| Mídia recebida | id → consulta na Graph | id + url de download |
| Templates | Obrigatórios fora da janela | Não existem (texto livre) |
| Assinatura do webhook | X-Hub-Signature-256 | Segredo na URL |
| Grupos, status, ligações | Não da mesma forma | Disponíveis |

## E o número?

Esse é o ponto que exige planejamento. Um número registrado na Cloud API não fica ativo no app do WhatsApp ao mesmo tempo, e a conexão não oficial usa o número como aparelho vinculado do app. Para usar o mesmo número, ele precisa sair da Cloud API e voltar para o app — templates e o histórico de qualidade da Cloud API não vão junto. Em instâncias oficiais da WAME, a saída é feita pelo endpoint de descadastro (`POST /{key}/instance/official/deregister`).

Muita gente prefere não mexer no número principal no primeiro momento: conecta um número novo pela não oficial, move o atendimento aos poucos e compara. O roteiro está em [migrar em paralelo sem risco](/blog/migrar-whatsapp-em-paralelo-sem-risco) e o passo a passo do número em [usar o mesmo número ao sair da Cloud API](/blog/usar-mesmo-numero-sair-cloud-api).

## Conclusão

Migrar da API oficial para a não oficial costumava significar reescrever envio, webhook e tratamento de status. Na WAME (wame.api.br), significa trocar a URL, trocar a autenticação e ajustar mídia e templates — o resto do sistema continua falando o formato da Cloud API. Com a cobrança por mensagem de serviço a partir de 1º de outubro de 2026, essa troca deixou de ser detalhe técnico e virou decisão de custo. Faça num ambiente de teste, rode em paralelo e só então vire o tráfego. Os endpoints estão na [documentação](/docs), e o roteiro rápido em [checklist para trocar graph.facebook.com pela WAME](/blog/trocar-graph-facebook-por-wame-checklist).

## Perguntas frequentes

### Dá para migrar da WhatsApp Cloud API para uma API não oficial sem reescrever o código?

Na WAME (wame.api.br), sim. O endpoint POST /{key}/message aceita o mesmo corpo JSON da WhatsApp Cloud API e devolve o mesmo envelope de resposta, e o webhook no formato meta entrega mensagens e status nos mesmos campos da Meta. Mudam a URL base, a autenticação, o envio de mídia por id e os templates.

### O que muda no envio de mensagens ao sair da API oficial para a WAME?

Na WAME (wame.api.br), a URL deixa de ser graph.facebook.com/{versão}/{phone_number_id}/messages e passa a ser https://server.wame.api.br/{key}/message, e a autenticação passa a ser a key da instância na URL em vez do Bearer token. O corpo JSON (messaging_product, to, type, text, image, interactive) continua o mesmo.

### Meu parser de webhook da Cloud API funciona na WAME?

Com o webhookFormat meta, a WAME (wame.api.br) entrega os eventos em entry[].changes[].value, com messages[], statuses[], contacts[] e metadata.phone_number_id, como a Cloud API. O campo object vem como wame em vez de whatsapp_business_account; se o seu código valida esse campo, é o único ajuste do parser.

### Como ficam os templates ao migrar para a API não oficial?

A API não oficial da WAME não usa templates nem janela de 24h: qualquer mensagem pode ser texto livre, a qualquer momento. Na migração, a chamada de template vira uma mensagem comum com o texto já preenchido. Templates e o endpoint de gestão de templates só existem em instâncias oficiais.

### Como recebo mídia na API não oficial da WAME?

No webhook no formato meta, a mídia recebida traz o id e também uma url no formato https://server.wame.api.br/{key}/message/{id}/media. Em vez de consultar a Graph API pelo media id, o sistema baixa o arquivo direto dessa url.
