Partial Outageshare-external
Developer FAQ
Account Kit

If you get an error like "We're sorry, something went wrong" and are having trouble determining the cause, you can optionally enable more detailed error messages which may show you more actionable information. More documentation on the debug flag to the SDK's init()' method can be found at

Account Kit Instant Verification bypasses the need for a verification code via SMS when Android consumers enter in a phone number that matches the one they have listed on Facebook.

This is only possible if the person is using the Facebook for Android app. If we are unable to confirm a match, the person will be taken through the regular flow and receive a verification code via SMS.

Please refer here for an updated list of countries and dialing codes that are supported:

No, we only support linking the JS SDK via This script will fetch the SDK loader, which will load the latest SDK either from or from your browser's cache.

For cases where you want to host the SDK via your own server, there is a grace lifetime of 24 hours. After this grace period, the SDK will start issuing warnings, and stop working after 7 days.

Set the enableSendToFacebook parameter (on iOS) or setFacebookNotificationsEnabled (on Android) to true.

Users logging in to your app will receive the confirmation message via Facebook notifications if the SMS could not be delivered, and if the phone number they're using is the primary phone number associated with their Facebook account.

You will need to add the INTERNET permission to call API methods. In addition, you can choose to add additional permissions to reduce friction during the login process:

  • For SMS access, add the RECEIVE_SMS and READ_PHONE_STATE permissions.
  • For email features, add the GET_ACCOUNTS permission.

You can find out more about integrating Account Kit into your Android app here.

Android SDK

When the user opens the mobile share dialog or mobile feed dialog, but closes it by canceling, your app will be notified about this through the onSuccess() callback method. You can think the onSuccess() callback as a mechanism to signal that the dialog was successfully closed in some way, but you cannot use it to establish whether something was actually posted. If the user has also granted your app the "publish_actions" permission scope, the onCancel() callback method will be invoked upon cancellation.

To see the full details of the FacebookCallback class, please refer to the reference documentation.

The native Like Button (LikeView) operates identically to the web-based Like Button. Most Facebook based URL's can't be used due to privacy. Exceptions include Facebook pages and Facebook's homepage.

You can do a preliminary check by using the Like Button previewer.

This is intentional. We have seen a lot of spam reports and abuse of this feature, and in order to improve the overall user experience, we decided to enforce this change.

There are better ways of sharing on android documented here.

App Review

We’ve moved all Messenger permissions to the Permissions and Features page.

We've consolidated this into one Permissions and Features page for Business apps, where you can see what access levels you have for each permission and feature.

Yes, developers may opt out of the Business app type and return to the previous App Review process for their app by selecting “Change App Type” on the App Dashboard. However, developers may not opt back into the Business app type and will need to create a new app to do so.

Additionally, apps previously in Development Mode that opt out to the legacy experience that have been approved for Advanced Access via App Review in the new model will lose access to data beyond what their business or anyone with a role on their app owns until they turn their app to Live Mode.

We have replaced Development and Live Mode with Standard and Advanced Access. Standard Access is always active and allows you to access data that a developer’s business or anyone with a role on their app owns. You may submit for App Review for permissions and features to access data owned by other businesses or people. Refer to our Access Levels document to learn more.

Business apps designed to help businesses and organizations manage Pages, Groups, Events, Ads, and ad-related assets.

The following are reasons why your app has lost permissions after initial approval:
  • The app is moved to a different unverified business. All previously approved permissions will be blocked.
    • If the app is then moved back to the verified business, the permissions will be unblocked.
  • The app is marked as Provide services to other businesses but is then moved to a different business which has not been verified.

Yes, ALL apps that leverage permissions that require review (Pages API, Groups API, Events API, Business Manager API, Instagram Graph API, Messenger Platform, extended Facebook Login permissions, Marketing API and Lead Ads API) must submit for app review in adherence with the communicated deadlines.

Active apps that leverage permissions with an August 1st deadline (Pages API, Groups API, Events API, Business Manager API, Instagram Graph API, Messenger Platform, extended Facebook Login permissions) and have not yet proactively submitted for review will be auto-enrolled in the review process. You can accelerate the App Review process by submitting your app for review prior to auto-enrollment. This will give you more control over when your app is reviewed and what information is used for the review.

For more details, visit this page. The process will give you the opportunity to provide details on which permissions you need, and how they will be used. Facebook will review the use case and determine if it is permissible under our policy. After permission review, depending on the API/permission we may have additional requirements such as business verification and contract signing.

The need for app review is based on the App ID level. Each individual app using those permissions or features must be submitted for review.

Yes, if your apps have made calls to the Graph API in the last 28 days as of July 31, 2018 and require access to the reviewable permissions with an August 1st deadline, your app will be auto-enrolled in the app review process. We will notify you when we have a process available to send us the additional information needed to complete the review process.

As we announced earlier this year, all apps accessing the Pages API, Groups API, Events API, Business Manager API, Instagram Graph API, Messenger Platform, and Facebook Login were expected to submit for app review by August 1.

To help protect the integrity of our platform, we have removed API access for apps that require these permissions, have not gone through app review, and have not been active within the last 28 days as of July 31, 2018. If you still need access to our APIs, we encourage you to submit for review through your app's App Dashboard.

All active apps that require these permissions will be auto-enrolled in app review in the coming weeks. Developers will be notified if we require additional information to complete the app review submission. If responses are not received in the allocated timeframe, reviewable API access will be disabled.

If your current submission requires additional information, you will have 30-days from receipt of the request to resolve and resubmit for review. During those 30-days you may be asked to provide more information by the App Review team. Please note that the 30-day window will not reset with each resubmission during this period.

To test a new feature or permission, after your app has been reviewed and published, use the Create Test App feature in the App Dashboard to create a clone of your production app. In the Dashboard of your production app, click the down arrow next to the app name in the upper left navigation pane and click Create Test App. The app clone, created with In Development status, allows all app roles access to all features and permissions.

If the clients are also the "owner" of the app, then they, themselves go through the process as direct developers. If the clients have a third party developer as the "owner" of the app, then it's the developer who will go through the review.

You will need to request the leads_retrieval and pages_manage_ads permissions.

You can provide a screencast of your integration, or if your app does not have an end user experience, you can provide a minimum of 2 screenshots which show the settings view of your page, your CRM or Business Manager as well as provide a Page ID for a page you'll be using through these products. You can read more about this option here.

The App Review process refers to apps that require certain API permissions. You can read about the permissions required for review here. Setting up the SDK itself does not require app review. However, the SDK does enable apps to make calls to Facebook APIs, and if those APIs require review, the app will need to submit for app review.

If you already have a Business Manager account, we recommend that you connect the app to the existing Business Manager.

If there are multiple Business Manager accounts that belong to the business, we recommend determining the rationale for multiple Business Manager accounts and aligning the app with the most appropriate Business Manager. If the business has a credit line set up through the Business Manager, we recommend that you connect the app with the one that has the credit line.

We give developers the opportunity to provide specific test users in case there’s additional configuration, whitelisting or test user profile information they want us to use. If they don’t provide a test user we will just use one of our own. The field should be marked as optional and not completing shouldn’t block them.

App review must be performed per app. We recommend that you review your app dashboard to get the specific list of permissions that require review.

Business Verification is required once per Business Manager. If you choose to associate all your apps with the same Business Manager, then you will only need to go through business verification once.

The app should be linked to the Business Manager for the business that ultimately owns the app and has access to the data being generated from the app. This business should be the one who goes through the business verification process.

You can always find the status of business verification and contracts and steps to take in the business verification panel found in the app review tab of the app dashboard. We will send you notifications throughout the process to let you know what action is needed.

You need to initiate app review before August 1, 2018 for these APIs: Pages API, Groups API, Events API, Instagram Platform API, Messenger Platform, Business Manager API, and Facebook Login.

You need to initiate App Review before February 1, 2019 for these APIs and features: the Marketing API and the Lead Ads Retrieval feature.

At the moment we are dealing with increased volume. The entire process may take up to several weeks.

  • Permission review may take up to several weeks. Our latest update on timelines can be found here.
  • Business verification should take a few days, however it will depend on the quality of documentation.
  • Contract signing can be completed as soon as you have your designated officer sign the contract.

As part of the review process, you may be asked for business information such as the legal name of the business, address and phone number. In addition, you may be requested to provide business documentation such as utility bills, licenses, certificates of formation, or articles of incorporation.

As of August 1, 2018, you only need to verify the Business Manager which the app is connected to.

As new APIs become available, these will need to be requested through App Review. Business Verification however, is only required once per Business Manager entity, so Business Verification will not be required again if new permissions or APIs are required for an app.

Yes, test apps will inherit reviewable permissions from parent apps.

All existing apps that are calling Facebook Login extended permissions and the 6 APIs (Pages, Messenger, Business Manager, Instagram, Groups and Events) would need to submit to the new App Review flow, which includes business verification and signing of contracts. App Review doesn't need to be completed by this date, just submitted. If a submission is not made before August 1, 2018, then access to those APIs will be lost on August 2, 2018.

All existing apps that are calling the Marketing API and Lead Ads Retrieval API need to submit to the new App Review flow which includes business verification and signing of contracts before February 1, 2019.

For more details, visit this page. The process will give you the opportunity to provide details on which permissions you need, and how they will be used. Facebook will review the use case and determine if it is permissible under our policy. After permission review, depending on the API/permission we may have additional requirements such as business verification and contract signing.

A business only needs to be verified once. Contracts only need to be signed once at a business level. Subsequent app submissions will require app review, but not verification.

The need for app review is based on the App ID level. Each individual app using those permissions or features must be submitted for review.

On May 1, 2018 we announced a new App Review processthat is required for FB Login (extended permissions) and the 6 APIs (Pages, Messenger, Business Manager, Instagram, Groups and Events). App Review submission for these APIs/permissions is required before August 1, 2018 in order to maintain access to those APIs. On August 1st, we will begin enforcing this deadline for inactive apps.

For active apps that require these permissions, we will auto-enroll apps into the app review process in the coming weeks. You can read more about this announcement here.

On July 2, 2018, we announced additional APIs that require app review: Marketing API and Lead Ads Retrieval. App Review submission for these APIs/permissions is required before February 1, 2019 in order to maintain access. You can read more about the due dates here.

During the review process, our review team follows your instructions to reproduce how permissions are used within your app. If we can't reproduce this experience - for example, because we can't follow your instructions, or we can't log into your app - then we also can't approve the submission.

To avoid this, please:

  • Provide a working version of the app that uses the permission
  • Make sure your instructions in the Add Notes section are clear
  • Make sure that the requested login permissions personalize the user experience and comply with our principles

In particular, for the publish_actions permission, please confirm that your app's publishing functionality is configured correctly. We need to be able to publish your app's content back to Facebook during the review process.

The App Review process involves loading your app on each supported platform, logging in with Facebook, and using every Facebook integration that you're requesting in review. This often results in what we call 'general issues.' These are errors or bugs relating to loading your app, logging into your app or the general functionality of your app. This means we weren't able to test the permissions you request in your submission.

Since these are issues that prevent us from reviewing your Facebook functionality, we can't comment in detail about how your app uses the Facebook functionality you've submitted for review. Because of this, we reject with 'General Issues' and provide feedback about this on each platform.

If you receive a 'General Issues' rejection, please carefully read all of the feedback. Each platform will receive individual feedback that should explain what issues were experienced in review.

Your review response will include a clear explanation for why your app wasn't approved, as well as the next steps you should take. We want to get you through the process as quickly as possible, so be sure to read this feedback carefully. Once you make the necessary changes, you can submit for review again.

If your app uses a permission in a way that isn't approvable, your feedback will explain this and you shouldn't resubmit for review.

To be approved for App Center, your App will need to meet our eligibility requirements. Apps eligible for the Facebook App Center must use Facebook Login or have a Facebook Canvas app.

App eligible to be listed in App Center are:

Your text assets and promotional images must also meet our guidelines.

If you're using the Share Dialog or any other social plugin to publish content back to Facebook, you don't need to submit for review. If you're still not sure, you can find more info in our general review documentation.

