News for Developers

Back to News

Announcing Recommendations API

Robert Boczek
February 18, 2016

Related News

Offer Ads API

February 09 2017

Developers Sandbox Mode

February 08 2017

Today, we're excited to introduce the v1 of our static recommendations API. Advertisers often make common mistakes when it comes to creating their ads, and we want to provide solutions/endpoints to prevent the creation of sub-optimal, underperforming ads. The static recommendations API will allow the API to return “soft errors” (e.g. 'Your targeting is too narrow,' or, ‘your bid is too low') as well as best practice recommendations for our advertiser’s created ads.

We support ads recommendations for campaign, ad set, and ad levels, for GET and POST requests

For POST requests:

A separate enum value: include_recommendations option has been added to execution_options field. When this option is used, recommendations for ad object's configuration will be included. A separate section recommendations will be included in the response, but only if recommendations for this spec exist. This option cannot be used by itself and requires specifying validate_only flag with it.

For READ requests:

GET requests are a little bit different, since we do not have execution_options param, we added a new field recommendations.

Reference: Recommendations API

Examples

Example for ad set level recommendations - POST request

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Targeting;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My Ad Set',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array('US'),
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_PAUSED,
  'execution_options' =>
    array('include_recommendations', 'validate_only'),
));
from facebookads.adobjects.adset import AdSet
from facebookads.adobjects.targeting import Targeting

adset = AdSet(parent_id='act_<AD_ACCOUNT_ID>')
adset.update({
    AdSet.Field.name: 'My Ad Set',
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.daily_budget: 1000,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.bid_amount: 2,
    AdSet.Field.targeting: {
        Targeting.Field.geo_locations: {
            'countries': ['US'],
        },
    },
})

adset.remote_create(params={
    'status': AdSet.Status.paused,
    AdSet.Field.execution_options: [
        'validate_only',
        'include_recommendations',
    ],
})
print(adset)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My Ad Set")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
  )
  .setStatus(AdSet.EnumStatus.VALUE_PAUSED)
  .setExecutionOptions("[\"include_recommendations\",\"validate_only\"]")
  .execute();
curl \
  -F 'name=My Ad Set' \
  -F 'optimization_goal=REACH' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'bid_amount=2' \
  -F 'daily_budget=1000' \
  -F 'campaign_id=<CAMPAIGN_ID>' \
  -F 'targeting={"geo_locations":{"countries":["US"]}}' \
  -F 'status=PAUSED' \
  -F 'execution_options=["include_recommendations","validate_only"]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/act_<AD_ACCOUNT_ID>/adsets

Sample response:

"success": true,
"recommendations": [
{
"title": "Your Bid Is Low",
"message": "Your bid is low and won't get as many results as you might want. Consider increasing your bid. The suggested bid amount is {min}-{max} for optimization goal {optimization_goal}.",
"code": 1942008,
"importance": "HIGH",
"confidence": "HIGH",
"blame_field": "bid_amount"
}
]

Example for ad level recommendations - POST request

use FacebookAds\Object\Ad;
use FacebookAds\Object\Fields\AdFields;

$data = array(
  AdFields::NAME => 'My Ad',
  AdFields::ADSET_ID => <AD_SET_ID>,
  AdFields::CREATIVE => array(
    'creative_id' => <CREATIVE_ID>,
  ),
);

$ad = new Ad(null, 'act_<AD_ACCOUNT_ID>');
$ad->setData($data);
$ad->create(array(
  Ad::STATUS_PARAM_NAME => Ad::STATUS_PAUSED,
  'execution_options' =>
    array('include_recommendations', 'validate_only'),
));
from facebookads.adobjects.ad import Ad

ad = Ad(parent_id='act_<AD_ACCOUNT_ID>')
ad[Ad.Field.name] = 'My Ad'
ad[Ad.Field.adset_id] = <AD_SET_ID>
ad[Ad.Field.creative] = {
    'creative_id': <CREATIVE_ID>,
}
ad.remote_create(params={
    'status': Ad.Status.paused,
    Ad.Field.execution_options: [
        'validate_only',
        'include_recommendations',
    ],
})
Ad ad = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAd()
  .setName("My Ad")
  .setAdsetId(<AD_SET_ID>)
  .setCreative(
    new AdCreative()
      .setFieldId(<CREATIVE_ID>)
  )
  .setStatus(Ad.EnumStatus.VALUE_PAUSED)
  .setExecutionOptions("[\"include_recommendations\",\"validate_only\"]")
  .execute();
curl \
  -F 'name=My Ad' \
  -F 'adset_id=<AD_SET_ID>' \
  -F 'creative={"creative_id":"<CREATIVE_ID>"}' \
  -F 'status=PAUSED' \
  -F 'execution_options=["include_recommendations","validate_only"]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/act_<AD_ACCOUNT_ID>/ads

Sample response:

"success": true,
"recommendations": [
{
"title": "Targeted Languages Don't Match Text",
"message": "The languages you're targeting are different from the language ({recognized_language}) you appear to be using in your ad's text. For better results, try using the same language for both your targeting and your text.",
"code": 1942001,
"importance": "HIGH",
"confidence": "HIGH",
"blame_field": "creative"
}
]

Example for ad recommendations - GET request

use FacebookAds\Object\Ad;
use FacebookAds\Object\Fields\AdFields;

$ad = new Ad(<AD_ID>);
$ad->read(array(
  AdFields::NAME,
  AdFields::RECOMMENDATIONS,
));

// Output Ad name.
echo $ad->{AdFields::NAME}.PHP_EOL;
// Output recommendations
echo $ad->{AdFields::RECOMMENDATIONS}.PHP_EOL;
from facebookads.adobjects.ad import Ad

ad = Ad(<AD_ID>)
ad.remote_read(fields=[Ad.Field.name, Ad.Field.recommendations])
Ad ad2 = new Ad(<AD_ID>, context).get()
  .requestNameField()
  .requestRecommendationsField()
  .execute();
curl -G \
  -d 'fields=name,recommendations' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<AD_ID>

Sample response

"id": "<AD_ID>",
"recommendations": [
{
"title": "Use Objectives Optimized for Mobile",
"message": "Your ad links to a mobile app store. Consider creating campaigns with objectives that are optimized for mobile, such as app installs or app engagement.",
"code": 1942010,
"importance": "HIGH",
"confidence": "HIGH",
"blame_field": "creative"
}
]

FAQ

Q: How does this work?
Using validate-only mode, Facebook will evaluate the ad object against the coded recommendations and return recommendation details and the api spec field associated with the recommendation.

For existing ad objects, you can ask for recommendations by including **recommendations **in the list of requested fields. Found recommendations will be included in the response.

Q: What recommendations are currently included in this API?
You can see a list of included recommendations in the documentation here

Q: How is this different than the current validations in the API?
We do have endpoints that validate for correct syntax, however the requests may still not perform as well as they could. With the Recommendations API, we can prevent advertisers from successfully creating ads that we know will underperform.


Related News

February 09 2017

February 08 2017

December 22 2016

December 18 2016

November 16 2016