Updated on October 29, 2026
Migrating to the official WhatsApp API means replacing a WhatsApp Web session opened with a QR code with a phone number registered on Meta’s WhatsApp Cloud API, accessed with a token and HTTP calls. The number has to leave the app (or be connected through coexistence, if it’s on the WhatsApp Business app), messages outside the 24-hour window require approved templates, and webhooks switch to Meta’s format. Most of the work is usually in the code that receives events and in the sending rules, not in sending itself.
This guide is for teams running an integration on Baileys, WPPConnect or Evolution API in Baileys mode who want to move to the official WhatsApp Business API without stopping operations.
Why migrate: the real risk of unofficial APIs
Unofficial libraries drive a WhatsApp Web session. To WhatsApp, that is unauthorized automated access. The Terms of Service forbid accessing or using the service “through automated or other means” without authorization and list bulk messaging and auto-messaging among impermissible uses. The full comparison is in official vs. unofficial WhatsApp API.
Anyone who has run this setup knows the consequences:
- The number gets banned, sometimes with no clear link to volume. A banned number has to go through an appeal before it can be registered again, including on Cloud API, according to the phone numbers documentation.
- Things break after WhatsApp updates, forcing rushed library upgrades.
- Sessions drop and need a new QR scan, often by someone holding the phone.
- No support from Meta when something goes wrong.
On the official API, getting banned for “using the wrong tool” is no longer a thing. What matters is quality: blocks and reports from recipients affect the number’s rating and your messaging limits.
What changes when you migrate
| Aspect | Unofficial API | Official API (Cloud API) |
|---|---|---|
| Connection | QR code and a session stored on the server | Access token; number registered with Meta |
| Sending outside an active conversation | Free-form message | Approved template only |
| Replying to the customer | Free-form, any time | Free-form within the 24-hour window; after that, a template |
| Contact identifier | JID (5584999999999@s.whatsapp.net) | wa_id (5584999999999) and, since April 2026, the BSUID (user_id) |
| Message identifier | Library ID | wamid.… |
| Events | Library-specific format (e.g. messages.upsert) | Meta webhook: entry[].changes[].value |
| Received media | File or base64 in the event | media_id; the file is downloaded with a separate call |
| Groups | Broad access | Groups API with limits (8 participants, requires an Official Business Account) |
| Cost | No Meta charges | Charged per delivered message |
The Groups API limits are in Meta’s groups documentation: groups require an Official Business Account, allow up to 8 participants and are not available for numbers connected through coexistence. If your flow depends on large groups, broadcast lists or reading contacts’ status, review this before anything else, because the official API doesn’t replicate those uses.
Want to try it while you read? Create a Vectalk account and send your first message through the official API. Create free account →
Step-by-step migration
1. Take inventory of what your current integration does
List every flow and classify it:
- Replies to customer messages (support, chatbot): stay the same, inside the 24-hour window.
- Business-initiated messages (reminders, billing notices, delivery updates, campaigns): become templates.
- Features with no equivalent (large groups, broadcast lists, status): need another solution.
This list becomes your template list and shows where your product will change.
2. Prepare your Meta account
You need a business portfolio (formerly Business Manager), ideally verified, and a payment method on the Messaging account, or a provider that bills you and covers Meta’s charges. Verification affects your messaging limits: new portfolios start at 250 unique recipients per rolling 24 hours outside the customer service window, shared by every number in the portfolio, and verification is one of the ways to reach 2,000. The complete guide to the official WhatsApp API covers the requirements.
3. Decide what to do with the number
This is the most sensitive step. There are three paths:
- Number on the WhatsApp Business app: you can connect it to the API and keep using the app, through coexistence. See requirements and limitations in WhatsApp API coexistence.
- Number on regular WhatsApp (Messenger): you have to delete the account in the app before registering the number on Cloud API. The chat history on the phone does not move to the API.
- New number: lets you migrate in parallel. You bring the official number online, move flows over gradually and switch off the old one later.
If the number is already on the official API with another provider, none of this applies: Meta doesn’t support migrating a number from one partner to another in the new account model, generally available since September 23, 2026. You share your WhatsApp account with the new provider instead, as explained in how to switch WhatsApp API providers.
If your current number has been banned, it can only be registered after it’s reinstated through the appeal process.
When you disconnect the unofficial session, shut down the library before registering the number with Meta. Two connections trying to use the same number cause errors that are hard to diagnose.
4. Create and approve your templates
For each business-initiated message, create a template in the right category: utility for notices tied to a transaction or account, authentication for codes, marketing for promotions. Meta reviews it and may recategorize it. With Vectalk, you create it through the templates endpoint with an instance token:
{
"name": "appointment_reminder",
"language": "en_US",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}, your appointment is scheduled for {{2}}. Reply 1 to confirm.",
"example": { "body_text": [["Maria", "Oct 22 at 2 pm"]] }
}
]
}
The template stays PENDING until it’s approved. Start here, because this is the step that depends on someone else.
If you plan to send marketing, keep a deadline in mind: Cloud API (/messages) stops sending marketing messages on October 13, 2027, and Messaging accounts created from April 13, 2027 already can’t send them there. The path is the Marketing Messages API.
5. Replace the sending layer
On an unofficial API, sending is a library function call. On the official one, it’s an HTTP POST. A typical Baileys send:
// Before (Baileys)
await sock.sendMessage('5584999999999@s.whatsapp.net', { text: 'Order confirmed' })
Becomes:
// After (official API via Vectalk)
const res = await fetch('https://apis.vectalk.com.br/api/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VECTALK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
messaging_product: 'whatsapp',
to: '5584999999999',
type: 'text',
text: { body: 'Order confirmed' },
}),
})
const data = await res.json()
const wamid = data.messages[0].id // store it to match against statuses
The number goes in E.164 format without the +. Store the wa_id the API returns in contacts[0].wa_id and use it as the contact key instead of rebuilding the number from whatever the user typed. Also plan for the BSUID: when a customer adopts a WhatsApp username, the phone number may no longer arrive in webhooks, so the contact model needs to accept user_id as well. See WhatsApp usernames and BSUID.
Before sending a free-form message, your code needs to know whether the 24-hour window is open. A simple way is to record when you last received a message from each contact:
function isWindowOpen(lastCustomerMessageAt) {
const TWENTY_FOUR_HOURS = 24 * 60 * 60 * 1000
return Date.now() - lastCustomerMessageAt.getTime() < TWENTY_FOUR_HOURS
}
const payload = isWindowOpen(contact.lastMessageAt)
? { type: 'text', text: { body: text } }
: { type: 'template', template: { name: 'resume_conversation', language: { code: 'en_US' } } }
6. Rewrite event handling (webhooks)
This is usually where most of the work is. Instead of events like messages.upsert, you receive a POST in Meta’s structure, with messages and statuses inside entry[].changes[].value:
{
"object": "whatsapp_business_account",
"entry": [{
"id": "WABA_ID",
"changes": [{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": { "display_phone_number": "558430000000", "phone_number_id": "PHONE_NUMBER_ID" },
"contacts": [{ "profile": { "name": "João" }, "wa_id": "5584988888888", "user_id": "BR.13491208655302741918" }],
"messages": [{
"from": "5584988888888",
"from_user_id": "BR.13491208655302741918",
"id": "wamid.HBgL...",
"timestamp": "1760000000",
"type": "text",
"text": { "body": "I'd like to reschedule" }
}]
}
}]
}]
}
Three changes deserve attention:
- Statuses arrive separately.
sent,delivered,readandfailedcome invalue.statuses[], referencing thewamidyou stored when sending. - Media comes by reference. A received image carries
image.id; to download the file, use the media endpoints. - Events can arrive more than once. Meta retries for up to seven days when your endpoint doesn’t return 200, which can duplicate notifications. Deduplicate by the message
id.
With Vectalk, you register webhooks through the API, and you can have several URLs per instance. Details are on the webhooks documentation page. For complete server examples, idempotency and queues, see WhatsApp API webhooks: a practical guide.
7. Run in parallel, then cut over
If you chose a new number, keep both running for a while. Move the reply flows first (they don’t depend on templates), then the notification flows. Track delivery and failure rates through the status webhooks. Once the numbers are stable, switch off the old session.
Migration checklist
| Item | Done? |
|---|---|
| Flow inventory: replies, business-initiated, no equivalent | ☐ |
| Business portfolio created and verification requested | ☐ |
| Payment method on the Messaging account, or billing through your provider | ☐ |
| Decision on the number: coexistence, delete from the app, or new number | ☐ |
| Display name approved | ☐ |
| Templates created by category and approved | ☐ |
| Contact list with recorded opt-in | ☐ |
Sending rewritten to POST /messages with wamid stored | ☐ |
| Marketing sends planned for the Marketing Messages API | ☐ |
| 24-hour window check before free-form messages | ☐ |
Contact model ready for wa_id and BSUID | ☐ |
| Webhook with a fast 200 response, a queue and deduplication | ☐ |
Handling of failed statuses and error codes | ☐ |
Media download by media_id | ☐ |
| Unofficial session shut down before registering the number | ☐ |
| Quality and messaging limit monitoring | ☐ |
Consent: the step many migrations forget
With unofficial APIs, many contact lists were built without any record of permission. The WhatsApp Business Messaging Policy only allows you to contact people who gave you their number and opted in to receive messages, and it requires you to honor opt-out requests. Before sending your first marketing template, separate the contacts with recorded consent. Messaging a cold list is the fastest way to sink the quality of a freshly migrated number. If your contacts are in Brazil, the LGPD (Brazil’s general data protection law) also applies; this is not legal advice.
Where Vectalk fits in the migration
Vectalk is a managed proxy for the WhatsApp Cloud API. You connect the number through Meta’s Embedded Signup, get a Vectalk token and use the same payloads as Meta’s documentation, changing only the base URL and the token. With an organization token, a single credential reaches every connected account; you just send the phone_number_id in the request body. That helps when you’re migrating several client numbers at once. Billing is a monthly fee plus a prepaid balance: Vectalk puts its own credit line on the number, each delivered message is deducted from your balance, and you don’t need to register a card with Meta. Vectalk also supports coexistence.
To get started, create your account at apps.vectalk.com.br/register and follow the quickstart, which asks for a verified Meta business account to connect through Embedded Signup. Account questions are answered in the Help Center (in Portuguese) or through contact.
Frequently asked questions
Can I migrate without losing my number?
Yes, in two scenarios. If the number is on the WhatsApp Business app, coexistence connects it to the API without removing it from the app. If it’s on regular WhatsApp, you delete the account in the app and register the number on Cloud API; the number is still yours, but the chat history on the phone doesn’t move to the API.
Does my chat history come with me?
Not in a traditional migration. With coexistence, Meta lets you sync up to six months of one-to-one chats if the business allows sharing, and the sync has to be done within 24 hours of onboarding.
Isn’t Evolution API already official?
Evolution API offers more than one type of integration. The Baileys-based mode uses WhatsApp Web and isn’t official. When it’s configured with Meta’s Cloud API, it uses the official API. What determines the risk is the channel, not the project’s name.
Will I pay for messages that are free today?
Yes. On the official API, Meta charges per delivered message, by category and by the recipient’s country. Each number gets 1,000 free delivered service messages per month; since October 1, 2026, utility templates sent inside the customer service window are charged; and the free entry point window opened by Click-to-WhatsApp ads can stay open for up to 7 days (utility templates sent inside it are still free). For recipients in Brazil, rates since October 1, 2026 are R$ 0.3217 for marketing and R$ 0.0350 for utility, authentication and service (R$ is the Brazilian real); details in WhatsApp API pricing in Brazil. For other markets, see WhatsApp API pricing by country.
Can I keep using groups?
With limits. Meta’s Groups API requires an Official Business Account, allows up to 8 participants per group and isn’t available for numbers in coexistence. Large groups and communities remain outside the API’s scope.
Sources checked on October 29, 2026: WhatsApp Terms of Service, Business phone numbers, Messaging limits, Webhooks overview, Groups API, Account model evolution, Marketing Messages API, Business-scoped user IDs, Pricing, WhatsApp Business Messaging Policy.
Put your business on the official WhatsApp
Create your account, connect your number to the official API (you can keep the app with coexistence) and start serving customers and sending messages.