It's against Platform Policy 4.5 to incentivize people to use social plugins or to like a Page. This includes offering rewards or gating apps or app content based on whether or not a person has liked a Page. User_likes will not be approved for this purpose.

To ensure quality connections and help businesses reach the people who matter to them, we want people to like Pages because they want to connect and hear from the business, not because of artificial incentives. We believe this policy will benefit people and advertisers alike.

Our review team may need additional login credentials for your app in order to complete your review.

If your app requires a secondary login before or after Facebook Login, please be sure to provide a username and password for this. This may include login credentials for a testing or demo server, secondary login for your app or an e-mail registration flow.

Apps hosted on staging or development servers may require an additional login to access your server. Please provide all necessary login credentials for this also.

If you're still not sure what credentials are missing, you can provide a video with your next submission that shows the Facebook Login option and all relevant Facebook integrations you're submitting for.

To approve your app submission, our review team will need to log into your app and check all Facebook integrations.

If your reviewer has been unable to load or use your app, please make sure that:

  • The App URL is publicly accessible and not configured as a localhost
  • You've provided the username and password needed to access your development or staging site
  • Your site's security certificates are up to date and not causing errors for new users
  • You're able to login and use your app as a newly created test user
  • The items you submitted for review are built out and working in your app

If you're rejected again for the same reason, update your Review Instructions or Add Notes section to ask your reviewer for some clarity and additional info.

A screencast is a great way to guide us through your app and show us how you're using the requested permissions. Here's some best practices and third party resources for creating a screencast.

Your video should show how your app uses each permission it requests. If you're requesting publish_actions, it should also show how content from your app is created and shared to Facebook.

Your Facebook App ID created for your Instant Game cannot be used for any other platform. You can find more info in our documentation.

Our review team will use the instructions you provide to test your app's Facebook integrations.

If you feel our reviewer has incorrectly rejected your app, you should resubmit for review with updated review instructions that provide more info for the reviewer.

The review process is the best way to communicate with your reviewer by updating your notes to address the feedback you've received.

Our review team uses multiple test users when reviewing submissions, and we don't always use the test user you provide. If your submission does need to be reviewed using a specific test user please let us know in your review instructions.

If you provide a test user, make sure you've correctly created the test user and attached the user with your submission.

No. Once you've been approved for a permission, you can use it across any version of your app on any platform.

If you expand and develop your app on a new platform, this will not need to be submitted for review. You only need to resubmit for review if you want to request a new permission - for example, when you add a new feature to your app. Changing and submitting your App Details or Open Graph actions will not affect the permissions you've been approved for.

If your app is a game and has a presence on Facebook Canvas

You can invite new players to your game by using either the:

  • Requests dialog. When using the requests dialog you can set 'filters=app_non_users' to filter the dialog to only show people who don't use your app. If your app has a Canvas presence, you may also use the Requests Dialog on iOS and Android.
  • Invitable Friends API. If your app is a game, and want to build your own multi-friend selector, you may use the Invitable Friends API, which returns a ranked list of the person's friends who do not use the app. Once a person has selected a number of friends to invite, you may pass the tokens returned by the Invitable Friends API to the to field of the Requests Dialog which will then let the person send an invite to those friends.

If your app does not have a presence on Facebook Canvas

You can use the Message Dialog on iOS and Android, or the Send Dialog on Web. These products let a person send a message directly to their friends containing a link to your app.

This type of message is a great channel for communicating with a smaller number of people in a direct way. The Message Dialog and the Send Dialog both include a typeahead which lets the person easily select a number of friends to receive the invite.

Currently, apps do not require App Review if they are only used by Users who have a role on the app, and who are only publishing to their own timelines or Pages. Starting on August 1, 2018, however, apps can no longer publish to User timelines, and any apps that allow Users to publish to Groups or Pages must go through App Review.

Our review team will actually test how your app uses each permission on every platform you have listed in the settings section of your app. Your reviewer ensures that your Facebook Login integration works correctly and that each permission requested adheres to our principles and utility guidelines while providing an enhanced user experience.

Please see our principles and utility guidelines for more info.

Before approving your request for user_likes, your reviewer will need to confirm that your app provides a unique experience to users based on the like info it receives from them. To do this, our review team will test your app with a variety of test users, each with a different set of likes and interests.

When submitting a request for user_likes, you should write detailed instructions that include:

  • A clear explanation of why you're requesting user_likes and how it improves a person's experience in your app.
  • A list of sample Pages for our reviewer to like to verify your use of user_likes. Please give direct links to the Pages that our reviewer should like before they test your app.

If you're using user_likes as part of an algorithm, it's important that the reviewer can see the result of this algorithm and how it influences content shown to people.

In certain cases, you may need the reviewer to reproduce a certain behavior or experience available only to a specific test user. If this is the case, you can add this user to your submission on the App Review page. In the Items in Review section, you'll see a Test User (optional) section that allows you to type the name of the user you wish to be used in your review.

The only test users available here are those listed as Test Users in the Roles section of your app. Please do not share Facebook login credentials for users in your review instructions.

Learn more about how to create a test user.

No, you don't need to submit for review to run mobile app install ads. You just need an app that is live in the iTunes App Store or Google Play Store. You can follow our guide to creating mobile app installs ads.

You'll need to explain exactly how to test each permission or feature in your app so that we can make sure it works and follows our policies. We can't approve your app if we can't fully test how it integrates with Facebook. Giving detailed instructions makes it less likely that you'll have to resubmit for review.

For each permission you request, list reproduction instructions in a step-by-step format. All instructions must be in English.

Your instructions should not:

  • Reference instructions from other submissions or documentation
  • Summarize what your app does instead of giving instructions
  • Provide technical details of how your APIs work

Here's a good example of step-by-step instructions:

  1. Press the Settings button on the left hand menu.
  2. Select Login with Facebook
  3. Complete the third step
  4. Complete the fourth step

If you're still not sure about what to include, please see more examples in our examples section for App Review.

Due to changes to the review process and the high volume of submissions expected, it may take several weeks for submitted apps to complete review.

Please provide as much info as possible to help the reviewer, including clear screenshots, detailed step-by-step instructions and a screencast recording of your app and its Facebook integration.

Apps that use mediated sharing products like social plugins, share dialog and share sheets, or a subset of Facebook Login do not have to be reviewed by Facebook. To learn more about what requires review, please see our App Review documentation.

We review your app to ensure a high-quality Facebook experience across apps. In general, people must be aware that they are logging in and posting to Facebook. People should be able to control the info they share with your app or back to Facebook.

Note: People who are listed in your app's Roles tab will have access to extended permissions without going through review (for example, user_posts). However, when the app goes public it must go through App Review to access information even for people with roles on the app.

All app capabilities should be available when your app is in Development Mode but you will only be able to access your data, your test user's data, or your pages data. If you wish to take your app public, even if you are the only user, it must go through app review .

Business Manager

