Deploy

Connect with your own Meta app

Messenger, Instagram and WhatsApp can run through your Meta app instead of Hania's. You create the app, generate a token, and paste it into Hania along with your app secret; Hania hands back a callback URL and a verify token that you enter in your app's webhook settings. It takes about fifteen minutes. Messenger and WhatsApp need no App Review at all, and Instagram needs it only once you want the public to be able to message you.

When to use this

There are two ways to connect a Messenger or WhatsApp channel, and both are live:

  • Quick connect with Facebook. You click Continue with Facebook, authorize in the popup, and Hania sets everything up from what Facebook hands back. Nothing to create, copy, or maintain. This is the right choice for most people, and it's covered in Messaging channels.
  • Your own Meta app. You own the app, the token and the webhook. Worth doing if your organisation wants messaging to run under its own Meta app for policy or auditing reasons, if you already have an app wired up for other Meta work, or if the Facebook window won't complete for your account.

Instagram uses this path. Quick connect isn't available for Instagram at this time, so its connect form goes straight to the own-app fields. The steps below are the ones to follow.

If Continue with Facebook fails for any reason - a popup blocker, a business account with unusual permissions, an asset Facebook won't return the ids for - this path always works. It doesn't depend on the popup at all.
One thing to know before you start on Instagram: until your app has been through App Review, Meta only delivers Instagram DMs from people who have a role on it. That's fine for a pilot and no use for a public inbox. Who can message you covers what that means and how to get past it. Messenger and WhatsApp have no such limit.

The rest of this page is the own-app path, start to finish. The console shows an abbreviated version of the same steps: open Channels → Connect a channel and pick a Meta platform. For Messenger and WhatsApp, choose Connect with your own Meta app instead; Instagram opens on these fields already. Then expand Setup guide.

1. Create the app

  1. WhatsApp only: create a business portfolio at business.facebook.com if you don't already have one. The app is attached to it.
  2. Go to developers.facebook.com/apps and create a new app. Meta asks what you're building: for WhatsApp, pick the WhatsApp use case and your portfolio. For Messenger or Instagram, choose the Business app type.
  3. Add the use cases you need. Messenger and Instagram both run on the Messenger use case, which carries the Pages permissions and the webhook settings for each.
There's a standalone Instagram use case in the dashboard, and it isn't the one you want. It belongs to a different integration, Instagram API with Instagram Login, whose webhooks are signed with a different secret. Adding it does no harm; configuring anything in it does. Everything for an Instagram channel here lives under the Messenger use case.

One app can carry Messenger, Instagram and WhatsApp side by side, so there's no need for a second app if you plan to connect several channels.

2. Switch the app Live

A new app starts in development mode, where it only works for people who have a role on it. Real customers messaging your Page would be ignored, so the app has to go Live before the channel is useful.

  1. Open Settings → Basic and fill in what Meta asks for before an app can go Live, starting with a privacy policy URL. Add your terms of service and data deletion URLs too if you have them.
  2. Flip the app-mode toggle at the top of the dashboard from Development to Live. No App Review is needed for this; see why below.
  3. While you're on Settings → Basic, click Show beside the App secret and copy it. This is the app-level secret, the one Meta signs deliveries with; other parts of the dashboard carry secrets of their own that won't work here. You'll paste it into Hania in step 5. Treat it like a password.
Copy the app secret carefully. A mistyped secret isn't caught when you connect, because it's only used to check the signature on incoming messages. It surfaces later as a Delivery error on the channel, once someone has already messaged you.

Meta's reference for the two modes: App modes.

3. Generate the token

The token has to be the right type as well as long-lived. Messenger and Instagram want a Page token, WhatsApp wants a System User token, and because a channel receives messages around the clock a short-lived one stops working within a day or so and the channel goes quiet. Paste any token into Meta's Access Token Debugger before you use it: the Type row tells you which kind you actually have, and Expires tells you how long it lasts.

Messenger and Instagram

Both use a long-lived Page access token for the Facebook Page involved. For Instagram that's the Page your professional account is linked to, so link them first if you haven't. The Graph API Explorer does the whole job, as long as you select your app in it first.

  1. Generate a User token granting pages_show_list, pages_messaging, pages_manage_metadata and pages_read_engagement. For Instagram, add instagram_basic and instagram_manage_messages.
  2. In the consent popup, tick the Page you're connecting, and the Instagram account with it. The popup remembers what you chose last time, so a Page you don't tick is quietly left out of the grant even though the authorization succeeds.
  3. Extend the token in the Access Token Debugger with Extend Access Token. That gives you a long-lived User token. It isn't the token the channel needs, but the Page token you take from it in the next step inherits its lifetime, which is why this comes first.
  4. Swap it for the Page token with GET /{page-id}?fields=access_token, using the Page you're connecting. The access_token in the response is what goes in the connect form.

