Offer Ads

Offer Ads help advertise discounts and promotions with consumers. You can claim, save and redeem your offers, and if not, we can send a notification to remind you before it expires.

You can also bring Facebook's Offer Ads creation IU to your website using the JavaScript SDK. Learn more about the Offer Dialog below.

To create an offer ad, create an offer and promote it with link_data, known as Ad Creative Link Data for AdCreativeObjectStorySpec.

Create an Offer

Create offers that are online, offline or both. You can redeem online offers on websites, offline offers at local stores or both online and at local stores. There are four types of offers available: percentage_off, cash_discount, bogo and free_stuff. For all offers options and parameters, see Page Native Offers.

Note: You cannot update or delete offers; instead, create a new offer for use.

Create an Online Offer

Provide the URL where people can redeem the online offer. If an offer needs a discount code, add one generic code for all people to use or upload a file with unique codes. See Unique Codes.

use FacebookAds\Http\RequestInterface;

$params = array(
  'location_type' => 'online',
  'discounts' => array(
    array(
      'type' => 'percentage_off',
      'text' => 'the text description for this offer',
      'value1' => 20,
    ),
    array(
      'type' => 'free_stuff',
      'text' => 'the text description for this offer',
    ),
  ),
  'redemption_link' => '<OFFER_URL>',
  'redemption_code' => 'happysummer2016',
  'details' => 'the details for this specific offer',
  'expiration_time' => (new \DateTime("+10 day"))->getTimestamp(),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/nativeoffers',
  RequestInterface::METHOD_POST,
  $params)->getContent();

// You need to note down this Offer ID to Create Offer Ads
$offer_id = $data['id'];
curl \
  -F 'location_type=online' \
  -F 'discounts=[ 
    { 
      "type": "percentage_off", 
      "text": "the text description for this offer", 
      "value1": 20 
    }, 
    {"type":"free_stuff","text":"the text description for this offer"} 
  ]' \
  -F 'redemption_link=<OFFER_URL>' \
  -F 'redemption_code=happysummer2016' \
  -F 'details=the details for this specific offer' \
  -F 'expiration_time=1518151463' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/nativeoffers

Create a Mobile App Offer

For mobile app offers, set redemption_link to an app store URL, such as https://play.google.com/store/apps/details?id=com.myapps.

Note: A mobile app offer's location_type must be online.

Upload Unique Offer Codes

To upload a file of unique offer codes, post the file through Native Offers edge. Once you upload the file, the ad associated with the offer automatically changes each time a person claims it to show one of your unique codes.

Make sure your file has:

  • One unique code per line with no line breaks
  • 20 or fewer characters per code with no space
  • Only letters, numbers, dashes or underscores allowed
  • 500,000 or fewer unique codes
curl \
  -F 'filename=my_uniquie_codes.csv' \
  -F 'access_token=<ACCESS_TOKEN>' \
 "https://graph.facebook.com/v2.7/<NATIVE_OFFER_ID>/codes"

Create an In-Store Offer

To create an in-store offer, choose the type of code you want: discount code, barcode or no code. You can choose from 7 different barcodes, including QR codes. Anyone can get this barcode scanned from their mobile device at your local store.

Note: Not all scanner technologies can read mobile device screens. If you are unsure, check the documentation for your point of sale hardware.

use FacebookAds\Http\RequestInterface;

$params = array(
  'location_type' => 'offline',
  'barcode_type' => 'QR',
  'barcode_value' => 'happysummer2016',
  'discounts' => array(
    array(
      'type' => 'cash_discount',
      'text' => '10 dollars off',
      'value1' => 10,
    ),
  ),
  'details' => 'the details for this specific offer',
  'expiration_time' =>  (new \DateTime("+10 day"))->getTimestamp(),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/nativeoffers',
  RequestInterface::METHOD_POST,
  $params)->getContent();

$offer_id = $data['id'];
curl \
  -F 'location_type=offline' \
  -F 'barcode_type=QR' \
  -F 'barcode_value=happysummer2016' \
  -F 'discounts=[ 
    { 
      "type": "cash_discount", 
      "text": "10 dollars off", 
      "value1": 10 
    } 
  ]' \
  -F 'details=the details for this specific offer' \
  -F 'expiration_time=1518151462' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/nativeoffers

Create an Offer Ad