If requesting a list of pages for a Business via /BUSINESS_ID/pages, not all fields of the page can be requested, and the API may respond with an error: (#100) Unknown fields: <FIELD_NAME>.

This is because this endpoint doesn't return a Page object like other similar endpoints, and it also includes pending requests which haven't been approved, for example. As such, it's not possible to use field expansion to return fields from the Page.

You may use <BUSINESS_ID>/owned_pages or <BUSINESS_ID>/client_pages - both of those endpoints should return Page objects and support field expansion.

To send a request to a verified page, a Facebook Partner Manager must configure the business to allow for making such requests against the organization associated with the page. Businesses without a Facebook Partner Manager will not be able to issue such requests.

Data Use Checkup

With Data Use Checkup, an app admin needs to:
1. Take a look at an app’s approved permissions and features
2. Certify that the app complies with the allowed usage
3. Certify compliance with the Facebook Platform Terms and Developer Policies together with all other applicable terms and policies

Data Use Checkup and App Review are two distinct, yet related, platform integrity measures. App Review is a forward-looking process that gates access to certain Facebook Platform permissions, requiring developers to submit an application to justify platform access, which is manually reviewed by our Developer Operations team. After platform access is granted, Data Use Checkup is an annual process that requires developers to certify that their continued use of Facebook data is in compliance with our Platform Terms and Developer Policies.

You must certify on behalf of every app your business manages.

Developers who manage many apps will have the option to complete Data Use Checkup for multiple apps at once. You can access this flow by going to your “My Apps” page in the App Dashboard. From there, you will see all apps for which you are an admin, be able to filter down to a subset (e.g., only those that require Data Use Checkup), and complete Data Use Checkup.

You will need to complete the checkup for each app you manage (each app may have multiple permissions). You can certify for apps individually and prioritize as you wish, as long as you complete the process before the deadline set for each app.

You will be prompted to certify for all permissions you have access to. However, if you realize you no longer need access to certain permissions, you can remove these permissions and you will no longer need to certify for them.

Live Mode and Dev Mode are two app modes that have implications on app functionality and Data Use Checkup. Dev Mode is typically used to test, explore API products/permissions and complete App Review, and apps in Dev Mode cannot call user-level data. Live Mode is used for production scenarios and does not gate access for data/permissions that apps are approved for in App Review. Only Live Mode apps require Data Use Checkup.

If for some reason you are unable to access an app and need to regain admin status, click here.

Generally speaking, we attempted to group apps’ deadlines together if they have the same app admin, so you should have the same deadline for your apps. However, there may be exceptions that result in some app admins needing to complete the process at varying deadlines – for example, if you created an app after others have gone through Data Use Checkup, it will have a different annual deadline.

You can see all apps that require Data Use Checkup by going to the "My Apps" page in the App Dashboard. There, you can see all apps you manage and filter down to those that require Data Use Checkup.

The process should be completed by the app administrator. To review who is an administrator on your app, log into the App Dashboard and click “Roles” on the left side of the page. App administrators should be in a position of authority to act on behalf of your organization.

Any app admin can certify for the app. If you have multiple admins for an app, only one of them needs to certify.

You will have 60 days from the time the process begins (when you receive the first Dev Alert) until the deadline.

If you do not respond and complete the certification process by the deadline, your app will be deactivated.

You may still be able to return to your App Dashboard, complete Data Use Checkup and restore access. However, we conduct periodic inactive “permission reaping” of inactive apps, meaning after a certain period of inactivity your permissions may permanently be removed and you will need to submit for App Review to gain access back. We recommend completing Data Use Checkup prior to your deadline to avoid this scenario.

Data Use Checkup will surface all permissions your app has access to, regardless of whether you’re actively using them. We recommend taking this opportunity to audit your integration, better understand your app’s capabilities, and remove access to any permissions you don’t need.

In some cases, we will be surfacing API usage information right in the Data Use Checkup flow. Otherwise, you can see usage levels for each permission in the “Permissions and Features” section of the App Dashboard. Once you log in, click “App Review” on the left side of the page, then select “Permissions and Features” from the dropdown. You’ll see a column for “API calls,” which will have a green check if our logging shows that you’re actively using the permission. Please remember this is just an estimate — you should consult with your development team to see if the permission is required for your integration.

We are requiring developers to certify for these auto-granted “basic” permissions because they are widely used and provide access to user data. However, if you haven’t used this data, you should still feel comfortable completing this process, since certifying indicates that any use of the permission is in compliance, which includes no use.

You should first remove the permission using the App Dashboard (click “My Permissions and Features” from the left-side dropdown under “App Review”). Then you can certify the remaining permissions and features you are still using.

However, there are some auto-granted permissions that cannot be removed and you may be asked to certify for. If you haven’t used this data, you should still feel comfortable completing this process, since certifying indicates that any use of the permission is in compliance, which includes no use.

No. After you remove the permission in the App Dashboard, you can refresh the Data Use Checkup page and the permission you removed should disappear.

You will have to complete Data Use Checkup for all permissions your app has access to.

We will be conducting a phased roll-out of Data Use Checkup, so while you should expect to complete the process in the coming months, your specific deadline will vary. Please make sure your contact information is up-to-date in the App Dashboard and refer to your Dev Alerts for specifics on your deadline.

Developer Accounts and Services

In order to comply with certain legal obligations, Meta’s developer services may not be available in all locations, including countries and regions currently subject to U.S. sanctions prohibitions.

Registration reviews may take longer and you may be unable to access our service during that time. Please try again in a few days. For more information, please refer to Meta’s Terms of Service.

We are currently reviewing your registration details. This takes 24 to 48 hours. Once completed and approved, you may be able to login and complete your registration.

Developer Tools

You can't delete screenshot or banner images that have already been approved for App Center. To replace these images with new images click "Edit" on the screenshot or banner and choose a replacement image.

Check if you can see the error message without making a request for user photos and verified that initially error message was visible. Then go and make the following API request me/photos and go back to check if the error message is still visible and no it is not visible any longer. Make sure when you do the test me/photos call, you use the intended app and get the right access token which requires user_photos permission and you should be good to go!

The aim of this check is to ensure developers have tested the feature in their app throughly before requesting us for the same permission. Testing it in test app does not guarantee a stable behavior of the same in the main app. We need you to make the test request from your main app to make sure you see it working as expected before you enable it to the external facing audience. Please follow the steps provided about to manually make a request and check you should no longer have this warning on your dashboard.

The 'Stream Post URL Security' migration will stop your Facebook App from publishing any URLs that don't point back to a domain it owns. Please do not use this option if your App will publish links to other sites.

This dashboard feature was removed. You will need to use the '/{app-id}/accounts/test-users/' endpoint to associate a test user with an application. You can read more about it here.

This is intended behavior and is documented here - - Test users cannot become a fan of a public Facebook Page or create content on them, such as writing on a Page's wall. A Test user can however view and interact with any app tab on the Page associated with the app that created them.

This is intentional. We do not allow for multiple arbitrary domains for security purposes.

Facebook Login

This is the intended behavior. The Login dialog uses a fixed width and will not scale to fit larger screens.

This is intended behavior. It's the developer's responsibility to set the appropriate 'redirect_uri' based on the user's device and hence, if the user is on a mobile device 'redirect_uri' should be the mobile site URL.

This is intended behavior, because it prevents a potential security vulnerability. Some browsers will append the hash fragment from a URL to the end of a new URL to which they have been redirected (if that new URL does not itself have a hash fragment).

For example if returns a redirect to, then a browser going to will go to, and the hash fragment content from would be accessible to a script on

Since it is possible to have one auth flow redirect to another, it would be possible to have sensitive auth data from one app accessible to another. This is mitigated by appending a new hash fragment to the redirect URL to prevent this browser behavior. If the aesthetics, or client-side behavior, of the resulting URL are of concern, it would be possible to use window.location.hash (or even a server-side redirect of your own) to remove the offending characters.

Graph API

Test apps created from Business apps will have Standard Access for all permissions and features.

No. For a given permission, Business apps have either None, Standard, or Advanced Access.

Yes. For Business apps, the Advanced Access level includes access to all data within the Standard Access level.

To share an URL, the associated image needs to be at least 200x200 px. If that is not the case you will get a error similar to this one "Provided og:image is not big enough. Please use an image that's at least 200x200 px."

For picking up an image for an URL we first look at your 'og:image' tag, see if it exists and if it is above the 200x200 px requirement. If the 'og:image' tag does not exist, we choose the first image we encounter on the webpage.

If you get the error but you think your site image is bigger than 200x200 px., you should verify that you have correctly set the 'og:image' tag, as the most probable cause is that we are retrieving an incorrect image from your site.

We have changed the behavior of the sharer plugin to be consistent with other plugins and features on our platform.

The sharer will no longer accept custom parameters and facebook will pull the information that is being displayed in the preview the same way that it would appear on facebook as a post, from the URL OG meta tags.

No, it is not possible to override 'caption' on a shared URL, just 'title' and 'description'.

An app can't upload to albums created by other apps.

In some cases, there are albums which are not associated with any apps (Wall photos album). We suggested to check the can_upload field. If the can_upload field returns false, that means that users can't directly place photos in this album via the Albums view on their profile.

The call to action will be shown under the 'replay' icon once the video is finished.

GIF's must be less than 8MB in size in order to be playable on Facebook.

Creating comments for unpublished posts through the API is not currently supported.

Video post created inline are not shown in the promotable_posts endpoint because they are already promoted. A Video post created inline is a post that was created as part of an ad creation therefore, cannot be boosted separately.

So is expected that inline created post will not show up in /promotable_posts endpoint.

This can happen if you are using a Page Access Token where the user associated with the token is listed as an analyst in Page Roles under Settings of your page.

When a request is made for data using the Graph API, various privacy rules apply which cause certain data not to be returned even though you can view them in the website. This can depend on various factors such as privacy settings of the user, app level permissions, etc. This means the data returned by the API does not necessarily include all the data seen on the website.

If the post was created using 'object_story_spec' of the Ads API, these posts are categorized as inline. In order to view such posts, you will need to use /{page-id}/promotable_posts edge and use the 'is_inline' modifier in v2.3 and below and 'include_inline' in v2.4 and above. You can read more here.

The shares field will return when the post is shared more than 10 times. If a post has been shared less than 10 times, we may either omit this field or attempt to return a number.

You can find out more about this endpoint here:

This was an old value used on our old infrastructure and we kept for backward compatibility when we moved to a newer one.

This will occur with historical posts and not with recent posts.

This is working as intended. There is no connection between the post and the photos in a post. We only return the first image that is uploaded within the post.

The 'application' field will not be returned if the post is attributed to the Facebook website or mobile application. This is aligned with the site, which does not show attribution for those types of posts.

The "privacy" field of a Post will include information about the visibility of that post on Facebook, but when a Page Post is targeted or is gated to be visible only to a specific audience, the information in the "privacy" field does not show all of the selected targeting options.

To see the full details of how the Post is targeted or gated, check the 'targeting' field (for gating), and the 'feed_targeting' field (for News Feed targeting). Please see the Post documentation for further information on which fields are available.

The comment_count value returned for a post may include comments that have been hidden or deleted. The number of comments visible on a post will never be more than comment_count.

It is not possible to override the 'caption' of a shared URL. You can only override the 'title' and the 'description' of that URL.

For more information and the fields that you can publish via the Graph API please see the /feed documentation here:

This is by design. It is aligned with how Facebook app (mobile or web) generated content is shown (without attribution to Facebook itself).

We've made updates on our side to how stream and post data are retrieved and presented via the API.

If you're encountering issues with fetching posts from the API and believe it's not working as documented, please verify the following -

  • the access token you're using has the appropriate permissions to access the posts you're interested in.
  • Please ensure any API calls you make to retrieve posts are using the 'id' returned to you in a previous call and that you're not manually crafting IDs based on page, user or other IDs.

Photos uploaded via Instragram are published as Open Graph actions, and require the appropriate Open Graph permissions to be read from the Graph API.

In the case of Instagram photos, the permission required is "user_actions:instapp" as "instapp" is the application namespace for Instagram.

Open Graph actions do not appear on the /feed connection but where a photo is uploaded as as Open Graph action it can be accessed with the appropriate permissions via the user's albums connection or /photos connection as applicable.

More information on Open Graph permissions can be found here.

That is intentional. Our system returns the above error message for objects that have been deleted or are invisible for privacy/permission checks.

This behavior is expected and this form of pagination is not supported for comments.

The field total_count for the summary param for the endpoint /{user-id}/accounts may return a higher number than is anticipated. This is because the total_count includes any deleted pages where the user was an admin as well.

The data returned by the endpoint itself, however, will only include pages that are not deleted.

The /user/likes endpoint has changed from time-based pagination (using 'since' and 'until' as parameters) to cursor-based pagination (using parameters 'before' and 'after').

You can read more about those differences here:

With the introduction of app scoped user-ids, we have made changes to how the endpoint returns back data.

As v1.0 has been deprecated, we will focus on v2.x here. /v2.0/{id} may return{id}, or it may return{id}.

This is intentional. This error means that the access token you're trying to extend is not able to access the app ID which is trying to extend that token.

The most likely reason for this is if your app has demographic restrictions applied and we detect that the user whose token you're trying to extend does not meet those restrictions (or no longer meets the restrictions, they may have moved location or we may now have a more accurate location detected for them).

The next most likely reason is that we can't confirm the user meets the requirements (e.g. we don't know their location), and your app's restrictions do not allow these users to access the app.

As of July 2013, it is no longer possible to use the search endpoint using an email in the user search type.

Also, numerous changes have been made to graph api with the introduction of v2.0. The ability to search on public posts and keyword searches are not available with v2.0.

Please refer to the changelog for more details.

Any application created after April 30th, 2014 uses version 2 and later of the API, which will only return your app friends with the /me/friends endpoint, as you stated. Furthermore, all user ID's are now app-scoped ID's, which are unique and permanent to your specific app.

You can learn more about all of the new features and changes that were introduced as part of v2.0.

The documentation for the email field of the User object clarifies the expected behavior here, which is: "this field will not be returned if no valid email address is available".

There are a number of circumstances in which you may think a user should have an email address returned but they will not. For privacy and security reasons it is not possible to elaborate on the precise reason any specific user's email address will not be returned.

Some possible reasons:

  • No Email address on account
  • No confirmed email address on account
  • No verified email address on account
  • User entered a security checkpoint which required them to reconfirm their email address and they have not yet done so
  • Users's email address is unreachable
You also need the 'email' extended permission, even for users who have a valid, confirmed, reachable email address on file.

These posts cannot be fetched via the API because in such posts a user's content is being re-shared on a page, and that user hasn't authorized the app to see her/his content.

User's posts shared on page's timeline won't be available via the API if user has base permission off for the content type of the post.

As a workaround to see the missing photo posts from fans you may be able to fetch the page's albums using the page access token - the photos should be in the Timeline Photos album

Even though a post is public and mentions the Page that is being requested, your App can not see those posts without the read_stream permission from the owner of those posts. This means that the {page_id}/tagged endpoint does not return all posts.

You can read more about this in the Page Feed documentation.

There are cases where a specific app (or any app) will not be able to obtain any information about a Facebook user due to that user's privacy settings - this includes when accessing posts made by that user in a context where your app is expecting to be able to see the post (e.g. page management)

For example, when a user has blocked the app, or has disabled all platform apps from accessing their information via the API.

With the release of v2.1 of the Graph API, this functionality has been removed. For apps created before August 7th 2014 this field is not present in the signed_request anymore.

For apps created before this date, the liked property will always return true regardless of whether or not the person has liked the page.

Please use the and paging.previous links returned in the response directly to get the other result pages. Using the links provided will ensure that your application would not break when the format of the pagination links change in the future.

Like most items on the API, it is not meant to be an exact 1:1 mapping to features and functionalities on the main Facebook site. What the Pages Insights UI calls organic reach is much different and is calculated differently from what Organic reach is via the API.

As an example, the 'organic' value in the Page Insights UI corresponds to the 'unpaid' value in the page_impressions_by_paid_non_paid_unique metric available via Graph API.

We are looking into aligning the two but this may take some time.

This error indicates that the user associated with the access token is unable to see this page due to privacy reasons. For example, the page may be unpublished and the user also not a valid admin of the page.

This error usually happens when you are trying to fetch insights for a very active page. This can be accounted for if you reduce the time interval for which you are requesting insights using 'since' and 'until' fields.

This is expected behavior for test apps and apps in development mode. Once the app is published, it works as expected.

The related bug for this design constraint can be viewed here

Only an Admin, Editor or Moderator can read and send Page messages. People with other roles, such as Advertiser and Analyst, cannot read Page conversations.

Please visit this help page to learn more about the various Page roles:

The total counts for 'page_fans' and 'page_fans_country' are not always equal. There are many factors that can affect the 'page_fans_country' value. For example, some page fans may not have set their home country on their accounts, or some page fans may have a privacy setting that hides their home country.

To find out more about the Facebook privacy settings, please visit this page in the help center:

Some public Page posts are re-shares from user content. If the User who created the post has not given the required permissions to the App, the App can't access their posts via the Graph API, and therefore can't comment on those posts.

Posts that are created inline as part of an Ad Creative creation can't be boosted separately. Therefore, those posts will also not appear in a call to the /promotable_posts endpoint of a Page.

This happens if you are using an app that is still in development mode to schedule the posts. Please use an app that is live and this should work fine.

We apologize that we currently do not support the creation, update or deletion of cover photos via the API.

