Before any code, get the shape of the whole system in your head: who the
players are, whose number sends the message, and where the two big surprises hide.
Everything else in this course hangs off this map.
~7 minKnowledgeTies to: onboard orgs → store creds → message parents
The one sentence
Your app is a Tech Provider: each teaching org connects its own
WhatsApp Business Account to your app via a Meta popup, and your backend then calls Meta's
Cloud API to send approved template messages from that org's number to a parent.
1. The message you want to send is the hard part — start there
Your killer feature is: "send an automated billing reminder to a student's parent."
That message is business-initiated — the parent didn't text first. On WhatsApp,
business-initiated messages are not free text. They must be a
pre-approved template that Meta reviewed.
This is the first surprise, and it shapes your whole product.
Surprise #1 — you can't just send arbitrary text
You can only free-type a reply within 24 hours of a user messaging you (the
"customer service window"). Your reminders go out cold, outside any window, so they
must be templates: fixed layout, variables like {{1}} for the child's
name and amount, submitted to Meta and approved before first use.
[Meta: sending messages]
2. The cast of characters
Five parties. Keep them straight and the docs stop being confusing.
Meta / WhatsApp Cloud API
The hosted service you make HTTPS calls to. It actually delivers the message and hosts every org's account.
▲ your server calls it · ▼ it calls your webhook
You — the Tech Provider
Your SaaS backend + a Meta "app". You hold each org's credentials and send on their behalf. You never own their number.
▲ org connects via popup · ▼ you send for them
The teaching org — the Business Customer
Owns its WABA (WhatsApp Business Account) and its phone number. Pays Meta directly for messages. Clicks your "Connect" button once.
▼ messages flow to
The parent — the end user
Receives the WhatsApp on their personal number. Sees it coming from the school's verified name, not yours.
Why "Tech Provider" and not "just use my own number"
You could send everything from one number you own — but then every parent sees messages from
"MyNotesApp", not their child's school, and you'd hit rate/quality limits fast across all orgs.
The Tech Provider model gives each org its own WABA + number + its own Meta bill,
with your app orchestrating. This is exactly what the "Connect WhatsApp" button is built for.
[Tech Provider model]
3. The whole lifecycle, once
Read this top to bottom — it's the entire system. Later lessons zoom into each step.
You set up once (as a business): create a Meta Business app, get Business Verification, and request Advanced Access to the two WhatsApp permissions. This makes you a Tech Provider. — one time, for your company.
Org clicks "Connect WhatsApp" in your app. This launches Meta's Embedded Signup popup (the Facebook JS SDK). → Lesson 02.
Org signs in with Meta, picks/creates its WABA, adds & verifies its business phone number, accepts terms — all inside Meta's popup. Your app never sees their password.
The popup returns to your page:waba_id, phone_number_id, and a short-lived token code.
Your backend exchanges that code for a long-lived, org-scoped access token, then subscribes your app to that WABA's webhooks and registers the number. → Lesson 03.
You storewaba_id + phone_number_id + encrypted token, keyed by org (multi-tenant row). → Lesson 03.
To notify a parent: your server POSTs an approved template to the Cloud API, authing with that org's token, sending from that org's phone_number_id. → Lesson 04.
Meta POSTs your webhook with delivered/read status (and any parent reply). You update your UI/billing. → Lesson 05.
4. Where do credentials live?
The mental model for storage (full detail in Lesson 03): one row per connected org.
orgs_whatsapp
─────────────────────────────────────────────
org_id → your tenant
waba_id → from Embedded Signup
phone_number_id → the "from" address for the API
access_token → long-lived, ENCRYPTED at rest
(never sent to browser, never logged)
status → connected | token_expired | ...
Surprise #2 — the token is per-org and sensitive
You don't have one global key. Each org's token can send messages billed to that org and read
their messages. Treat it like a password: encrypt at rest, decrypt only to make the call.
We'll cover rotation and the "system user" behind it in Lesson 03.
5. Build vs. buy (decide before we go deep)
Two roads to the same outcome:
Path
What you do
Cost / tradeoff
Direct with Meta (Tech Provider)
You run Embedded Signup, token exchange, webhooks yourself.
Full control, no middleman margin. But Business Verification + App Review + you own the plumbing.
Via a BSP (360dialog, Twilio, Sinch…)
Use their SDK/onboarding; they wrap tokens & webhooks.
Faster to launch, less Meta bureaucracy. But per-message margin + vendor lock-in.
Everything after Lesson 02 changes depending on this choice — so we'll settle it together next.
Check yourself
Retrieval, not recognition. Answer before revealing — the effort is the point.
Q1. A parent has not messaged the school in days. To send a billing reminder, you must use:
Q2. After Embedded Signup completes, which three things come back to your app?
Q3. In the Tech Provider model, whose WhatsApp number does the parent see?
I'm your teacher — ask me anything. Good next questions: "Should I go direct or use a BSP for my scale?",
"What does Business Verification actually require?", or "Show me a real template for a billing reminder."