Your Page ID is the same number you'll enter on the connect form. You can read it in Meta Business Suite under the Page's settings, or from About and Page transparency on the Page itself.

The last step is the one people skip, and it's worth slowing down for. Extend Access Token hands back something that looks finished, and it is long-lived, but it's still a User token. Paste that into the connect form and Meta refuses the subscription with (#210) A page access token is required to request this resource. If you see that, go back and take the token from GET /{page-id}?fields=access_token instead.
You may have seen GET /me/accounts suggested for this elsewhere, including in older versions of this page. Don't use it. Pages on Meta's New Pages Experience are absent from its response, so it returns an empty list for a growing number of accounts and tells you nothing about why. Asking for the Page directly works either way.

For Instagram you also need the account id, which GET /{page-id}?fields=instagram_business_account returns.

Read the Instagram account id from that call rather than guessing at it or reusing a number from elsewhere. A wrong id connects perfectly happily, because nothing checks it against the Page until a message needs routing, and then every message goes nowhere with no error on either side.

WhatsApp

Open the WhatsApp use case page in your app. The try it out panel at the top shows both ids you need: the Phone number ID and the WhatsApp Business Account ID. The Phone number ID is a long number beside the phone number, not the number itself.

WhatsApp uses a System User token rather than a Page token. Create one in Business settings → System users: add a system user with the Admin role, use Add Assets to assign your app (and your WhatsApp account, if it's offered there), then Generate new token granting whatsapp_business_messaging, whatsapp_business_management and business_management. Set the expiry to Never. Copy it when it appears, as it's shown once.

The try it out panel offers a temporary token of its own for sending a sample message. That one lasts about 24 hours and must never be used to connect the channel. Nothing about it looks wrong at the time: the channel works all day, then replies stop, with nothing reported anywhere. Only the System User token belongs in Hania.

4. Prepare the account

Messenger: turn off the Page's automations

In Meta Business Suite, open the Page's Inbox and switch off every automation on it: Instant Reply, Away Message and any FAQ or keyword autoresponders. Do this before you connect.

An automation answers the message inside Meta's own Page Inbox, and Meta then treats it as handled. The messages webhook never fires, so nothing reaches Hania at all. Everything else looks correct while this is happening: the channel connects, the callback URL verifies, the field shows as subscribed, and no error appears on either side. The only visible sign is that the sender gets Meta's canned reply a few seconds after writing in, and your agent says nothing.

This one is worth checking even if you're sure. A Page with Instant Reply left on behaves exactly like a Page whose webhook was never configured, and the two are indistinguishable from the console.

WhatsApp: the number people will message

Adding the WhatsApp use case provisions a test number for you automatically, which is enough to see the whole thing work. A real business number is a few more steps in the same place, and everything after this point is identical either way.

The test number only reaches phones you list. On the use case page, add each number you'll test from as a recipient and confirm it with the code Meta sends; you get five slots. The panel's temporary token can send a sample message from there as a quick smoke test, which tells you the app and number are wired up before Hania is involved at all.

Meta lends test numbers rather than giving them out, and can reclaim one without notice. They also only ever deliver to the recipients you listed. Use one to prove the setup, then move to a real number before anyone relies on the channel.

For a real number, open API Setup and add your business number, then verify it by SMS or voice code. That flow also registers the number for the Cloud API, including its six-digit two-step verification PIN, so there's nothing separate to do. Three things to know: the number can't be in active use on the consumer WhatsApp or WhatsApp Business app, Meta reviews the display name you choose, and the real number has its own Phone number ID that differs from the test number's. Copy that one.

Instagram: let the account receive messages

Two things have to be true before Instagram will pass a DM to anyone. The account has to be a professional account, Business or Creator, linked to the Facebook Page whose token you're using. And in the Instagram app itself, under Settings → Messages and story replies → Message controls → Connected tools, Allow access to messages has to be switched on. It isn't on for every account by default, and while it's off the channel connects normally and then never hears anything.

5. Connect in Hania

Everything else happens here, in one step. WhatsApp wants four things: the Phone number ID, the WhatsApp Business Account ID, the System User token and the app secret. Messenger wants the Page ID, the Page token and the app secret. Instagram wants those three plus the Instagram account id.

  1. Open Channels in the console and choose Connect a channel.
  2. Pick Messenger, Instagram or WhatsApp, then choose the agent that should answer messages here.
  3. Click Connect with your own Meta app instead.
  4. Fill in the platform ids, the token from step 3, and the App secret from step 2. A display name is optional; leave it blank and the channel is labelled with the account's own name.
  5. Click Connect. Hania validates the token and ids against Meta before saving, so a wrong id or a missing permission fails here with Meta's own error message rather than silently later.

On success Hania shows a callback URL and a verify token. Use them together as a pair; both go into your Meta app in the next step.

Nothing to lose here: both values are fixed for as long as the account is connected, and the channel's Webhook button in the Channels list shows them again whenever you need them. Copy them now for convenience, not because it's your only chance.
Moving a Page or account that's already connected through Hania's own app over to yours needs one extra thing done on Meta's side. Our app stays subscribed to the Page until it's removed, and removing the old channel in Hania doesn't touch that, so while both subscriptions exist every message is answered twice. Get in touch before you convert an existing channel and we'll clear it as you switch. If you'd rather do it yourself, drop the old app under the Page's own settings, or call DELETE /{page-id}/subscribed_apps with a page token minted by that app.

6. Point your app's webhook at Hania

Back in your app dashboard, find the webhook settings for the channel you're connecting. Enter the callback URL and verify token Hania gave you and click Verify and save. Verification is instant. If it fails, the verify token was mistyped or step 5 hasn't been done yet. Then subscribe to the fields:

ChannelWhere in the dashboardSubscribe to these fields
MessengerMessenger use case, webhook settings for Pagesmessages, messaging_postbacks, and calls if the agent takes voice calls
InstagramMessenger use case, Instagram settings sectionmessages
WhatsAppWhatsApp use case, Configuration page, labelled step 2: production setupmessages, and calls if the agent takes voice calls
Order matters. Connect in Hania first, then set the webhook. Meta verifies a callback URL the moment you save it, and until the channel exists on Hania's side there's nothing there to answer the handshake, so it fails with a 403. If you hit that, finish the connect in Hania and save the webhook again.
Subscribing the field is a separate click from saving the URL. This is the one people miss. Saving the callback URL and verify token gets you a verified webhook that delivers nothing at all, because no field is subscribed to it yet. Check that messages shows as subscribed before you move on.
Instagram has webhook settings in two places, and only one of them works. Use the Instagram settings section inside the Messenger use case, as in the table above. The standalone Instagram use case offers what looks like the same form, but it belongs to a different integration signed with a different secret, so a channel configured there fails signature verification permanently. Its Test button passes either way, which is what makes this one expensive to find.

Treat Test as a check that something is listening, and nothing more. It fires whether or not the field is subscribed, and it passes from the wrong section too. A real message is the only test worth believing, and Meta can take up to about fifteen minutes after you subscribe a field before it starts delivering.

Once the webhook is verified and the fields are subscribed, message the Page, account or number yourself. On WhatsApp, send a text from one of the recipients you listed if you're on a test number; on Instagram, send it from an account with a role on the app, for the reason in Who can message you. The conversation appears in the console under Conversations, tagged with that platform's channel.

Meta channels handle text for now. Images, audio and stickers are dropped rather than passed to the agent.

If the agent should take voice calls

Messenger and WhatsApp channels can answer inbound voice calls as well as messages. That needs three things, on top of subscribing the calls field above:

  1. The assigned agent has to be voice-enabled, or there's nothing to answer the call.
  2. WhatsApp only: calling has to be switched on for the number itself. With your own token, call POST /{phone_number_id}/settings with the body {"calling":{"status":"ENABLED","call_icon_visibility":"DEFAULT"}}.
  3. For Messenger calling, the calls field on the page object has to be subscribed, same as the messaging fields.
Worth knowing before you build on it: Meta documents the own-app carve-out clearly for messaging permissions, but is less explicit about the WhatsApp calling permission (whatsapp_business_manage_events). Messaging on your own app is well-trodden; calling on your own app is newer ground. If you're planning voice on an own-app WhatsApp channel, test it early rather than close to a launch.

WhatsApp on a real number

Answering people is the easy half. Your agent can reply freely for 24 hours after a customer's last message, and Meta doesn't charge for those replies, so an inbound support or enquiry channel costs nothing per message.

Starting a conversation is different. Messaging someone who hasn't written to you first, or replying after the 24 hours have lapsed, needs an approved message template and a payment method on the WhatsApp account. Meta also caps new businesses at 250 business-initiated conversations a day until the business is verified. None of that limits replies to inbound messages.

Instagram: who can message you

An own-app Instagram channel starts out able to hear from a small group of people, and it's worth understanding that before you plan around it. Meta's rule is that webhook notifications covering data owned by people without a role on your app require the app to have passed App Review; short of that, in Meta's words, "Webhooks will only be sent if the person using your app has a role on the app."

So an unreviewed app receives DMs from its own admins, developers and testers, and nothing else. Messages from the general public never arrive at all: Meta drops them before Hania sees anything, and the channel goes on looking perfectly healthy. The symptom, if you don't know to expect it, is an agent that answers you and ignores your customers.

Two ways forward, depending on what you need. For a pilot or an internal trial, add the people who'll be messaging as Testers on the app and have them accept the invitation; their DMs then come through. For a public inbox there's no way around App Review: your app needs Advanced Access on instagram_manage_messages, which also means completing business verification. That's a review of your app by Meta, so plan for it early rather than the week you intend to launch.

This applies to Instagram only. Messenger and WhatsApp deliver from anyone as soon as the channel is connected, whichever app they run through.

Connecting more than one account from the same app

Every connect returns its own callback URL, so three connected accounts give you three different URLs. You only ever configure one of them in your Meta app: any one delivers for all accounts connected from that app, because they share the app secret and Hania routes each incoming event to the right channel. So after the first channel is working, connect the others and leave your webhook settings exactly as they are.

The one thing to be careful about is mixing pairs. The callback URL and verify token you paste into Meta have to come from the same connect response, because the handshake validates against that account's token.

Removing one of those channels is safe: messages arriving on its URL are routed on to the app's other connected accounts, so nothing else stops working. The one thing that does need a live account is a fresh handshake, which happens when you re-save the webhook settings in your Meta dashboard. So if you're choosing which account's callback URL to configure, prefer one you don't expect to remove.

Why there's mostly no App Review

App Review is what Meta requires before an app can touch assets belonging to other businesses. Reaching your own Pages, Instagram accounts and WhatsApp numbers is Standard Access, which every app has from the moment it's created. Since your app only ever talks to your own assets here, there's nothing to submit and nothing to wait for; making the app Live in step 2 is enough.

Instagram messaging is where that stops being the whole story. Reaching your own account is still Standard Access, but a DM from a member of the public is a webhook notification carrying their data, and that crosses into Advanced Access. Hence a channel that works for your own team on day one and needs review before it works for customers. Who can message you has the detail.

Meta's references, if you want to confirm this for your own compliance notes:

Troubleshooting

  • Saving the webhook fails with a 403 - the channel doesn't exist in Hania yet, so nothing answered Meta's verification request. Connect in Hania first, then save the webhook.
  • "The verification token does not match" - the verify token was mistyped, or it belongs to a different connect than the callback URL beside it. The two have to come from the same connect response. Both values are behind the channel's Webhook button in the Channels list if you need to check them.
  • Re-saving webhook settings fails after removing a channel - a fresh handshake needs the configured callback URL to belong to a connected account. Point your Meta app at a still-connected account's URL, from its Webhook button, and save again. Message delivery itself keeps working either way.
  • A channel shows a Delivery error badge - the reason Meta gave is printed next to it. The usual cause on an own-app channel is a reset app secret, which makes inbound messages fail their signature check; reconnect with the new secret. See resetting your app secret.
  • Connect fails with "Could not connect account (subscription failed - check the token and ids)" - Hania asked Meta to subscribe the account's webhooks and Meta refused. Usually a token of the wrong type, a wrong Page ID or Phone Number ID, or a token missing a permission. Meta's own message follows the colon and names the problem.
  • That message ends in "(#210) A page access token is required to request this resource" - the token is a User token rather than a Page token. It's what Extend Access Token gives you, and it looks right because it is long-lived. Run GET /{page-id}?fields=access_token and connect again with the access_token it returns. To check a token before you use it, paste it into the Access Token Debugger: the Type row reads User or Page.
  • "token is required" - an app secret was entered without a token. This path needs both; the app secret identifies your app, the token grants access to the account.
  • Verification passed but no messages ever arrive - the field itself wasn't subscribed, which is the usual answer, and a green Test doesn't rule it out. On Instagram, check the webhook went into the Messenger use case's Instagram settings and not the standalone Instagram use case. On a WhatsApp test number, check you're messaging from a number on the recipient list. Give Meta up to fifteen minutes after subscribing before you call it broken, and remember a Development-mode app only answers people with a role on it.
  • The channel shows a signature failure straight after setup - the app secret doesn't match the app that's sending. Either it came from a different app, or, on Instagram, the webhook was configured in the standalone Instagram use case, which signs with a secret of its own. Move the configuration to the Messenger use case's Instagram settings, or reconnect with the right app secret.
  • It worked for a day, then went quiet - a temporary token was used. On WhatsApp that's the one from the try it out panel, which lasts about 24 hours; on Messenger or Instagram it's a Page token that was never made long-lived. Remove the channel and connect it again with a System User or long-lived token. The callback URL and verify token come back the same, so nothing changes in your Meta app.
  • A channel that was working goes quiet, with no error anywhere - nothing failed, so nothing is recorded: the channel still shows as Active and no Delivery error appears. The Channels list is what tells a quiet channel apart from a dead one, because it shows when the last inbound message arrived. Check the asset still exists on Meta's side: the number in WhatsApp Manager, or the Page or Instagram account in your app dashboard. Reclaimed test numbers are the usual cause, since Meta's +1 555 numbers are lent out rather than given and can be taken back without notice. Reconnecting the same number or account keeps the same callback URL and verify token, so your Meta app needs no change.
  • Instagram answers you but ignores everyone else - the app hasn't been through App Review, so Meta only delivers DMs from people with a role on it. Add the people you're testing with as Testers, or take the app through review for public traffic. See Who can message you.
  • Instagram messages don't arrive at all - work through the causes in order: the webhook is in the standalone Instagram use case instead of the Messenger one, Allow access to messages is off in the Instagram app, the professional account isn't linked to the Page whose token you used, the Instagram account id is wrong (it connects fine and routes nothing), or the messages field isn't subscribed.
  • Every message gets answered twice - a second app is still subscribed to the Page, almost always because the account used to be connected through Hania's own app and that subscription outlived the old channel. Get in touch, or drop the old app yourself under the Page's settings. See connecting.
  • A working channel goes silent after a change in the app dashboard - saving in some dashboard sections resets the Page's subscription fields. Reconnect the channel in Hania and the subscription is re-established correctly.
  • GET /me/accounts returns an empty list - your Page is almost certainly on Meta's New Pages Experience, which that call doesn't report. It's the default for new Pages and Meta has been migrating older ones, so most people see this now. The token isn't broken and regenerating it won't help. Ask for the Page directly instead: GET /{page-id}?fields=access_token. You can confirm which kind of Page you have with GET /{page-id}?fields=has_transitioned_to_new_page_experience. An older Page can also come back empty if the token is missing pages_read_engagement or the Page wasn't ticked in the consent popup, which carries your last selection forward.
  • The channel is connected but the assistant never replies - on Messenger, check the Page's automations first. Instant Reply, Away Message and FAQ autoresponders are answered by Meta's Page Inbox, and Meta then never fires the messages webhook, so nothing reaches Hania and nothing is recorded anywhere. Turn them all off in Meta Business Suite under the Page's Inbox. See turning off the Page's automations. If the sender is getting a canned reply within a few seconds, that's what this is. If they're getting nothing at all, it's more likely the field was never subscribed.
  • "Object with ID '...' does not exist" - usually a stray character on the end of a pasted Page ID rather than a permissions problem. A trailing quote is the common one, and it reads as though Meta can't see your Page. Retype the id or paste it somewhere plain first.

After it's connected

An own-app channel is marked Own app in the Channels list and behaves like any other channel from there on. Its Webhook button, and its Edit view, show the callback URL and verify token again whenever you need them. The list also carries the channel's delivery health: when the last inbound message arrived, or a Delivery error badge with Meta's reason beside it if messages are being rejected.

Renaming the channel or reassigning it to a different agent needs no reconnect and no change on Meta's side: the route, the credentials and the webhook wiring all stay as they are, and the new agent picks up the next incoming message. The platform, the ids, the token and the app secret are fixed, so changing any of those means removing the channel and connecting it again.

If you reset your app secret

Meta lets you reset an app secret, and doing so invalidates the copy Hania holds. Inbound messages then fail their signature check and are rejected. There's no way to update the secret in place, so remove the channel and connect it again with the new one. The callback URL and verify token are unchanged, so your Meta app needs no edit.

You'll see this in the console rather than having to guess at it: the channel picks up a Delivery error badge in the Channels list, with what Meta reported printed next to it. The badge clears itself once messages are getting through again.