To learn more about the cover photo API please visit

This is the current behavior. Page admins cannot post to pages as themselves through the Graph API - that functionality is only available on and our mobile apps.

No, there is no way to get the entire list of the people who have liked a Page. This is by design.

Please ensure you are using a page access token when performing actions on behalf of a page. The error message indicates you are using a user access token instead of a page access token.

You can learn about the different kinds of access tokens here:

It's not possible, pinning posts and reading pinned posts is only available through the native Facebook products.

If comment mirroring has been turned on for the external URL at some point, the reactions to posts where the comments are mirrored will be logged against the URL itself, and will be returned when calling {URL-id}/reactions>

Pulling data for more than 1000 breakdown values of the /app_insights/app_event endpoint is not supported at this time. We suggest using the Facebook Analytics UI to slice down into specific data points, such as specific countries, if interested in breaking down the data into specific categories.

You are probably calling the endpoint too fast even before the data has propagated to our servers.

The API calls should be made after waiting for 1-2 seconds to allow for the information to propagate to all our servers.

The 'page_fans_country' metric will typically be a subset of the count from page_fans. This metric covers a breakdown by country of the page's fans, provided we can determine the user's country accurately.

The metric also includes only the top countries (by fan count) for a page's fans, not all countries in which there are fans; for pages with fans in many countries, the least populous countries will not be included in this metric.

The API does not support the use of offset based pagination.

Instead you should use either the “paging” links that are returned at the end of each response from the Graph API or use “cursor” based pagination, which is most preferred.

More information on how to page correctly through the Graph API is described here:

There are short-lived and long-lived access tokens. The short-lived token is meant for a short session and will typically expire after a few hours.

You can exchange a short-lived token for a long-lived token, which will have a life-time of about 60 days.

You can read about this in the Access Token Documentation.

This is intentional behaviour - the search API respects privacy on Facebook, is tailored to the user whose access token you're using, does not support hashtag searching, and is not designed to have parity with the same search being run in the search typeahead on

We explicitly do not support or have a goal of the search API returning the same volume of results or specific results as searches on - and in general posts being returned via the API are subject to more restrictive privacy and security checks than the same posts on Facebook itself.

Our system enforces rate limits on API calls made by Apps. To learn more about the various limits and prevent your App from being throttled, please visit

Instant Articles

You can add animated GIF images to your article using a <figure> element which wraps an <img> element referencing the GIF image's URL. As with other images, you can add captions and attributions to GIF images.

You can refer to the documentation for more details and examples here.

You can re-use a feed URL on different pages, but note that only articles which have canonical URLs matching the domains claimed by the page will be ingested.

Our recommended approach is to use separate RSS feeds for each page containing only the articles that should be ingested by that page.

You can add supported social embeds, including videos, using Social Embeds. For other third-party video players, you can add them to your article as an Interactive Embed.

You can embed interactive graphics and content in your articles using a <figure> with the op-interactive class. The figure should contain an <iframe>, which contains the content to be embedded.

You can find more details and see examples here.

You can specify a caption using the <figcaption> element. Within the caption, you can add an attribution using the <cite> element.

You can find more details and examples in the documentation here.

When an article is in Draft mode, it will only be visible as an Instant Article to page admins. Once the article is published and is Live, it can be shared by anyone on Facebook and it would render as an Instant Article to everyone.

Please check if you have granted the pages_manage_instant_articles permission to the app. This permission is required to call API methods to read and update your page's Instant Articles.

You can find out more about using the API here.

If you are using the dir="rtl" attribute to display a right-to-left language in your article, you could be viewing the article in an app that doesn't support right-to-left languages in Instant Articles.

Please check that you are using the latest version of the app. The minimum version of each app that supports right-to-left languages are:

  • Facebook for iOS: 52.0
  • Facebook for Android: 69.0
  • Pages Manager for iOS: 44.0
Note that we do not currently support right-to-left languages in Pages Manager for Android.

Please check if the dir="rtl" attribute has been set on the <body> tag of your article. If your article isn't using a right-to-left language, you should not set this attribute in your article.

Please check that you have set the dir attribute on the body tag of your article. For right-to-left languages, you should set the dir attribute to "rtl".

The News Feed preview of an article uses the image specified in the og:image meta tag in the web version of the article. You can also choose to replace the image with a video by adding the "fb-feed-cover" class to any video in your article. You can read more about News Feed previews here.

When sharing an article's URL before the Instant Article is published, it will redirect to the mobile web version of the article. Once the Instant Article is published, all shares of the link including those posted before the article was published, will automatically display the Instant Article when viewed on mobile.

At the moment the "views" metric only includes iOS users. Android views are counted separately in the "android_views" metric.

You can get more information about this here.

We have yet to launch support for the development feed in Pages Manager for Android. As a workaround to view your articles on Android for now, you can try adding the articles to your production feed as drafts.

To edit your Instant Articles, you can use the Page interface. To do so, you can go to your Page on your browser, and go to Publishing Tools > Instant Articles. You can see your articles and edit them right there. You can read more about it here:

The timeout for the feed download is currently 30 seconds.

No, the shared link must be the canonical URL of the article. If the URL is changed - for example, by adding parameters - it will be considered a different URL.

Any errors or warnings found when ingesting your RSS feed will be shown on the Instant Articles tab of your Settings page. You can also view warnings and errors for individual articles by clicking on the article from the Instant Articles tab of the Publishing Tools page.

Please check that your RSS feed follows the format documented here.

Your articles' canonical URL should also use the domain configured for your page, or a subdomain of it. If you're seeing new articles being ingested, but updates to existing articles are not shown, please check that you have incremented the "op-modified" timestamp.

You can find more information about this here.

A common reason for articles not being updated from the RSS feed is that the op-modified timestamp of the article in the feed is the same as the version we last fetched. We update an article only if the timestamp is later than the last version.

Additionally, you should also confirm that the same canonical URL has been used in the updated version of the article.

You can refer to the documentation for more information on how we fetch articles from the RSS feed here.

We attempt to fully load and parse your RSS feed within 10 seconds. This error indicates that this was unsuccessful.

One way to resolve this is to include less items in your RSS feed, for example by only including articles that are new/changed since the last ~10 minutes. Since the feed is fetched every 3 minutes, it would be unnecessary to include unchanged articles.

Unfortunately, we don't have a list of static IP addresses for the crawler. However you can use the user agent of our crawler instead: facebookexternalhit/1.1

If an update to an existing Instant Article is more than 24 hours old based on its op-modified time, it will be ignored by the pull. This means that the modified time should be within 24 hours of the modified time set in the existing article and not the current time. In such cases where the update is ignored, you can make the changes to the articles manually via the web-based Instant Articles editor tool.

You can find more information about this here.

Please check if the duplicate articles are using different canonical URLs. We use the canonical URL of an article as its unique identifier, so articles having different canonical URLs will be treated as separate articles.

One common issue is that your CMS may publish updates to articles with a different URL, resulting in the updates being ingested as a new article.

Yes, each page is uniquely mapped to a domain name and this is a 1:1 mapping. We require that the Instant Articles belonging to a particular page have canonical URLs that belong to the specified domain or a sub-domain of the same.

However the domain of the RSS Feed URL itself need not match the one mapped to the page. This restriction is only for the canonical URLs of the articles in the feed.

If you want to publish articles to different pages depending on their language, you should set up different RSS feeds for each language, and configure each page to use the appropriate RSS feed.

No, once an article has been ingested from your RSS feed, it will remain stored as an Instant Article until it's deleted from your page's publishing tools. You can then safely remove it from your RSS feed to speed up the next fetch.

At the moment there is no way to publish or delete articles via an API, though we are working on this.

The Like button uses the Accent color configured in your style settings. Please check that you have configured a color that is visible against your header.

Also, the Like button only shows up if the user viewing the article hasn't already liked the page, so it won't show up for the Admins of the page who would have Liked the page earlier.

Please check that you are not using multiple <br> tags in a row. To split your article's text into multiple paragraphs we recommend using paragraph (<p>) tags instead of line breaks.

Please ensure that you have added the "op-tracker" class to the <figure> tag wrapping the tracking pixel. Without this tag, it will be treated as an image embed.

Please check that you are using a supported format for the video file. You can find a list of all supported video formats here.

You should also ensure that you are correctly wrapping the video embed in a <figure> tag, and that you're not wrapping the video in a paragraph (<p> tag).

This warning is commonly shown if you have wrapped non-text content - such as images or interactive embeds - within paragraphs (<p> tags). Paragraphs should contain only body text, and any other content should be added within the <figure> tag or other appropriate container elements.

No, the Caption (<figcaption>) element only supports <h1>, <h2> and <cite> tags. The paragraph (<p>) tag is not supported.

The "muted" attribute isn't supported on <video> elements right now.

Ads in articles are defined using the standard HTML5 <figure> element, which wraps an <iframe> element containing the markup for your ad. You can apply the op-ad class to a <figure> element to specify an ad in an article. There are two ways of specifying ads: by specifying the URL of the ad directly using the "src" attribute in the iframe, or by embedding the unescaped set of HTML and scripts within the iframe.

You can find more information about ads here:

The standard image element doesn't support using an SVG image. You can instead use an interactive embed ("op-interactive") and add an <img> element within the iframe, with the "src" attribute set to the URL of the SVG image.

You can use the Map element documented here: This is the recommended way of adding a map to Instant Articles.

If you're adding a Google Maps embed to your article as an interactive embed, there is a known issue with the way the embed works that may prevent the map from being shown. To work around this issue, you need to enclose the iframe loading the map content ("") within another iframe.

You can embed interactive modules using a op-interactive figure. You can get more details and code samples here:

To define a height, add the "height" attribute to the <iframe> element wrapping your embedded content. The value of the attribute should be an integer value indicating the height in pixels. You can set the height up to a maximum of 960 pixels.

You can add a cover by adding a <figure> tag within the header. You can use either an image or a video as the cover by adding a <img> or <video> tag in the figure.

You can find out more about covers here.

To add spacing between images, you can add empty paragraphs between images - for instance, <p>&nbsp;</p>.

To add an attribution, use a <cite> element within the <figcaption> element.

On Cover images, you can specify the attribution to always be visible by explicitly specifying one of the Vertical Alignment attributes on the <cite> element. Otherwise, your citation will not be shown on the image until it is expanded.

You can embed social content by adding a figure with the "op-social" class and adding an iframe containing the content to be embedded.

You can refer to this document for more details and code samples.

You need to use a direct link to a video file (for example, an mp4 file) to add a cover. As videos hosted on Facebook do not provide a direct link, you will need to host your video elsewhere to use it as a cover.

You can use some HTML tags inside list items, for example to bold text or add links. To customize the color or font style, you can use the style editor on Facebook Page interface (Settings->Instant Articles).

If you are embedding a video using the <video> HTML element, this is not possible as we don't support playing multiple videos in a sequence.

If you are embedding a video player as a social embed in an iframe, this should be possible as long as the embedded player supports it.

Blockquotes are not supported, they would need to be placed outside the paragraph tag.

If the title of the article is long enough that it displays on two lines, only the title will be shown in the News Feed. If the title fits on a single line, the News Feed preview will also show the beginning of the article's text.

Please check that you have not added the "data-fb-disable-autoplay" attribute to your videos.

If videos are not auto-playing for a specific person, check that video auto-playing is not disabled in the settings of the Facebook app. You can find the instructions to check this here.

You can display a video in the News Feed preview of an article by adding the "fb-feed-cover" class to any video in your article. You can read more about News Feed previews here

It's required to include a <time> element in the HTML markup for each of your articles, using the op-published class, to specify the date/time when the article was originally published.

The op-modified class is not required. You'll only need to include a <time> element with this class if you are updating the content of the article and want us to update the version of the article that we have stored.

Please check that you have wrapped your text in paragraphs (<p> tags). You can find out more about creating your article's markup here.

Please check that your <figure> are not wrapped in paragraphs (<p> tags). Images should be contained in figure tags that are directly nested under the article tag.

Unfortunately it's not possible to add captions to individual images in a slideshow. You can only add a single caption to the entire slideshow.

You can refer to the documentation on Slideshows for more details.

