store_visits
ObjectiveThe store_visits
objective helps advertisers achieve the goal of driving customers into physical stores. Access to this API and Insight API for Store Traffic is on a limited basis only. Please contact your Facebook Representative for access.
Currently available for Facebook Desktop or Mobile.
There are two optimization options available for this objective:
Reach Optimization - Available to all advertisers with access to this API. It optimizes for daily
unique reach and shows Impressions
as the default metric in Ads Manager reporting.
Store Visits Optimization - Available to eligible advertisers. Optimize your ads for the lowest cost per attributed store visit. Increases delivery of your ads to people who are most likely to visit a store. Store visits is the default metric in Ads Manager reports, if available.
To create Dynamic Ads for this objective, your page must use Facebook Locations.
Requirements:
objective
set to STORE_VISITS
.promoted_object
set to the corresponding <PARENT_PAGE_ID>
.promoted_object
and targeting
must contain a place_page_set_id
of a <PAGE_SET_ID>
optimization_goal
must be set to STORE_VISITS
or REACH
billing_event
should be IMPRESSIONS
To create Dynamic Ads with this objective:
PageSet
Facebook uses PageSet
to target ads and uses it as the promoted object in your ad. To create a PageSet
:
PageSet
with the Locations JSONTo create a PageSet, first get all the locations from the parent Facebook Page. <PARENT_PAGE_ID>
is page ID for the parent page for all your child locations. This retrieves all child pages and locations for a parent page and returns the longitude and latitude for each location:
Sample output:
{ "data": [ { "location": { "latitude": 29.173384, "longitude": 48.098807 }, "is_permanently_closed": false, "id": "1788030244802584" }, { "location": { "latitude": 29.303635, "longitude": 47.937725 }, "is_permanently_closed": false, "id": "261533444245300" }, { "location": { "latitude": 29.302303, "longitude": 47.933178 }, "is_permanently_closed": false, "id": "179435399132774" }, { "location": { "latitude": 29.302591, "longitude": 47.931801 }, "is_permanently_closed": false, "id": "1790317704582144" } ], "paging": { "cursors": { "before": "MTc4ODAzMDI0NDgwMjU4NAZDZD", "after": "MTA4MTU4NjU5NjA5MDA4" } } }
Iterate through each entry in the returned results and verify each location is open for business by checking the is_permanently_closed
field.
Get the estimated radius with two GET
requests. Alternatively, you can make a batch API call to generate the values below.
You should make this request using each child page's latitude and longitude from the JSON results. This returns the estimated radius for each location.
You can also batch multiple requests into a single request:
curl \ -F "access_token=<ACCESS_TOKEN>" \ -F "include_headers=false" \ -F "batch=[ { \"method\": \"GET\", \"relative_url\": \"/VERSION/search?type=adradiussuggestion&latitude=29.173384&longitude=48.098807\" }, { \"method\": \"GET\", \"relative_url\": \"/VERSION/search?type=adradiussuggestion&latitude=29.303635&longitude=47.937725\" } ]" \ "https://graph.facebook.com"
Use the radius
and distance_unit
in results from the previous calls and the <CHILD_LOCATION_ID>
as the page_id
, create this JSON; this is the final locations JSON:
[ { "page_id": 1788030244802584, "radius": 1, "distance_unit": "mile" }, { "page_id": 261533444245300, "radius": 1, "distance_unit": "mile" } ]
Pageset
You can now create a PageSet
with the information in your Locations JSON. The maximum number of locations in a PageSet is 10000.
As of v3.3, you can make an asynchronous request to create your PageSet. This enables you to make create large PageSets with more than 1000 locations without experiencing timeouts. YOu can also still use /ad_place_page_sets
for synchronous requests, however you should use asynchronous requests for more than 50 locations.
If you use v3.3 and later, you can also use a metadata
field for your PageSet
. This specifies you want to use a fixed radius per location for your ads delivery, or that you want to reach a certain audience size. If you select the latter, Facebook automatically calculates a radius per location to reach that number of people.
We recommend you use asynchronous requests whenever you create a Pageset with over 50 locations. Make your request to https://graph.facebook.com/VERSION/ad_place_page_set_async_request
:
curl -X POST \ -d 'name=test_2' \ -d 'parent_page=ID_1' \ -d 'pages=[{\'page_id':ID_2}]' \ -d 'metadata={"audience":{"size":5000}}' \ -d 'access_token=<ACCESS_TOKEN>' \ "https://graph.facebook.com/VERSION/AD_ACCOUNT_ID/ad_place_page_sets_async/"
The format for parameters are the same as those you use for synchronous requests. In this example we show the metadata
option set to a desired audience
size, which we describe below. See metadata
for Radiuses This returns an ad_place_page_set_async_request
ID:
{ "id": "405738580111111" }
Later you can query that ID with ads_read
permission to get the PageSet ID:
curl -i -X GET \ "https://graph.facebook.com/VERSION/405738580111111?access_token=ACCESS_TOKEN"
The response looks like this:
{ "id": "405738580111111", "place_page_set": { "id": "555555791481678", "name": "test_2" }, "progress": 1 }
Where progress
is from 0.0
to 1
and 1
means we completed your request and created a PageSet.
metadata
for RadiusesAs of v3.3 we also introduce the metadata
field. This tells Facebook you want to use a fixed radius for your locations or you want Facebook to automatically calculate radiuses per location based on a given audience size. For example, to specify a fixed radius using a synchronous request:
curl -X POST \ -d 'name=test_2' \ -d 'parent_page=238219010666666' \ -d 'pages=[{\'page_id':405936056444444}]' \ -d 'metadata={"fixed_radius":{"value":5,"distance_unit":"mile"}}' \ -d 'access_token=ACCESS_TOKEN' \ "https://graph.facebook.com/VERSION/AD_ACCOUNT_UD/ad_place_page_sets/"
This means you want Facebook to deliver your ad to people within a five-mile radius of all locations in your PageSet. The reponse is your new PageSet ID:
{ "id": "1618547271777777" }
metadata
should be either the fixed
or audience
JSON objects. If you use fixed
, also provide distance_unit
and value
:
{ 'fixed_radius': { 'distance_unit': <distance unit> 'value': <distance> } }
If you use audience
provide this JSON:
{ 'audience': { 'size': <audience size> 'max_radius': { // optional 'distance_unit': <distance unit> 'value': <distance> } } }
Some points to keep in mind if you use metadata
:
locations
however do not specify a radius in it. Alternately if you use the locations
parameter and provide radiuses, you should not also provide it for metadata
.distance
must be either mile
or kilometer
and must be between 0.7
to 50
for mile
or 1
to 80
for kilometer
size
in audience
is number of people in the radius as long as the radius is from 1
to 80
kilometers in length. If you provide max_radius
and actual radius we calculate varies between 1
and max_radius
.audience
for metadata
you must make your request with the asynchronous endpoint: ad_account_ID/ad_place_page_set_async
.You can still use synchronous requests to create a PageSet:
curl -X POST \ -d "name=My Grand Pageset" \ -d "parent_page=<PARENT_PAGE_ID>" \ -d "pages=<LOCATIONS_JSON_STRUCTURE>" \ -d "access_token=<ACCESS_TOKEN>" \ "https://graph.facebook.com/VERSION/act_<AD_ACCOUNT_ID>/ad_place_page_sets/"
This returns a PageSet ID which you use later:
{ "id": <PAGE_SET_ID> }
If the number of pages is too large for a cURL
call, you can create a text file with LOCATIONS_JSON_STRUCTURE
and pass it in to the pages
attribute with this flag: -F "pages=<locations_json_structure.txt"
.
Create a campaign with objective set to STORE_VISITS
and your parent page ID as promoted object.
Create an ad set to contain your ad. See Reference, Ad Set, Reference, Targeting specs and Reference, Page locations.
At delivery time, Facebook invalidates any ads targeting locations more than 50 miles away from the nearest page location, known as local page.
curl \ -F 'name=Store Visits Ad Set' \ -F 'promoted_object={"place_page_set_id":"<PAGE_SET_ID>"}' \ -F 'optimization_goal=STORE_VISITS' \ -F 'billing_event=IMPRESSIONS' \ -F 'is_autobid=true' \ -F 'daily_budget=1000' \ -F 'campaign_id=<CAMPAIGN_ID>' \ -F "targeting={ 'place_page_set_ids': ['<PAGE_SET_ID>'], 'device_platforms': ['mobile','desktop'], 'facebook_positions': ['feed'] }" \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/VERSION/act_<AD_ACCOUNT_ID>/adsets
You can also target by geo_locations
in store visits campaigns. Note you can only either use geo_locations
or place_page_set_ids
in ad set targeting for this objective.
We support all types of geo_location
targeting in Advanced Targeting and Placement, including targeting by countries, cities, and zip codes. You can also select location_types
such as recent
, home
, or travel_in
.
You should still provide place_page_set_id
in the promoted_object
. This page set has to be a page set without any explicit set of locations. See Creating the Pageset with the Locations JSON to create this page set. However in this case, do not pass the parameter pages.
First create a page set you later provide in a promoted object:
curl -X POST \ -d "name=My geo targeting page set" \ -d "parent_page=PARENT_PAGE_ID" \ -d "access_token=ACCESS_TOKEN" \ "https://graph.facebook.com/VERESION/act_AD_ACCOUNT_ID/ad_place_page_sets/"
Note you do not need to provide the parameter pages
as you normally do. Now you can create and ad set with the store visits objective which targets on geo_locations
:
curl \ -F 'name=Store Visits Ad Set' \ -F 'promoted_object={"place_page_set_id":"<PAGE_SET_ID>"}' \ -F 'optimization_goal=STORE_VISITS' \ -F 'billing_event=IMPRESSIONS' \ -F 'is_autobid=true' \ -F 'daily_budget=1000' \ -F 'campaign_id=CAMPAIGN_ID' \ -F "targeting={ 'geo_locations': {"countries":["US"],"location_types": ["home"]}, 'device_platforms': ['mobile','desktop'], 'facebook_positions': ['feed'] }" \ -F 'access_token=ACCESS_TOKEN' \ https://graph.facebook.com/VERSION/act_AD_ACCOUNT_ID/adsets
We automatically deliver ads for the store which is closest to the person viewing your ad.
Creative Template You can dynamically insert creative based on someone's location. Customize your creative using a set of template placeholders, and Facebook replaces the placeholders in your ads at runtime with data from the nearest page location.
Available placeholders:
{{page.hours.today}}
{{page.location.city}}
{{page.location.region}}
{{page.location.postcode}}
{{page.location.street_address}}
{{page.name}}
{{page.phone_number}}
The dynamic_ad_voice
field allows you to control the voice of your ad:
dynamic_ad_voice
is set to DYNAMIC
: Page name and profile picture in your ad post come from the nearest page location.dynamic_ad_voice
is set to STORY_OWNER
: Page name and profile picture in your ad post come from the main page location.You can also dynamically ad call-to-action buttons (CTAs) based on someone's location:
GET_DIRECTIONS
or CALL_NOW
, the CTA value
field is not required. Users will automatically be directed to nearest location or prompted to call the nearest location phone number. MESSAGE_PAGE
is allowed only if dynamic_ad_voice
is set to STORY_OWNER
. Messages will be delivered to the main page.Like Page
button.For details, see Reference, Ad creative
dynamic_ad_voice | type in call_to_action |
---|---|
|
|
|
|
Provide an ad creative using dynamic page name and city:
curl \ -F 'dynamic_ad_voice=DYNAMIC' \ -F 'object_story_spec={ "page_id": "<PARENT_PAGE_ID>", "template_data": { "description": "Ad Description", "link": "<URL>", "message": "Ad Message for {{page.location.city}}", "name": "{{page.name}}", "picture": "<IMAGE_URL>" } }' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/VERSION/act_<AD_ACCOUNT_ID>/adcreatives
To use a map card add a place_data
structure in a attachment in the child_attachments
field for your Ad Creative.
In this example, the map, with a Facebook store locator link is the second item in the child_attachments
array. You must provide have at least one item in addition to the map card:
curl \ -F 'dynamic_ad_voice=DYNAMIC' \ -F 'object_story_spec={ "page_id": "<PARENT_PAGE_ID>", "template_data": { "description": "Ad Description", "link": "<URL>", "message": "Ad Message for {{page.location.city}}", "name": "{{page.name}}", "child_attachments":[ { "description": "Come visit us!", "link": "http://yourweburl.com", "name": "{{page.location.street_address}} - {{page.location.city}}", "call_to_action": { "type":"GET_DIRECTIONS" }, }, { "link": "https://fb.com/store_locator", "name": "Check out our stores.", "place_data": { "type":"DYNAMIC" }, } ] } }' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/VERSION/act_<AD_ACCOUNT_ID>/adcreatives
When you create an Ad, if you set the link
to 'https://fb.com/store_locator' the ad appears with the Store Locator as the link destination.
Create an ad as usual:
curl \ -F 'name=My Ad' \ -F 'adset_id=<AD_SET_ID>' \ -F 'creative={"creative_id":"<CREATIVE_ID>"}' \ -F 'status=PAUSED' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/VERSION/act_<AD_ACCOUNT_ID>/ads
To create ads for Store Visits, your Page and Ad Account must be approved for Store Visit Measurement. Otherwise, an error similar to Reach estimate isn't available because 'store_visit' isn't a valid action type
appears.
Store visits is an estimated metric based on data from users with location services enabled. It ultimately offers store visit measurement and optimization for the Store Visits objective. Store visit measurement is only available for campaigns with the Store Visits objective.
To access the Store Visits metric in Ads Manager or Marketing API you must be whitelisted. Contact your Facebook Representative for access.
Store visits are based on clicks and views to ads using the store visits objective. It's an estimated number of visits to an advertiser's business locations by people who have seen or clicked on each store's ads. You can configure the attribution window; you can choose to customize it based on 1-, 7- or 28-day clicks or views. The ad account's default attribution applies unless you customize the configuration. See Insights API, Attribution Window.
These sections describe features added to:
The features relate to reporting for the following items:
See columns under ENGAGEMENT: ACTIONS
which appear in the reporting interface for Store Visits and the Cost per Store Visit.
Store visit data is only available for business locations that Facebook team confirms as measurable for a campaign.
You can get data on store visits from the Insights API. We provide two additional fields in the general insights calls: cost_per_store_visit_actions
and store_visit_actions
. See Insights, Reference. For example:
Sample output looks like:
{ "data": [ { "cost_per_store_visit_actions": [ { "action_type": "store_visit", "value": "0.193995", } ], "store_visit_actions": [ { "action_type": "store_visit", "value": "93625", } ], "date_start": "2017-12-01", "date_stop": "2017-12-30" } ], "paging": { "cursors": { "before": "AAAAAA", "after": "AAAAAA" } }, "__fb_trace_id__": "aaaaaaaaaaa" }
This result shows the cost per store visit and the estimated value of the store visits. See
Field | Description |
---|---|
point_estimate int32 | The point prediction of the value |