After an offer is created, you can promote the offer by injecting the offer ID to Ad object, which had been returned in the previous step. You can retrieve all Offer IDs via Page Nativeoffers.

Create an Ad Campaign

To create a campaign for Offer Ad, use Traffic, Conversion and Store Visits Objectives as the campaign objective.

Create an Mobile App Offer Ad Campaign

To create a Mobile App Offer Ad, use corresponding campaign objectives that advertise on app install and engagement. See App Ads.

Create an Ad Set

To create an ad set for a general offer, specify page_id and offer_id in PROMOTED_OBJECT when creating an Ad Set.

curl -X POST \ -F 'name=My Offer Claim AdSet' \ -F 'lifetime_budget=56000' \ -F 'start_time=2018-07-18T10:58:14-0700' \ -F 'end_time=2018-07-25T10:58:14-0700' \ -F 'campaign_id=<AD_CAMPAIGN_ID>' \ -F 'billing_event=LINK_CLICKS' \ -F 'optimization_goal=LINK_CLICKS' \ -F 'bid_amount=1000' \ -F 'promoted_object={"page_id":"<PAGE_ID>","offer_id":"<OFFER_ID>"}' \ -F 'targeting={"geo_locations":{"countries":["US"]},"genders":[1],"age_min":"25","age_max":"55"}' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.0/act_<AD_ACCOUNT_ID>/adsets
const adsSdk = require('facebook-nodejs-ads-sdk'); const AdAccount = adsSdk.AdAccount; const AdSet = adsSdk.AdSet; let access_token = '<ACCESS_TOKEN>'; let app_secret = '<APP_SECRET>'; let app_id = '<APP_ID>'; let id = '<ID>'; const api = adsSdk.FacebookAdsApi.init(access_token); const showDebugingInfo = true; // Setting this to true shows more debugging info. if (showDebugingInfo) { api.setDebug(true); } const fields = [ ]; const params = { 'name' : 'My Offer Claim AdSet', 'lifetime_budget' : '56000', 'start_time' : '2018-07-16T20:45:36-0700', 'end_time' : '2018-07-23T20:45:36-0700', 'campaign_id' : '<adCampaignLinkClicksID>', 'billing_event' : 'LINK_CLICKS', 'optimization_goal' : 'LINK_CLICKS', 'bid_amount' : '1000', 'promoted_object' : {'page_id':'<pageID>','offer_id':'<offerID>'}, 'targeting' : {'geo_locations':{'countries':['US']},'genders':[1],'age_min':'25','age_max':'55'}, }; (new AdAccount(id)).createAdSet( fields, params ) .then((result) => { adsets_id = result.id; console.log(adsets_id); }) .catch((error) => { console.log(error); });
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\AdSet; use FacebookAds\Api; use FacebookAds\Logger\CurlLogger; $access_token = '<ACCESS_TOKEN>'; $app_secret = '<APP_SECRET>'; $app_id = '<APP_ID>'; $id = '<ID>'; $api = Api::init($app_id, $app_secret, $access_token); $api->setLogger(new CurlLogger()); $fields = array( ); $params = array( 'name' => 'My Offer Claim AdSet', 'lifetime_budget' => '56000', 'start_time' => '2018-07-16T20:45:36-0700', 'end_time' => '2018-07-23T20:45:36-0700', 'campaign_id' => '<adCampaignLinkClicksID>', 'billing_event' => 'LINK_CLICKS', 'optimization_goal' => 'LINK_CLICKS', 'bid_amount' => '1000', 'promoted_object' => array('page_id' => '<pageID>','offer_id' => '<offerID>'), 'targeting' => array('geo_locations' => array('countries' => array('US')),'genders' => array(1),'age_min' => '25','age_max' => '55'), ); echo json_encode((new AdAccount($id))->createAdSet( $fields, $params )->getResponse()->getContent(), JSON_PRETTY_PRINT);
from facebookads.adobjects.adaccount import AdAccount from facebookads.adobjects.adset import AdSet from facebookads.api import FacebookAdsApi access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAdsApi.init(access_token=access_token) fields = [ ] params = { 'name': 'My Offer Claim AdSet', 'lifetime_budget': '56000', 'start_time': '2018-07-16T20:45:36-0700', 'end_time': '2018-07-23T20:45:36-0700', 'campaign_id': '<adCampaignLinkClicksID>', 'billing_event': 'LINK_CLICKS', 'optimization_goal': 'LINK_CLICKS', 'bid_amount': '1000', 'promoted_object': {'page_id':'<pageID>','offer_id':'<offerID>'}, 'targeting': {'geo_locations':{'countries':['US']},'genders':[1],'age_min':'25','age_max':'55'}, } print AdAccount(id).create_ad_set( fields=fields, params=params, )
import com.facebook.ads.sdk.*; import java.io.File; import java.util.Arrays; public class SAMPLE_CODE_EXAMPLE { public static void main (String args[]) throws APIException { String access_token = \"<ACCESS_TOKEN>\"; String app_secret = \"<APP_SECRET>\"; String app_id = \"<APP_ID>\"; String id = \"<ID>\"; APIContext context = new APIContext(access_token).enableDebug(true); new AdAccount(id, context).createAdSet() .setName(\"My Offer Claim AdSet\") .setLifetimeBudget(56000L) .setStartTime(\"2018-07-16T20:45:36-0700\") .setEndTime(\"2018-07-23T20:45:36-0700\") .setCampaignId(\"<adCampaignLinkClicksID>\") .setBillingEvent(AdSet.EnumBillingEvent.VALUE_LINK_CLICKS) .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_LINK_CLICKS) .setBidAmount(1000L) .setPromotedObject(\"{\\"page_id\\":\\"<pageID>\\",\\"offer_id\\":\\"<offerID>\\"}\") .setTargeting( new Targeting() .setFieldAgeMax(55L) .setFieldAgeMin(25L) .setFieldGenders(Arrays.asList(1L)) .setFieldGeoLocations( new TargetingGeoLocation() .setFieldCountries(Arrays.asList(\"US\")) ) ) .execute(); } }
access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAds.configure do |config| config.access_token = access_token config.app_secret = app_secret end ad_account = FacebookAds::AdAccount.get(id) ad_account.adsets.create({ name: 'My Offer Claim AdSet', lifetime_budget: '56000', start_time: '2018-07-16T20:45:36-0700', end_time: '2018-07-23T20:45:36-0700', campaign_id: '<adCampaignLinkClicksID>', billing_event: 'LINK_CLICKS', optimization_goal: 'LINK_CLICKS', bid_amount: '1000', promoted_object: {'page_id':'<pageID>','offer_id':'<offerID>'}, targeting: {'geo_locations':{'countries':['US']},'genders':[1],'age_min':'25','age_max':'55'}, })

Create an Mobile App Offer Ad Set

In the PROMOTED_OBJECT of the ad set, instead of page_id, simply provide application_id and object_store_url for the app. You have to specify the offer_id to be the Mobile App Offer you created. Learn more about App Ads.

Create an Ad

To create an Ad, provide ad creative with the right object story specs.

Include link_data in the AdCreativeObjectStorySpec. The link you provide in link_data must be exactly the same as redemption_link.

curl -X POST \ -F 'name=My New Offers Ad' \ -F 'adset_id=<AD_SET_ID>' \ -F 'creative={"object_story_spec":{"page_id":"<PAGE_ID>","link_data":{"offer_id":"<OFFER_ID>","link":"https:\/\/www.facebook.com\/","message":"Great Deal","name":"30% off","image_hash":"<IMAGE_HASH>"}}}' \ -F 'status=PAUSED' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.0/act_<AD_ACCOUNT_ID>/ads
const adsSdk = require('facebook-nodejs-ads-sdk'); const AdAccount = adsSdk.AdAccount; const Ad = adsSdk.Ad; let access_token = '<ACCESS_TOKEN>'; let app_secret = '<APP_SECRET>'; let app_id = '<APP_ID>'; let id = '<ID>'; const api = adsSdk.FacebookAdsApi.init(access_token); const showDebugingInfo = true; // Setting this to true shows more debugging info. if (showDebugingInfo) { api.setDebug(true); } const fields = [ ]; const params = { 'name' : 'My New Offers Ad', 'adset_id' : '<adSetID>', 'creative' : {'object_story_spec':{'page_id':'<pageID>','link_data':{'offer_id':'<offerID>','link':'https:\/\/www.facebook.com\/','message':'Great Deal','name':'30% off','image_hash':'<imageHash>'}}}, 'status' : 'PAUSED', }; (new AdAccount(id)).createAd( fields, params ) .then((result) => { ads_id = result.id; console.log(ads_id); }) .catch((error) => { console.log(error); });
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\Ad; use FacebookAds\Api; use FacebookAds\Logger\CurlLogger; $access_token = '<ACCESS_TOKEN>'; $app_secret = '<APP_SECRET>'; $app_id = '<APP_ID>'; $id = '<ID>'; $api = Api::init($app_id, $app_secret, $access_token); $api->setLogger(new CurlLogger()); $fields = array( ); $params = array( 'name' => 'My New Offers Ad', 'adset_id' => '<adSetID>', 'creative' => array('object_story_spec' => array('page_id' => '<pageID>','link_data' => array('offer_id' => '<offerID>','link' => 'https:\/\/www.facebook.com\/','message' => 'Great Deal','name' => '30% off','image_hash' => '<imageHash>'))), 'status' => 'PAUSED', ); echo json_encode((new AdAccount($id))->createAd( $fields, $params )->getResponse()->getContent(), JSON_PRETTY_PRINT);
from facebookads.adobjects.adaccount import AdAccount from facebookads.adobjects.ad import Ad from facebookads.api import FacebookAdsApi access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAdsApi.init(access_token=access_token) fields = [ ] params = { 'name': 'My New Offers Ad', 'adset_id': '<adSetID>', 'creative': {'object_story_spec':{'page_id':'<pageID>','link_data':{'offer_id':'<offerID>','link':'https:\/\/www.facebook.com\/','message':'Great Deal','name':'30% off','image_hash':'<imageHash>'}}}, 'status': 'PAUSED', } print AdAccount(id).create_ad( fields=fields, params=params, )
import com.facebook.ads.sdk.*; import java.io.File; import java.util.Arrays; public class SAMPLE_CODE_EXAMPLE { public static void main (String args[]) throws APIException { String access_token = \"<ACCESS_TOKEN>\"; String app_secret = \"<APP_SECRET>\"; String app_id = \"<APP_ID>\"; String id = \"<ID>\"; APIContext context = new APIContext(access_token).enableDebug(true); new AdAccount(id, context).createAd() .setName(\"My New Offers Ad\") .setAdsetId(<adSetID>L) .setCreative( new AdCreative() .setFieldObjectStorySpec( new AdCreativeObjectStorySpec() .setFieldLinkData( new AdCreativeLinkData() .setFieldImageHash(\"<imageHash>\") .setFieldLink(\"https://www.facebook.com/\") .setFieldMessage(\"Great Deal\") .setFieldName(\"30% off\") .setFieldOfferId(\"<offerID>\") ) .setFieldPageId(\"<pageID>\") ) ) .setStatus(Ad.EnumStatus.VALUE_PAUSED) .execute(); } }
access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAds.configure do |config| config.access_token = access_token config.app_secret = app_secret end ad_account = FacebookAds::AdAccount.get(id) ad_account.ads.create({ name: 'My New Offers Ad', adset_id: '<adSetID>', creative: {'object_story_spec':{'page_id':'<pageID>','link_data':{'offer_id':'<offerID>','link':'https:\/\/www.facebook.com\/','message':'Great Deal','name':'30% off','image_hash':'<imageHash>'}}}, status: 'PAUSED', })

Use Video or Carousel Ad Creative

Create Offer Dialog

You can use the Create Offer dialog to provide the Facebook offer creation UI flow in your website. For details about the UI component, see Dialogs.

Set up the Facebook SDK for JavaScript, see:

Then trigger the Create Offer page:

FB.ui({         
  account_id: '<ACCOUNT_ID>',
  display: 'popup',
  method: 'create_offer',
  objective: '<OBJECTIVE>',
  page_id: '<PAGE_ID>',
}, function(response) {
  // callback
});

You can provide these settings for the dialog:

Name Description

account_id

Your ad account ID

display

popup

method

create_offer

objective enum{APP_INSTALLS, CONVERSIONS, LINK_CLICKS, OFFER_CLAIMS, PRODUCT_CATALOG_SALES, STORE_VISITS}

Campaign objective

page_id

Your page ID

The dialog provides this response on success:

Struct {
  id: numeric string,
  success: bool,
}