You can add likes or comments to an image by specifying the "data-feedback" attribute on the <figure> tag containing the image. For example, adding the attribute data-feedback="fb:likes,fb:comments" will display both likes and comments on the image.

For more information, you can refer to the documentation for the feedback attribute.

When specifying a width for items such as interactive embed, please use an integer value specifying the width in pixels. By default, items are displayed with full width.

To display an interactive embed without any margins, you can add the "no-margin" class to the iframe containing your content.

If we have already approved an RSS feed for your page, you do not need to submit it for approval again if you change the feed URL.

We map every page to a unique domain name. The URL of the RSS feed itself need not match this domain name. However, the canonical URL of your individual articles within the feed must belong to the same domain or its subdomain. If you are only changing the URL of the RSS feed, this will not cause any issues.

If you are also updating the canonical URLs of the articles to point to a new domain, you will need to request this domain update through your Partner Manager and they should be able to guide you through the process.


Please make sure your Facebook Application has a real iPhone Store ID, iPad Store ID (for testing purposes this doesn't have to be your real ID, you can use one of any app available at the Apple App Store) set, and have iOS - iPad enabled in your App Center Listed Platforms.

This is by design. Feed dialog publishes content with an attachment, so it's not possible to customize additional attachments.

Javascript SDK

Please refer to this doc for some best practices to optimize images in order to generate great previews here.

Response data is only available if the user is logged into your app using Facebook and has granted publish_actions. It's also documented here.

This is an intentional change. We have shortened the friends list in an attempt to make game requests more relevant to the appropriate player. Note that players can still select as many friends as they so choose using the Search field.

The good news is that with this change we’ve seen an increase in clicks and a sizable increase in overall CTR. We look forward to continuing to optimize this channel, and to find new ways to ensure that the right games get in front of the right people.

Link Sharing

The crawler will look for a AAAA record and return a response code 0 if it is not found. Ensure that your AAAA record is updated correctly when you change your URL or server.

Please see Updating URLs for more information.

Changing og:title, og:image, etc. only applies to future shares of that link.

Once a person or page shares a link, and there have been more than 50 interactions with the post (comments, likes, shares, etc.), then the title cannot be changed. This is to prevent a site from changing details of a link after you've interacted with it, making it look like you were interacting with something different. All other properties can be modified at any time.

If you've shared a link and updated the image, the original share will continue to show to old image unless you refresh it in the post.

To refresh the link image in a post:
  1. Navigate to the post in your newsfeed.
  2. Click the ellipses in the upper-right corner of the post.
  3. Select Refresh share attachment.

We freeze titles after a number of actions are taken against that object (described here: Updating URLs).

Many factors go into how an image may be cropped. For example, we try to center the image around faces that we can detect.

For large images, try to keep your images as close to 1.91:1 aspect ratio as possible to display the full image in Feed without any cropping.

Page posts always use a large, landscape image for link shares. This is the same across desktop and mobile Feed. Try to keep your images as close to 1.91:1 aspect ratio as possible to display the full image in Feed without any cropping.

Your link may have been flagged by our content filtering system. If you believe this is in error, please submit a report on our Help Site; be sure to include the relevant URL.

Images are cached asynchronously, so the image may not render the first time someone shares your content. You can avoid this by either:

All shares and likes are tied to a specific URL (what we call a canonical URL). Changing the site structure to use new URLs will therefore begin attributing likes and shares to that new URL.

Please see Preserve Engagement Metrics for more information.

All shares and likes are tied to a specific URL (what we call a canonical URL). Changing the site structure to use new URLs will therefore begin attributing likes and shares to that new URL.

Please see Preserve Engagement Metrics for more information.

Images smaller than 600 x 315 pixels but larger than 200 x 200 pixels will be rendered with a small, square image.

We consider all image URLs immutable, since these are used to cache the resources at different layers, so if you need to replace an image, you need to also use a new URL. As the caches age, we will fetch the new image and the issue will fix itself.

If you are using a different URL but still seeing the old image, you can also go to the Sharing Debugger and rescrape the URL:

All URLs must be absolute as they represent the canonical location of a resource (page/image), so that we can attribute shares and likes to the correct URL and cache images properly.

The original image is no longer available, is too big or could not be fetched due to a temporary issue. Ensure the image URL is accessible to our crawler, is no bigger than 8mb and is served with less than a few seconds of latency.

When you change the og:image for a page, make sure that you do not remove the old image from your site, as then existing shares will show this white area.

Marketing API

This is caused by replication lag across our datacenters. It takes several seconds before this process finishes, before which the object ID won't be accessible via the API.

If you attempt to read an ad's details before it's fully saved, you may receive a GraphMethodException with a message like Unsupported get request. Object with ID 'XXXXXXXXXXXXXXXXXX' does not exist, cannot be loaded due to missing permissions, or does not support this operation.

Waiting a moment before trying to GET the ad details should work around the issue.

Sometimes you may run into a validation error when trying to use a certain creative within a particular campaign. This can happen when the campaign has an objective that is incompatible with the creative you are using. One example of this could be that your creative points to a canvas game, while the campaign objective is "MOBILE_APP_INSTALLS".

In order to resolve validation errors you might be seeing, you can follow the Marketing API Validation Best Practices.

Please check that the upload sessions which did not contain the items in question did not contain any failures.

Items will only be deleted that no longer exist in the feed of a successful upload session when deletion_enabled is set to true.

If you encounter this error please check the status of the ad account being specified. This error is often returned when the ad account is in an unsettled state.

This behavior is expected since data in the backend for Page Insights is stored for 2 years only. Thus the call is expected to return zero values. The only items which will not be zero are the inline likes/comments/shares on a post whose data will be retained by the post itself.

Please check the syntax of the targeting spec, specifically ensuring that the targeting spec has valid geo_locations parameters and values.

When you create an ad with certain objectives, the default conversion specs will be set. If you make change to the conversion specs, the existing specs will be overwritten.

Please note that certain objectives will not have default conversion specs and must be specified explicitly.

This could be happening because the work_positions audience for the country you are targeting is so small that it does not affect the reach estimate. We are continuing to gather data that will hopefully improve the number of people added to the work_positions exclusion which will affect the reach estimate.

This is happening because your app has the Stream post URL security migration enabled.

if your app has that setting turned on, then the system will not allow link post ads of any kind to be created unless they redirect to the canvas url referenced in your app setting. It shouldn't be a requirement to have that enabled unless your app is a canvas app and only posts stories that redirect back to the canvas app domain.

The user is likely associated with the account via a Business Manager association, which will not show up as an explicit Graph API association.

Please confirm that you have the Partner Categories specified in the appropriate targeting field. Partner Categories retrieved from the “/partnercategories” endpoint contains a field called “targeting_type” which specifies the targeting field you need to use when specifying a Targeting Type.

For example if your Partner Category returns the “targeting_type” of “behaviors” then in your targeting spec you should use that Partner Category in the “behavior” field of your targeting spec.

More information on Targeting Types and Partner Categories can be found here:

This error can be caused by a Custom Audience that does not have any inclusions/exclusions set. The best way to resolve this issue is to create a new Custom Audience and make sure that you have set some inclusions/exclusions.

More information on custom audiences is available here:

An Ad Set can have both a daily_budget and lifetime_budget. The daily_budget value defined in your account's currency must be at least 100 cents and the duration must be longer than 24 hours. If you query any of those fields, both will be returned. A value of 0 will be returned when a field is not used.

To learn more, please visit:

The adcampaign_groups endpoint uses cursor based pagination, so does not return the count, limit, and offset fields. We recommend using cursor-based pagination for all endpoints to get consistent results.

For more information about how to use cursor pagination, please see here:

It might be that some of the posts are created inline. To retrieve these inline posts, please see the note on the /promotable_posts "is_inline" field at the bottom of this doc section:

Messenger Platform

As long as the user replies to the first question the messaging window will be open. If the anwers provided disqualify thre user or the user does not reply, then the ad experience will end and the ad will pass thread control to the target app and provide the metadata "messenger_lead_gen_incomplete" this allows business to have a fallback experience to convert non leads into customers. See HOP webhook after Lead Ad for more info

Send Summary is enabled by default only when an App is selected, in the Create Template dialog inside the Ad. Note the summary can be disabled on the ad after selected the connected App. Even when an app is not selected the Lead Gen Ad will pass thread control to the Handover primary reciver, when set, or just release thread control. Any follow up message after the lead is submitted will be sent to subscribed Apps. Apps can query Conversation API to retrieve the message history and get the information shared during the lead generation.

By Default Send API and Webhooks are blocked while a Lead Generation Ad is in progress. App Id: 413038776280800 for Messenger Lead Gen App will have thread control. This behavior can be disabled using the Block Send API toggle on the Create Template dialog inside the Ad

After the lead submission ends Apps will get webhooks on user messages and can reply to them. If an app was selected as part of the App then only that selected app will be allowed to reply and will get webhooks on the messaging channel. The messaging window is open and the App can reply using Send API

Apps are installed from the app website using Facebook Login and granting pages_messaging permission to a particular Page. Authorized Apps will show up in Page settings inside Advanced messaging.

Only Authorized Apps for the Page will show up. You can see Authorized apps in Page settings inside Advanced messaging.Apps are installed from the app website using Facebook Login and granting pages_messaging permission to a particular Page.

Automated chat experiences (i.e. ‘bots’) should disclose that the person is interacting with an automated service:

  • at the beginning of any conversation or message thread
  • after a significant lapse of time
  • when a chat moves from human interaction to automated experience

Learn more about this policy here.

When required by applicable law, automated chat experiences (i.e. ‘bots’) must disclose that a person is interacting with an automated service. This is also good practice even when not required by applicable law so users aren’t surprised. You can read more about this policy here.

Yes, a single Facebook app can subscribe to multiple pages. Once it goes for app review, like the permission pages_messaging, the app can subscribe to receive webhooks on more than one page. It will be up to you to get the context of each webhook based on the payload.

Yes, more than one app can be subscribed to a page. When multiple apps handle the same conversation is best to use the Handover Protocol to handle which bot owns the thread at any given time.

This can happen if the user has deleted the thread. This results in the bot not being able to message the user again. The bot will be able to communicate with the user once the user re-initiates by sending a message.

Here is a workaround to use a platform test user for your messenger platform integration:

  1. From your app's Roles page, create a new test user by clicking the Add button.
  2. Toggle the Authorize Test Users for This App? option and grant permissions "page_messaging".
  3. Use the Edit Button and get an access token for this user (using v4.0). Please save this for later.
  4. Use the Edit button to login as the test user.
  5. After logging in, create a page as the test user.
  6. Use the user access token for the test user to get the page access token for this user. You can do this with the following call:[TEST_USER_ACCESS_TOKEN]
  7. Use this page access token to link your Facebook Application with your Page:[TEST_USER_PAGE_ACCESS_TOKEN]
  8. After you have followed these steps you will receive RTU updates to your Test Page and be able to message your Test User from your Test Page. In addition to the above you can replace your access token with a long-lived token if they are expiring too quickly for your tests. Please follow the documentation here:
    GET /oauth/access_token?  

There are multiple reasons why this may happen:

  • You're using an ID from Facebook Login. User IDs from Facebook Login are not intended to work with the Send/Receive API. Only user IDs obtained through authentication with the Messenger Platform will work with the Messenger Platform.
  • You're using an ID with the incorrect Page Access Token. User IDs for the Messenger Platform are scoped to a page and, therefore, are page specific. If you use a valid user ID but with a page access token that's associated with a different page, the call will not work. Be sure to use the user ID and page access token associated with the same page.
  • You're sending to a phone number that hasn't been recently verified. When using the Send API with a phone number, we will only send messages if the phone number has been recently verified. Even if the phone number is shown as verified, but has not been recently verified, then the send may fail. Re-verify your phone number and wait 24 hours until trying again.

When using the “Send to Messenger” Plugin, the data-ref parameter can be used by you as a pass-through-parameter to send through any information regarding the context of the click.

People may also discover your page through search in Messenger. In these cases, you won't have a pass-through-parameter. You can use the account linking feature to associate a thread to a user account on your site.

The app dashboard under Messenger Settings provides a button called "Show Recent Errors" that shows if webhooks are getting response 200 or failing.

There is a tool that shows recent webhook errors. If webhooks are failing to be delivered, Meta servers will unsubscribe your URL. To find the tool, go into your App dashboard > Messenger > Settings, inside the Webhooks card there is a button called Show recent errors

Make sure your webhook is responding with a status code of 200. This communicates to us that the webhook was successfully received. If you do not return a 200, we will retry the call until successfully completed. Also, if a webhook doesn't return a 200 for an extended period of time, we will surface developer alerts.

Also, note that a successful status code is returned in a timely manner. A webhook call with timeout after 20 seconds. Be sure to architecture your code such that webhooks are processed asynchronously so that a successful status code can be returned immediately and processed separately.

Calls to the webhook contain a field in the header named X-Hub-Signature, which can be used to validate that the call came from Facebook.

There are 2 steps to receiving callbacks. First, make sure your webhook is setup properly ( There is an indicator when webhooks are properly setup.

Second, you must subscribe to each page. All pages that are subscribed to will be listed.

If calls to your webhook fail for an extended period of time, your app will be unsubscribed and you will have to re-add your webhook and re-subscribe your page.

Open Graph

The content most likely needs to be re-scraped, which will happen automatically in time, or it can be manually triggered via the Debug Tool.

You cannot control how a post is going to be displayed in News Feed or Timeline when sharing your open graph story beyond supplying the OG tags for your page. Facebook optimizes posts automatically to ensure maximum engagement for your content.

Yes, the Action Links feature has been deprecated. Support for action links has been removed from the Facebook site, so it is also being deprecated from platform. This feature may be revisited in the future, but not on the current roadmap.

If your web page is using our OpenGraph meta tags and is including an og:image entry, we will fetch that image and display it in the preview. Additionally, if your site provides both og:image, og:image:width and og:image:height, that image will be used even for the first share created.

Failing to provide these means that you will need to wait for our crawlers to fetch and analyze the images first. See for an example of how this can be done.

Rest API

This is by design. The REST API has been deprecated a long time back, and is not expected to continue working. There is a limitation - Page access tokens cannot be used with the REST API.

Social plugins

You can set a locale for the Like button using the 'locale' parameter in the JS SDK. This will work for non-logged in users. If a user is logged in, their language preference is also taken into consideration. If that is set to a specific language, the Like button will be in that language.

You can test this behaviour by visiting your website without being logged into Facebook (or by using a private session of your browser).

It is against Facebook policy to pre-populate the text area when sharing to Facebook. Your application's user will have to populate the text they want to share themselves.

Pre-filling the text area when sharing violates Platform Policy 2.3 ( ). We enforce this policy to ensure users are sharing exactly what they want to share on Facebook, and are not accidentally sharing text they did not approve of.

This can be the expected behavior, if you change or modify the URL of the web page. Each URL that houses the comments plugin is treated as a separate open graph object and comments are associated with that object. Thus, if you modify the URL, a new object is created and so the existing comments might not show up on the page.

No, you are not allowed to post comments to a comments plugin via the API.

The sharer will not allow you to pass in custom parameters and will instead pull in the meta-data from the open-graph meta tags of the page directly.

To learn more about best practices for content sharing, please refer to this doc:

WhatsApp Business API

Yes, Whatsapp Flows can be sent with On-Premises API. You can learn more about Whatsapp Flows here, or learn how to get started with Whatsapp Flows and On-Premises API here.

No this is not possible. Numbers that are registered under WABAs (WhatsApp Business Accounts) can only message regular WhatsApp accounts.

We will provide a seven day grace period post sending the warning. This will allow time for businesses to adjust their behavior. If businesses continue to exceed our internally set threshold of calls to the Contacts API vs. number of messages sent, we will permanently disable the phone number.

Interactive messages can be reopened by the user in order to resend an option. This is in case of mistyping the desired option or wanting to choose a new option.

Through user testing we’ve identified 10 as the optimal number of rows to provide a good user experience. If you have a list of more than 10 options, and cannot condense into one list message, we recommend creating an additional step in the flow and using two list messages. During testing businesses had higher response rates and conversions with this approach than using text-based lists.

Through user testing we’ve identified 3 as the optimal number of buttons to provide a good user experience. If you have a list of more than 3 options, and cannot condense it into one button message, we recommend using list messages. During testing, businesses had higher response rates and conversions with list messages than using text-based lists.

There may be a very small number of users for whom their app version does not support this feature, the business will receive a webhook notification throwing an error that describes why the message was unable to be received. It is up to the business to determine how to handle this error elegantly. Best practice would convert the interactive message to a text-based list to allow the user to complete the workflow.

If there is a delay in a subset of numbers, then it is likely not an issue affecting the customers integration but rather an issue on the recipients end, these delays in delivery can happen for a number of reasons. See Send Message Performance, Delays for more information.

No, currently we do not support changing the default path to media storage (/usr/local/wamedia/). All media storage needs to be at this default location in order to work properly.

No, currently we have to use AWS EFS to share the media volume between the Coreapp and Webapp.

The Coreapp will check the /usr/local/waent/data and /usr/local/waent/log directories within the Coreapp container, ensuring there is at least 10 MB of storage, otherwise it will give this critical error.

Check your logs and data directory to ensure you have enough space.

No. There's currently no way to run multiple numbers in the same WhatsApp Business API client setup. We are working on a proper solution that will allow this in the future.

Use the database garbage collection services API endpoint to purge messages and corresponding message receipts from the messageStore.messages and messageStore.messages_receipt_log tables.

Double-check your pass_through application setting. You won't receive any read status callbacks if you have enabled pass_through with WhatsApp Business API client v2.29.1 or higher.

If you'd like to receive the read status callback, disable the pass_through application setting. Note that by disabling pass_through, your database storage could grow quickly. See the Database Management documentation for more information on managing your database.

Database garbage collection periodically cleans up the messages and messages_reciept_log tables to help with database management.

The garbage collector retains certain messages to allow for successful delivery/processing. For example, retaining incoming message for a certain period of time to allow business integrations to mark the message as read.

The Coreapp performs garbage collection at random intervals (i.e., every few hours). This is to prevent potential performance degradation in High Availability stacks due to database contention.

Garbage collection is independent of the callback queue. For example, if the Webhook server isn't available for 4 days, the callbacks will be stored to be delivered when the Webhook server connectivity is restored.

A link will only be rendered as clickable if the recipient has already saved your business number as contact or you have an Official Business Account.

Prior to v2.29.x, it was possible for the outgoing message queue size to grow over time due to a bug. Upgrading to v2.29.3 resolves this issue.

Analytics are not available for QR Codes and Short Links as we limit the amount of data we log to protect user privacy.

You will be responsible for using the appropriate QR code based on expected location and language of users.

QR codes can now be generated and managed directly within the WhatsApp Business Management API and users can scan them with their WhatsApp, iOS, or Android camera.

In addition, with WhatsApp QR codes

  • Prefilled messages are fully customizable and can be changed or deleted at any time,
  • Users will always go directly to the app without any interstitial page, and
  • The in-app experience for an expired code sends the user a clear message.

If a user tries to access a QR code or short link that has been deleted, they will see an error message indicating the QR code/short link has expired.

If the user has the WhatsApp desktop client installed, it will launch a conversation with your business. If not, the user will be prompted to install the WhatsApp desktop client.

The new short links enable prefilled messages associated with a link to be edited or deleted at any time. They also reduce the syntax of the URL to a random code, which eliminates the need to embed messages in the URL and masks the phone number.

We recommend the .svg file format for the best quality in print materials.

A single WABA phone number cannot be associated with more than 2,000 QR codes and short links.

You can view, create, edit and delete QR codes and short links in the WhatsApp Business Management API or in the Business Manager UI.

We are announcing the deprecation of Groups through the WhatsApp Business API. Starting July 8, 2020, only API phone numbers in a group created prior to July 8th can continue to use/manage Groups through the WhatsApp Business API. All other API phone numbers won’t be able to create/manage Groups through the Whatsapp Business API. On October 8, 2020, we will deprecate this feature for all API phone numbers (i.e., API phone numbers will be removed from their groups and no longer be able to send messages to their group).

v2.25.x improves outbound and inbound performance over previous releases. This optimization relies on creating additional database connections. For some deployments, this can cause the number of database connections to increase and reach configured limits. To keep the increased performance, you can increase the maximum number of connections your database server can accept. If that's not possible, you can change the the axolotl_context_striping_disabled parameter to disable this behavior. See the Applications Settings documentation for more information on how to do this change.

If you or your end client would like to request become an WhatsApp official business account, see the instructions in the Requesting an Official Business Account documentation section.

No. Currently, messaging limits only apply to business-initiated messages (notifications).

When sending image as an album from the WhatsApp Business API, you will need to send at least 4 images in succession. If the user's conversation view is currently active when the images are received, then the album view is unavailable until the next visit.

An album will not be created if any of the following criteria are met:

  1. Images with captions
  2. Unread divider - user sees some images, but not the rest
  3. Date header - new day between deliveries

For WhatsApp Business API client's running v2.21.6, when the client is disconnected from the server it may remain disconnected for a few minutes (up to 4 minutes) and then will retry the connection. Upgrading to v2.23.4 will allow for less downtime for a client when attempting to connect to the server.

Error code 471 relates to quality-based rate limits. See the Quality-Based Rate Limits documentation for more information.

All businesses start at the lowest tier and will automatically upgraded to higher tiers as they send out more messages that have high quality.

Yes, when sending a message template, if it failed to display on the receiving end, you will receive a "failed" status callback with "structure unavailable" in the error object indicating that the message could not be displayed. Depending on the recipient, you may also receive a "delivered" status callback which simply indicates that the message was delivered to the recipient after which the recipient failed to display the message.

The following are message template send side validation errors and why you may see them:

  • "No message templates exist in language your-language" or "No message templates exist in language your-language and locale your-locale" — The given language pack does not exist. Check your Business Manager account.
  • "Template your-template-name does not exist in language your-language" or "Template your-template-name does not exist in language your-language and locale your-locale" — You are trying to use a template that does not exist (has not been created or is not yet approved). If you attempt to send a message with a template that was deleted, you will also get this error.
  • "Number of localizable_params num1 does not match the expected number of params num2" — You are trying to send a message template with parameters that do not match the number of parameters expected. Please check your API invocation for correctness.
  • "your-template-name is a rich template and requires the template message API to be used" — You are trying to send a media message template as a regular message template. Make sure the message type is template. See the Media Message Templates documentation for more information.
  • Once templates are approved in Business Manager (or deleted), it can take up to 20 minutes for the WhatsApp Business API client to receive the updated templates. If you are trying to send a message with a template that just got approved, and you get an error saying the template does not exist, you can retry sending the message after waiting the above specified time.

Duplicates messages can be sent to a WhatsApp Webhook as the only guarantee provided is that messages will be received at least once (as opposed to exactly once). If this is affecting how messages are processed on your end, then we suggest dedup-ing Webhook messages based on the message ID.

If that phone number has not been used on WhatsApp Business API, you can use that phone number. Follow the migration steps outlined here to reuse that phone number.

Starting with release v2.18.26, the App Stats endpoint allows for exporting internal metrics in the Prometheus text format. See the Instance Monitoring documentation for more information.

An empty profile object will be returned if the the Business Profile is only partially populated. Please upgrade to v2.21.4 to resolve this issue.

See the Business Profile Settings documentation for more information about completing your business profile.

If you are receiving an error similar to the following when setting up your AWS deployment, try changing to a stack name that uses 8 characters or less.

Country Name (2 letter code) [AU]:State or Province Name (full name) [Some-State]:Locality Name (eg, city) []:Organization Name (eg, company) [Internet Widgits Pty Ltd]:Organizational Unit Name (eg, section) []:Common Name (e.g. server FQDN or YOUR name) []:string is too long, it needs to be less than 64 bytes long Common Name (e.g. server FQDN or YOUR name) []:Email Address []:error, no objects specified in config file problems making Certificate Request Created device key for

There is no limit to the number of parameters allowed in a message template.

The maximum is 250 message templates per WhatsApp business account.

If a Webhook event isn't delivered for any reason (e.g., the client is offline) or if the Webhook request returns a HTTP status code other than 200, we will retry the webhook delivery. We will continue retrying delivery with increasing delays up to a certain timeout (typically 24 hours, though this may vary), or until the delivery succeeds.

There may be cases where you need more time to handle a customer query and may only be able to provide a response after 24 hours. We recommend creating message templates to either:

  • deliver the result to the user, or
  • prompt the user to reply in order to activate the customer service window.

In both cases, please ensure you provide as much context to the message template as possible. For example:

  • "Hello {{1}}, regarding the issue you reported earlier, we regret to inform you that {{2}}. Apologies for any inconvenience caused."
  • We have updates regarding your ticket. Please respond back if you'd like to continue support."

WhatsApp runs experiments to measure and understand the impact of WhatsApp Business API notifications on user experience and the overall product in general. If the user you are messaging is in one of these experiments, they may not receive notifications from you even if they have opted in to receiving them.

If you back up your current setup and restore it on the new machine, the registration information should move over with the rest of your implementation. See the Backup and Restore Settings documentation for more information.

Yes, log rotation for webapp containers and coreapp containers has slightly different behaviors:

  • Webapp: the last 30 log files will be retained. The log file is rotated only if its size is greater than 20MB.
  • Coreapp: the last 30 log files will be retained. The log file is rotated only if its size is greater than 15MB. Rotated files are compressed.

Please Contact Support with any information you have. We will investigate and shut down any fake numbers.

All builds of the WhatsApp Business API Client have an expiry of 6 months from the date of release. If you see this error, upgrade to the latest released version as soon as possible.

You need to first check if the contact exists before sending a message. See the Contacts documentation for more information on how to do this.

This error is due to Coreapp is not yet initialized. It means registration may not have gone through successfully. Please try registration before making a call to another end point. First step after installing WhatsApp Business API is login. Second step is registration. These two steps are necessary before making requests to any other end points.

Note: that the fallback language policy is deprecated beginning with v2.27.8 and the deterministic language policy is now the default policy.

If you create a translation in a new language you need to translate all the elements you use into that language. Otherwise, you might get "structure unavailable" errors since recipient's phone can't find an element it expects for the language it's in. These structure unavailable errors are seen when sending template messages using fallback policy.

If creating language translations is not an option for you at this moment, You can use deterministic policy to avoid these errors.

A message payload from a user can be either a text or media file.

For text, there is not believed to be any identified danger.

For media files:

  • Normally, it is expected that businesses have some protection software (i.e., anti-virus, anti-malware, etc.) in place to analyze any potential threats.
  • WhatsApp is unable to identify or check the content of a file being transferred as it is end-to-end encrypted (the same also applies for text-only content).
  • There is an option to prevent media files being automatically downloaded in the WhatsApp Business API Client. If the business does not want to receive any file from users, they can set the auto_download field to an empty array.

No, there is no way to use the WhatsApp Business API to detect multiples devices using the same number.

Structure unavailable errors occur when the phone cannot read the template message.

Templates are stored on the server. When a template message is sent using the messages node, only the namespace, language, element name, and localized parameters are sent to the phone but not the entire message. Once these values are delivered to the phone, it tries to render the message.

If any errors occur during rendering, a structure unavailable error is sent to the callback URL containing the recipient and message ID. These errors can happen due to a wrong namespace, localized parameter mismatch, wrong element name, etc.

Go to the WhatsApp Manager in your Facebook Business Manager to view the correct number of parameters. Double check that the namespace is correct and that the element name exists.

One common source of errors is not creating translations for all templates in use. For example, if you have 2 templates you generally send and you add a new language translation for one template, please make sure to add that new language translation for another template also. If you are planning to support more than one language, you need to provide translations for all templates in all supported languages.

The good news is that structure unavailable errors is usually due to mistakes in the messages API call and can be fixed by changing the send payload.

You can register new phones numbers and delete old one in your WhatsApp Account in the Facebook Business Manager.

  1. In your WhatsApp Account, go to Settings.
  2. Click on WhatsApp Manager.
  3. Select the Phone Numbers tab. This is where you can manage all the phone numbers for this account.

For images, the caption will be added as description. The caption text appears in full length for images on both Android and iPhone.

For documents, the caption replaces the filename. It is not meant to be displayed on the user's device as description text but instead to show the name of the file. iPhones show the full text while Androids truncate the filename; this is technical limitation of the current implementation of WhatsApp on both devices.

If registration is failing with "sms" because of too many attempts and you see an "access denied" message, then please try registering with "voice"

It is currently 7 days. If a cache has not been updated for longer than 7 days, it will pull the latest language pack from the server regardless of whether the element already exists in the pack or not.

The device will first load from cache, and if an element exists, it will unpack the message using that message template. So instead of modifying message templates, it's safest to simply add a new one with a different element name. That will guarantee that the language pack gets re-downloaded when it can't find that element. Storage costs of message templates are negligible so there's no absolute need to delete message templates.

See Sending Message Templates — Language for more information.

In order to ensure a high quality experience for businesses and users, we're in a limited public preview. If you'd like to work with us, submit more information about your business for consideration as we continue to expand our availability, or reach out to your Facebook representative if you already have one.

Logging a user out via the users endpoint will invalidate all of the auth tokens assigned to that account. Deleting a user will have the same effect, though that's much more drastic. Keep in mind that logging a user in via the users endpoint will return a new auth token, but it will not invalidate auth tokens already in circulation for that user. Anyone in possession of a previously provisioned token will continue to be able to use it until it expires or is invalidated via one of the previously mentioned methods.

If you are seeing this error but the missing mandatory parameter it refers to is set in your json body, it could be a json parsing error. This error can occur when the entire json payload is unparseable because of json formatting errors. Check the values of those parameters for invalid json characters, like a carriage return at the end. Sometimes parameters can be copied in with extra whitespace that might have characters that break json.

There are many reasons for this. Your Coreapp might be down or your database was not setup correctly. If these are not the case, please take a look at your Coreapp logs (or master Coreapp logs if you are running multiconnect). If you see database connection errors, it is likely your database is running out of connections. See the MySQL doc or PostgreSQL doc on this error.

We recommend bumping up the number of database connections on your database. 1000 database connections should be a safe number, but please make your own informed decision on number of connections. If the error persists, please open a support ticket.

Reasons a message template might be rejected include:

  • Contains potentially abusive content such as abusive language or spam-like content
  • Contains promotional content
  • Does not match the select tag type
  • Formatted incorrectly

A "connection refused" error likely means the Coreapp is not running. Use docker ps to see if the Coreapp is up. If it is not up, take a look at the Docker logs. The Coreapp may be unable connect to the database. Make sure your database is set up correctly.

This happens if the Docker bridge is corrupted. The best remedy for this is to stop the Docker service and start it again. You can also try docker restart on your containers.

WhatsApp strongly verifies whether a number provided actually belongs to a phone. The fact that a user has a WhatsApp account is proof that they confirmed the number and no one else has used that number to register on WhatsApp subsequently. However, it is not a guarantee of the physical location of the SIM card.

On the other hand, if a user's phone is lost or stolen, they can deactivate their WhatsApp account. To read more about how users can deactivate their account see the Lost and stolen phones FAQ.

If a customer's phone number becomes inactive, but the customer is still using WhatsApp, the customer will continue to have access to WhatsApp until/if the phone number is reassigned or reregistered.

WhatsApp strongly verifies whether number provided actually belongs phone. The fact that a user has a WhatsApp account is proof that they confirmed the number and no one else has used that number to register on WhatsApp subsequently. However, It is not a guarantee of the physical location of the sim.

On the other hand, if users phone is lost or stolen, they can deactivate their WhatsApp account. You may read to know more about how users can deactivate their account here.

This error occurs when the database has not been set up correctly.

  • Make sure you are using either MySQL 5.7 or later or PostgreSQL 9.5.x, 9.6.x, 10.x.
  • Your database password should not contain any of these characters: ?{}&~!()^.
  • If you are using AWS, make sure your stack has a short name. See the Installation documentation for more information.

Yes, the TCP connection is necessary. If your business cannot open additional ports, you can use terminated SSL.

See the Network Requirements documentation for more information.

This is a known issue. Sometimes upgrading the WhatsApp Business API Client using the CloudFormation scripts also ends up requiring an update to the RDS DB stack. The new RDS stack won't have the same hostname as the original stack, and the Docker containers aren't able to connect to the database. The solution is to SSH into the EC2 instance created by CloudFormation and update the whatsapp.conf file with the new host name, then restart the Docker containers so they pick up the new settings.

Yes, send an API call to the contacts node before sending a message. The information from checking contacts is cached in the container and not doing this might result in an Unkown Contact error. See the Check Contacts documentation for more information.

Use the mcdockerreset script and tear down the webapps then use the mcdockersetup script to bring up a new webapp.

Reason: When the webapp first connects to the DB, it creates the database.yml file. it will never try to create it again. The coreapps will just not start up on a bad DB config; however, the webapp will, so you see the master and slave nodes in your DB because they were setup correctly once you got around all the DB and script issues but the webapps were started by the script in a bad state to begin with.

If a Webhook fails to send a callback, the callback is put into a retry queue. Any callbacks sent after the initial callback failure will not be received. It is only after the initial failed callback succeeds that the rest will follow.

The WhatsApp Business API Client sends the Webhook callbacks to you via the Coreapp container. Therefore, your Webhook endpoint needs to be configured to accept inbound requests from the Coreapp.

You should register a second phone number and spin up a second CloudFormation stack or Docker instance for testing. If you have two WhatsApp Business API Clients active using the same phone number, the server will kick you out because the encryption keys will conflict. We recommend having a second environment that you can use to test your non-production instance before you do any kind of migration on your production client.

MySQL 5.7.x, MySQL 8.0.x, PostgreSQL 13.x, 12.x, 11.x are required. Using a previous version will throw an Unable to initialize config store error.

When you send a message, as soon as you get back a message ID, that means the message request has been stored on the database. The WhatsApp Business API Client will keep attempting to send that message until acknowledged by the WhatsApp server. This process has no end timeline. The WhatsApp server will then try to deliver that message to the user's phone. If the user's phone is not online, the message will be stored for 30 days before being discarded by the WhatsApp server.

The database tables store information related to app settings, chat threads, messages, media, etc., which are all required by the app to operate.

Your business does not get notified when a customer changes their WhatsApp phone number. When you use the contacts node, the status for that number will be invalid.

No, you can run a single account per instance. If you need a second test account make sure to use a different number for that second instance.

Checking the Health is free and can be queried as often as necessary.

Read the Stats documentation to learn more about the application and database stats you can query. Application stats are stored in memory and are cheap to query. Database stats require more resources and should only be queried when needed.

When using the messages node, you need to set the Content-Type header to application/json for the WhatsApp Business API Client to properly parse the message body. There is also an Authorization header that needs to be set and must contain an unexpired access token. See the Login and Authentication documentation for information on how to get your token and when it expires.

Your system might start slowing down as the space fills up. This can be caused by many media files, messages, and large log files. Log files are automatically rotated, but if they start to get large, deleting them is safe.

Messages are stored in the database. You can delete messages as necessary. Also, if the pass_through is set to false in the application settings, then all messages are saved in the database until they are explicitly deleted.

Media files that users send to you are downloaded to the media volumes. It is up to the business to decide which media files to delete, but it is generally safe to delete any media files. You can use docker inspect your-container-id to check where the media volume folder is.

Set up MySQL locally using Docker by following the Docker MySQL guide.

Set up PostgreSQL locally using Docker by following the Docker PostgreSQL guide.

In most cases you should run the database on a separate physical server from the core and web containers. The database server should only be a few milliseconds of latency away from the compute machine(s).

It is up to you when to delete media.

After uploading media, you will receive a media ID, which you can use to send a message that includes the uploaded media element. Upon sending the media message, the WhatsApp Business API will encrypt and upload the media to WhatsApp servers where it will remain for a period of 14 days. After that, you can decide to delete the media by providing the media ID or to keep it for later use. While we recommend keeping the media for 30 days, it is up to you to decide the retention policy based on your business's policy or use-case.

Yes, the database can be used in other ways without touching the WhatsApp related tables.

First check the callbacks for critical errors to diagnose the problem.

If you are seeing "Conflict: Detected multiple instances that share the same number", you need to check your containers. The most likely cause is you have multiple Docker containers trying to connect to the WhatsApp servers using the same WhatsApp account. Make sure you have only one container up and running. If you have old containers, shut them down and the error will go away.

If you want to test our more complicated high availability solution, see the High Availability documentation.

An allowlist can be created with either hostnames or IP addresses.

See the Hostnames section of the Network Requirements documentation for more information.

Yes! WhatsApp allows you to format selected text inside your messages with Bold, Italics, Strikethrough or Monospace.

Yes, message templates support all WhatsApp messaging characters and formatting including emojis, bolding, italics, etc. For emojis, you will need to use the emoji character (copy/paste) rather than its unicode equivalent.

Toll-free numbers are allowed as long as your country code is included. The reason is that toll-free numbers without country codes cannot be uniquely identified — the same number can apply for two different countries.

Also note that there are added complexities around toll-free numbers. Typically, if you call a toll-free number with the country code when you're inside the country, it will fail. This means that there is a chance your customers from your country will try to dial what shows in the business contact (country code included) and they won't be able to reach you. If this is a concern, you will need to let them know explicitly.

Read more about toll-free numbers here.

NO! At any given time, you can only have one instance of the WhatsApp Business API Client running for a single phone number. As soon as you register a second instance, your first instance will get kicked off and fail. We are working on a proper solution that will allow you to accomplish this. We will keep you posted of any updates.

WhatsApp considers communications with Business API users who manage the API endpoint on servers they control to be end-to-end encrypted since there is no third-party access to content between endpoints.

Some organizations may choose to delegate management of their WhatsApp Business API endpoint to a third-party Solution Partner. In these instances, communication still uses the same Signal protocol encryption. However, because the WhatsApp Business API user has chosen a third party to manage their endpoint, WhatsApp does not consider these messages end-to-end encrypted.

In addition, if you are using HTTPS when making calls to the WhatsApp Business API client, that data is SSL-encrypted (from your backend client to the WhatsApp Business API client).

See our WhatsApp Encryption Overview technical whitepaper for more detail.

This is caused by a bug in an old version of the iOS client. We expect the errors to reduce overtime as the general population upgrades.

No, the order in which the messages arrive is not guaranteed to be the same order as what was sent. If ordering is critical to your use case, the suggested approach is to listen for the delivered callback of the first message before firing the second message.

There is a script that can be triggered externally to clean up old logs of a container:

docker exec CONTAINER_NAME /opt/whatsapp/bin/

The script works with both webapp and coreapp containers. By running the script, old log files will be removed so that only 30 log files of the container remain.

Note: Please do not send the same message repeatedly to the same recipient using the WhatsApp Business API.

There can be multiple reasons why delivery rates are not 100%. Some common cases include users having sporadic access to network, being inactive for a period of time, or to create a high quality user experience.

Messages that can be delivered with WhatsApp will have a very high delivery rate. However there are many reasons why a message may not be delivered. You will have access to the exact status of a message by monitoring your callbacks. This is different from sending messages with SMS, for example, where you do not have access to final delivered status and resending the message may indeed produce a different outcome.

Messages may remain undelivered because a user's phone is out of service, or battery, or they have lost it and are getting a new one and have disabled their SIM. It is possible there are errors in the business client's ability to connect to the network. It is also possible callbacks (Webhooks) are not being delivered. You can monitor these situations by using the health node. You can turn on server receipt callbacks to know that the message made it into the WhatsApp server cloud.

If and when a user does reconnect to the network all the messages you sent will be delivered to them. Receiving more than one message with the same content will be a bad experience for them. They will be more likely to block you or complain. You will be more likely to be banned.

If you send a message and receive a message ID from the API, you have done what you can to send this message. Do not resend the same content to the same recipient.

If you are seeing low delivery rates over a prolonged period of time, please file a support ticket with Direct Support.

The WhatsApp Business On-Premises API Client requires a database to stores keys to decrypt messages sent between a business and customers. All messages on WhatsApp are encrypted with sender and receiver keys. Customer keys are stored on their mobile device and business keys are stored in the business' database. Learn more about WhatsApp's Security.

The WhatsApp Business Cloud API is an alternative wherein Meta hosts a business' database. The Cloud API allows you to implement WhatsApp Business APIs without the cost of hosting of your own servers. Learn more.

No. The WhatsApp Business API Client opens an outbound TCP connection to port 5222 or 443 on the WhatsApp servers. TCP traffic occurs over this long-lived connection. Normally firewalls classify this as allowing “outbound traffic and the established traffic.” Of course, packets will flow back and forth once the connection is established but the connection start comes from the WhatsApp Business API Client so there is no need for a rule allowing inbound connections.

MySQL and PostgreSQL are supported. If you run Docker by yourself, you must provide a MySQL/PostgreSQL database for the containers to connect to. Using the AWS template sets up a MySQL database by default.

Requirements depend on your load and situation. The solution will run on any internet-connected machine that runs docker. For instance, simple testing can be done on a laptop.

For single-instance production server setup, we recommend at least 250 GB SSD, 16 GB RAM, and 4 core CPU. HDD is not recommended as the I/O speeds will become bottlenecks under load.

For Multiconnect production server setup, we recommend at least 50 GB SSD, 4 GB RAM and 2 core CPU for each Coreapp/Master/Webapp container.

In most cases you should run the database on a separate physical server from the core and web containers. The database server should only be a few milliseconds of latency away from the compute machine(s).

This setup supports sending approximately 20 messages per second.

Absolutely! Reach out to your WhatsApp representative and make this request.

Currently, there is no way to do this. If you are not capable of handling inbound responses from your users over WhatsApp, we suggest sending an auto-reply message redirecting them to your proper support channels.

In the normal consumer scenario, this is by design when the sender is not in your address book and you have not sent a message to this sender in the past. In the enterprise scenario, a business should use Message Templates when first engaging a user to establish "trust"; in doing so, the WhatsApp Business API Client will then be able to render the link and make it clickable.

In the normal consumer scenario, this is by design when the sender is not in your address book and you have not sent a message to this sender in the past. In the enterprise scenario, a business should use Message Templates when first engaging a user to establish "trust"; in doing so, the WhatsApp Business API Client will then abide by the in-app auto-download setting.

Unfortunately, you will need to pick a different phone number that is capable of receiving SMS or voice in order for us to send the registration code. In the past, we had allowed manual registration codes, but this is no longer supported. Phone numbers that used manual registration codes before will continue to be supported as required. For any new phone numbers, we will only deliver registration codes via SMS or voice call.

If you want to use your 1800 or toll free number, please read this guide.

Currently, there is no way to see how many or which users have blocked your business. The best indicator would be to listen for status callbacks and if you do not receive the delivered status, then either the user has blocked your business or they do not have a network connection. See the Webhook documentation for more details.

If a user has blocked your business, the Contacts API will continue to return that phone number as a valid WhatsApp user. However, when you send the message, it will never get delivered. If it is a paid message, you will not be charged.

Yes, we can set up a new phone number or change the verified name when you are ready to go live.

The maximum file upload size is 64 MB, which means this limit also applies to any image, document, or video you send with a message.

No. The WhatsApp Business API solution requires a clean number.

To find the mountpoint of your media volume, you can run a docker command.


docker volume inspect whatsappMedia


        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/whatsappMedia/_data",
        "Name": "whatsappMedia",
        "Options": {},
        "Scope": "local"

Then, to see all your incoming media files you can run the ls command with the received Mountpoint file path:

ls /var/lib/docker/volumes/whatsappMedia/_data/

For AWS setup, the media volume is mounted to /mnt/wa/media path on the host.

There is no cleanup mechanism for either outgoing nor incoming media files. You may delete your media files manually by locating them on your file system.

You can restart the Docker containers by running the following code:

Coreapp Docker container

docker restart wacore<Current_WABA_Version>

Webapp Docker container

docker restart webapp<Current_WABA_Version>

You can check which version you're running with

docker ps
Working As Intended
Please use our Sharing debugger instead: OG debugger is not maintained any more.
The behavior is by design. All newly created accounts go through a classification process which may last up to 45 minutes. During that time, these accounts won't be able to login to any app.
Carousel Images does not return "media_url" at the Carousel Media Node, as a carousel is a collection of images. Instead, users should query children{media_url} in order to see the "media_url" of the children nodes.
In v2.9 and above, we've started filtering out all posts ineligible due to payment method needing an update for Ad Accounts. Please double check that your Ad Account has a valid payment method.
This field will no longer be supported via the API. You can find all of the information provided by this field from this tool instead:
This is by design that Thread_key will not be included in the webhook event
When 'estimate_DAU' is 0, we automatically return the default suggested bid which is 0 for all entries. The reason being that we do not show audience size for campaigns using custom audience.
For Website Custom Audience, we will return 0 as pixel id and retention days if it has multiple sections since we cannot uniquely identify the retention based on more than one sections. To fetch rule for it, you need to specify rule_v2 instead of rule: GET audience_id?fields=rule_v2
At this time, "Force Web OAuth Reauthentication" feature is unsupported for Device Login. To enable device login feature, please turn off "Force Web OAuth Reauthentication" under Facebook Login settings.
Notifications on canvas games are not guaranteed. We have systems in place which will determine if a notification is of low or high signal automatically and filter users' jewel notifications accordingly. This means that not all notifications will appear within the users jewel notification.
We have privacy policies in place to prevent content generated from an Application that is not visible, to be distributed to the public. Also in effect is the app is in dev mode.
You should be able to add pages to your app that meet a few conditions:
  • The Page must be categorized as "App Page"
  • You should have access to the page via a role
  • The App Page should not already be linked to an existing app
  • The Page must have the same name (or a subset of the name) of the app
/page/* — User information will not be included in GET responses for any objects owned by (on) a Page unless the request is made with a Page access token. This affects all nodes and edges that return data for objects owned by a Page.
The business management permission is a granular permission, which means that it can be granted to some businesses and not granted to others. The access token debugging tool will show the access token has the permission even if it was granted for only some apps.
We maintain a specific cache on Android which can take some time to refresh. However, in iOS, you should see the updates almost instantly when you refresh the article.
The app must be subscribed to 'messaging_account_linking' Webhook event for Account Linking to work. You can subscribe to the event by going to the Messenger tab of your Application Settings.
In order to access the Leadgen information received from a Webhook you needed to be:
  • An admin of the campaigns
  • A full admin of the page
This message is usually shown if the user has an old Facebook for Android app installed on their device. If the user removes the old app and install the latest one, this message should disappear. If not, then please report a bug.
1. The message shown on screen does not mean the user has read it. In order to trigger a read receipt, there need to be some movements on the user side. (The user closing the input box is definitely a movement) An indicator of a message being read is the message text turns from the bold state into a normal state in the preview;
2. There won't necessarily be a read receipt for each message. The read receipt means that ALL messages before this watermark timestamp have been read by the user.
Unique fields are not supported with hourly breakdowns. Unique fields are those prepended with `unique_*` or `reach`.
There's a difference between game requests sent from an app to user and game requests sent from a user to user:
  • App to user game requests are sent through the /apprequests API endpoint. They generate request in games activity feed, but do not generate a notification in the website.
  • User to user game requests are sent through the request dialog. They generate request in games activity feed and notification in the website.
  • Moreover there is also app to user notifications which are sent though the /notifications API endpoint. They generate a notification, but do not generate request in games activity feed.
The post is targeted to either the region or the country. For example, if the post is targeted to "US or CA", the user will pass the rule if she is the United States (US) or if she is from California (CA). If you'd like to restrict targeting to a region within a country, then only region should be specified.
Global pages structure reduces page likes. Once a Global Pages structure is set up, fans will be migrated to different Pages within the structure based on each Page's targeting. As a result, the change in page_fans will not match the difference between page_fan_adds and page_fan_removes.
Newly created custom audiences can sometimes not be fetched via the API. This is due to retention delay and replication lag across datacenters.
It's not possible to get the post IDs for internal FB urls using the ?ids= endpoint. As documented (, that edge is meant for external URLs.