Build on the WhatsApp Cloud API Yourself, or Use a Platform? An Honest Engineering Estimate
Sending your first WhatsApp Cloud API message takes an afternoon. Running WhatsApp as a production channel takes a lot more: webhooks you can trust, a 24-hour window modelled correctly, templates and sending limits, phone numbers, media, onboarding, and an inbox where people actually reply. Here's what each piece took us at WAPGROWAI, with real line counts from our codebase, and a fair answer to when building it yourself is the right call. This is the last post in a series that went through each of these pieces in detail. This one puts them side by side. The afternoon version Meta's Cloud API is genuinely easy to start with. Create an app, add the WhatsApp product, take the test number and a token, and send the hello_world template: curl -X POST "https://graph.facebook.com/v26.0/$PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "15551234567", "type": "template", "template": { "name": "hello_world", "language": { "code": "en_US" } } }' You get back a message ID, the phone buzzes, and it feels like most of the work is done. If all you need is to send a few kinds of notification from your own backend, it nearly is. Everything below is what turns that into a channel a business runs on. What production adds Line counts are non-blank TypeScript lines in our backend, measured for this post. They're a rough measure of size, not of effort, and some files are shared between rows. WAPGROWAI is a multi-tenant SaaS, so a few of these pieces are bigger than one business would need. Piece What it involves Backend lines Webhook intake Signature check on the raw body, a fast 200, de-duplication on the message ID, statuses that arrive out of order ~1,600 Conversations and the 24-hour window Window state anchored on the customer's last message (or call), expiry, reopening, what the inbox may send ~2,300 Sending and media Text, media and interactive sends; media upload and download; retries for throttling errors; delivery status ranking ~4,000 Templates Create, submit, sync status from Meta, variables, header media handles, button payloads ~2,400 Campaigns Audience resolution, a queue per campaign, throughput control, pause and resume, failure reasons ~5,500 Drips and sequences Multi-step journeys over days, scheduling, reconciliation ~3,200 Contacts and import Phone parsing, CSV/XLSX import, de-duplication, opt-outs, attributes ~2,800 Onboarding and coexistence Embedded Signup, phone registration, Business app coexistence, history and contact sync ~3,000 Chatbots and WhatsApp Flows A flow engine with branching, timers and delays; Flow JSON generation and publishing ~6,400 AI agent and AI helpers Scope checks, grounding, history, failover, formatting for WhatsApp ~2,500 Realtime and notifications Socket events to the inbox, web and mobile push ~1,800 That's roughly 35,000 lines of WhatsApp-specific backend before counting the frontend. The team inbox alone is about 16,700 lines of React, and the campaign screens and chatbot builder are another 12,500 and 14,100. Under all of it sit MySQL, RabbitMQ for campaign and sequence queues, socket.io, and 13 scheduled jobs, from expiring windows to running delayed chatbot steps. None of it is exotic. All of it has to be right, and most of the bugs only show up with real customers. The parts that cost more than they look Each of these has its own post in the series. The short version: Webhooks are your source of truth, and Meta retries them. Verify the X-Hub-Signature-256 header against the raw body, answer quickly, and expect the same event more than once and statuses in any order. A "read" can arrive before "delivered". (Webhooks post) The 24-hour window is state, not a timer. It's opened by the customer's message or call, never by yours, and it decides whether your inbox can send a normal reply or only a template. Model it from the last inbound message, and keep "conversation status" and "window open" as separate things. (24-hour window post) "Approved" is the start of a template's life, not the end. Templates have categories that set their price, variables that must be filled positionally, header media Meta must be able to fetch, and a messaging limit per business portfolio that caps how many people you can reach with templates in a rolling 24 hours. Sending to 10,000 people means a queue, a throughput limit and a plan for the failures that arrive by webhook minutes later. (Templates and campaigns post) Phone numbers fail silently. A number without its country code gets your business number's code prepended, and a spreadsheet can turn a column of numbers into 9.1982E+11. Neither throws an error. (Phone numbers post) Onboarding is its own product. If you only connect your own number, it's a one-time setup in Meta's dashboard. If customers connect theirs, you need Embedded Signup, token handling, phone registration, and now coexistence with the WhatsApp Business app, including history sync and message echoes. (Coexistence post) People need somewhere to reply. The moment a human answers customers, you're building an inbox: realtime updates, assignment, unread state, notifications on phones, and a reply box that knows when only a template is allowed. For us this was the single biggest piece of frontend work. Automation is where scope creeps. A keyword auto-reply becomes a chatbot, which becomes a flow builder with branches and timers, which gains an AI agent that needs guardrails. (AI agent post) The part that never ends: keeping up Building is a one-time cost. These are recurring: Graph API versions. Every request names a version (v26.0 above). Meta guarantees each version for at least two years, then retires it, so the version you start on has an expiry date, and upgrading means reading changelogs and retesting. WhatsApp Flows versions. Flow JSON has its own version number, and Meta freezes and retires old ones. Meta warns in the Flow Builder and by webhook first, but if nobody acts, publishing and sending flows breaks. For us it first looked like an intermittent bug. Pricing. Meta can change rates and rules at the start of each quarter. October 2026 brought charges for service messages beyond 1,000 a month per number, and for utility templates inside the window. If you show costs or enforce budgets, that's code to update. New platform features. 2026 alone brought usernames and business-scoped user IDs, which mean a webhook may no longer include the customer's phone number if they use a username and you haven't interacted recently. Systems keyed only on phone numbers have to change. Someone on your team owns this, every quarter, for as long as you run the channel. Build it yourself if… WhatsApp is a narrow feature of your own product. One-time passcodes, order and delivery notifications sent from your backend, with no humans replying. The afternoon version plus solid webhook and status handling is most of what you need. You need integration a platform can't give you. Messages tied deeply into your own data model, workflows or compliance controls, and you have engineers to maintain it. WhatsApp messaging is your product. If you're building a platform, the pieces above are the job. (That's our situation.) You need full control over data and infrastructure, and the maintenance cost is acceptable to you. Use a platform if… People reply to customers. A team inbox is the biggest single build, and often the one users judge most harshly. Non-developers run campaigns and chatbots. Template management, audiences, scheduling and flow builders are product work, not API work. Nobody can own the recurring work. API versions, Flow versions, pricing changes and new identifiers don't wait for your roadmap. You want to start this month. The afternoon version is an afternoon; the production version is not. Meta's per-message rates are the same either way; a platform adds its own fee on top. The real comparison is that fee against your engineers' time. If you do choose a platform Ask the questions this series kept running into: How does it model the 24-hour window, and does the inbox stop you sending a normal reply when it's closed? Does it show why a campaign message failed, including failures that arrive later by webhook? How does it parse phone numbers on import, and what does it do with 9.1982E+11? Does it support coexistence with the WhatsApp Business app, if you need it? Can you export your contacts, templates and chat history, and what moves with your number if you leave? (Switching providers post) Is there an API to send from your own systems, so you're not forced to choose all-build or all-buy? Summary The first message takes an afternoon; a production channel takes tens of thousands of lines, most of them unglamorous. The biggest pieces are the inbox, campaigns and automation, not the API calls. The cost that's easiest to forget is the recurring one: versions, pricing and new platform features. Build when WhatsApp is narrow, deeply integrated or your actual product. Buy when people reply, non-developers run it, or nobody can own the upkeep. I work on WAPGROWAI, a WhatsApp Business platform built on the Cloud API. We're obviously on one side of this question, so the line counts are here to let you check our reasoning rather than take it on trust. For the business view of what changed in WhatsApp pricing, see the companion post on Medium.
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to