Instant Experiences, formerly Canvas Ads

We recently announced that Canvas is renamed to Instant Experiences, to better reflect the value it delivers for people as a full-screen, post-click destination that loads nearly instantaneously from ads in News Feed. We will soon update the API to reflect this change; in the meantime, consider all references of “canvas” to represent Instant Experience.

You can create Instant Experience campaigns on Facebook and Instagram through the API. By using sight, sound, and motion, the video format allows advertisers to effectively drive both brand and direct response objectives.

You can also add Facebook's ad creation user interface for Instant Experiences to your website using the JavaScript SDK. Learn more about the Instant Experiences Dialog below. You can also preview an Instant Experience ad using the Instant Experiences Dialog.

For Instagram, this API is available on a limited basis. For details and limitations, see Instagram and Instant Experiences. Ads using Instant Experiences are not supported for Facebook Stories.

A Instant Experiences ad has these elements:

  • Header and Footer
  • Carousel
  • Button and Text
  • Photo
  • Video
  • Product set
  • Store Locator

In these examples we show how you can create each element and how they're used to create an Instant Experience. See Clicks to Website: Instant Experiences on Facebook Ads guide for a visual example on each element.

Managing Instant Experiences

To create an ad:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'background_color' => 'FFFFFF',
  'body_element_ids' => array(<CANVAS_PHOTO_ID>),
  'is_hidden' => false,
  'is_published' => false,
  'name' => 'Canvas Name',
);

$data = Api::instance()->call(
  '/' . <PAGE_ID> . '/canvases',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'background_color=FFFFFF' \
  -F 'body_element_ids=["<CANVAS_PHOTO_ID>"]' \
  -F 'is_hidden=' \
  -F 'is_published=' \
  -F 'name=Canvas Name' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvases

To read an ad:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'body_elements',
    'canvas_link',
    'id',
    'is_hidden',
    'is_published',
    'name',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "body_elements", 
    "canvas_link", 
    "id", 
    "is_hidden", 
    "is_published", 
    "name" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ID>

Note, you can only update an unpublished Instant Experience. To update it:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'background_color' => 'FFFFFF',
  'body_element_ids' => array(<CANVAS_PHOTO_ID>),
  'is_hidden' => false,
  'is_published' => false,
  'name' => 'Canvas Name',
);

$data = Api::instance()->call(
  '/' . <CANVAS_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'background_color=FFFFFF' \
  -F 'body_element_ids=["<CANVAS_PHOTO_ID>"]' \
  -F 'is_hidden=' \
  -F 'is_published=' \
  -F 'name=Canvas Name' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ID>

Publishing

To publish your ad:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'is_published' => true,
);

$data = Api::instance()->call(
  '/' . <CANVAS_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'is_published=1' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ID>

If you want to preview your ad before you publish it, you can trigger a notification sent to your phone:

curl \
-F 'user_ids=[USER_ID]' \
-F 'access_token=ACCESS_TOKEN' \
https://graph.facebook.com/VERSION/CANVAS_ID/preview_notifications

Get Page Instant Experiences

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'background_color',
    'body_elements',
    'canvas_link',
    'id',
    'is_hidden',
    'is_published',
    'last_editor',
    'name',
    'owner',
    'update_time',
  ),
);

$data = Api::instance()->call(
  '/' . <PAGE_ID> . '/canvases',
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "background_color", 
    "body_elements", 
    "canvas_link", 
    "id", 
    "is_hidden", 
    "is_published", 
    "last_editor", 
    "name", 
    "owner", 
    "update_time" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvases

To create a header for your ad:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_header' => array(
    'name' => 'Canvas Header Name',
    'background_color' => 'FFFFFF',
    'child_elements' => array(<CANVAS_PHOTO_ID>),
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_header={ 
    "name": "Canvas Header Name", 
    "background_color": "FFFFFF", 
    "child_elements": ["<CANVAS_PHOTO_ID>"] 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

To read an existing header:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'child_elements',
    'id',
    'name',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_HEADER_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "child_elements", 
    "id", 
    "name" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_HEADER_ID>

To update a header:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'name' => 'Canvas Header Name',
  'background_color' => 'FFFFFF',
  'child_elements' => array(<CANVAS_PHOTO_ID>),
);

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_HEADER_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'name=Canvas Header Name' \
  -F 'background_color=FFFFFF' \
  -F 'child_elements=["<CANVAS_PHOTO_ID>"]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_HEADER_ID>

If you want to delete a header:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

To create one:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_footer' => array(
    'name' => 'Canvas Footer Name',
    'child_elements' => array(<CANVAS_BUTTON_ID>),
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_footer={"name":"Canvas Footer Name","child_elements":["<CANVAS_BUTTON_ID>"]}' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

To read an existing footer:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'child_elements',
    'id',
    'name',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_FOOTER_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "child_elements", 
    "id", 
    "name" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_FOOTER_ID>

To update a footer:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'name' => 'Canvas Footer Name',
  'child_elements' => array(<CANVAS_BUTTON_ID>),
);

$data = Api::instance()->call(
  '/'.<CANVAS_ELEMENT_FOOTER_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'name=Canvas Footer Name' \
  -F 'child_elements=["<CANVAS_BUTTON_ID>"]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_FOOTER_ID>

To delete a footer:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

To create a carousel:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_carousel' => array(
    'bottom_padding' => 12,
    'child_elements' => array(
      <CANVAS_PHOTO_ID_1>,
      <CANVAS_PHOTO_ID_2>,
      <CANVAS_PHOTO_ID_3>,
    ),
    'name' => 'Canvas Carousel Name',
    'style' => 'FIT_TO_WIDTH',
    'top_padding' => 12,
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_carousel={ 
    "bottom_padding": 12, 
    "child_elements": [ 
      "<CANVAS_PHOTO_ID_1>", 
      "<CANVAS_PHOTO_ID_2>", 
      "<CANVAS_PHOTO_ID_3>" 
    ], 
    "name": "Canvas Carousel Name", 
    "style": "FIT_TO_WIDTH", 
    "top_padding": 12 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

To read it:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'child_elements',
    'id',
    'name',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_CAROUSEL_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "child_elements", 
    "id", 
    "name" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_CAROUSEL_ID>

To update it:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'bottom_padding' => 12,
  'child_elements' => array(
    <CANVAS_PHOTO_ID_1>,
    <CANVAS_PHOTO_ID_2>,
    <CANVAS_PHOTO_ID_3>,
  ),
  'name' => 'Canvas Carousel Name',
  'style' => 'FIT_TO_WIDTH',
  'top_padding' => 12,
);

$data = Api::instance()->call(
  '/'.<CANVAS_ELEMENT_CAROUSEL_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'bottom_padding=12' \
  -F 'child_elements=[ 
    "<CANVAS_PHOTO_ID_1>", 
    "<CANVAS_PHOTO_ID_2>", 
    "<CANVAS_PHOTO_ID_3>" 
  ]' \
  -F 'name=Canvas Carousel Name' \
  -F 'style=FIT_TO_WIDTH' \
  -F 'top_padding=12' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_CAROUSEL_ID>

To delete it:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

Here are options you can use for a carousel in Instant Experiences:

Name Required or Optional Description

style

Optional

FIT_TO_WIDTH or FIT_TO_HEIGHT

Buttons

To create:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_button' => array(
    'bottom_padding' => 0,
    'button_color' => 'FF000000',
    'button_style' => 'BUTTON_FILLED',
    'font_family' => 'sans-serif',
    'font_size' => 15,
    'line_height' => 1,
    'name' => 'Canvas Button Name',
    'open_url_action' => array('url' => '<URL>'),
    'rich_text' => array('plain_text' => 'Click Me'),
    'text_alignment' => 'CENTER',
    'text_color' => 'FF777777',
    'top_padding' => 0,
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_button={ 
    "bottom_padding": 0, 
    "button_color": "FF000000", 
    "button_style": "BUTTON_FILLED", 
    "font_family": "sans-serif", 
    "font_size": 15, 
    "line_height": 1, 
    "name": "Canvas Button Name", 
    "open_url_action": {"url":"<URL>"}, 
    "rich_text": {"plain_text":"Click Me"}, 
    "text_alignment": "CENTER", 
    "text_color": "FF777777", 
    "top_padding": 0 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

To read:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'action',
    'id',
    'name',
    'rich_text',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_BUTTON_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "action", 
    "id", 
    "name", 
    "rich_text" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_BUTTON_ID>

To update a button:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'bottom_padding' => 0,
  'button_color' => 'FF000000',
  'button_style' => 'BUTTON_FILLED',
  'font_family' => 'sans-serif',
  'font_size' => 15,
  'line_height' => 1,
  'name' => 'Canvas Button Name',
  'open_url_action' => array('url' => '<URL>'),
  'rich_text' => array('plain_text' => 'Click Me'),
  'text_alignment' => 'CENTER',
  'text_color' => 'FF777777',
  'top_padding' => 0,
);

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_BUTTON_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'bottom_padding=0' \
  -F 'button_color=FF000000' \
  -F 'button_style=BUTTON_FILLED' \
  -F 'font_family=sans-serif' \
  -F 'font_size=15' \
  -F 'line_height=1' \
  -F 'name=Canvas Button Name' \
  -F 'open_url_action={"url":"<URL>"}' \
  -F 'rich_text={"plain_text":"Click Me"}' \
  -F 'text_alignment=CENTER' \
  -F 'text_color=FF777777' \
  -F 'top_padding=0' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_BUTTON_ID>

To delete a button:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

Here are options you can use for buttons:

Name Required or Optional Description

button_style

Required

BUTTON_OUTLINE, BUTTON_FILLED

Text

To create text:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_text' => array(
    'name' => 'Canvas Text Name',
      'rich_text' => array(
        'plain_text' => 'Canvas Text',
        'inline_styles' => array(
          array('offset' => 10, 'length' => 9, 'style' => 'underline'),
          array('offset' => 20, 'length' => 9, "style" => 'bold'),
       ),
     ),
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_text={ 
    "name": "Canvas Text Name", 
    "rich_text": { 
      "plain_text": "Canvas Text", 
      "inline_styles": [ 
        { 
          "offset": 10, 
          "length": 9, 
          "style": "underline" 
        }, 
        { 
          "offset": 20, 
          "length": 9, 
          "style": "bold" 
        } 
      ] 
    } 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

To read text:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'id',
    'name',
    'rich_text',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_TEXT_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "id", 
    "name", 
    "rich_text" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_TEXT_ID>

To update existing text:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'name' => 'Canvas Text Name',
    'rich_text' => array(
      'plain_text' => 'Canvas Text',
      'inline_styles' => array(
        array('offset' => 10, 'length' => 9, 'style' => 'underline'),
        array('offset' => 20, 'length' => 9, "style" => 'bold'),
     ),
   ),
);

$data = Api::instance()->call(
  '/'.<CANVAS_ELEMENT_TEXT_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'name=Canvas Text Name' \
  -F 'rich_text={ 
    "plain_text": "Canvas Text", 
    "inline_styles": [ 
      { 
        "offset": 10, 
        "length": 9, 
        "style": "underline" 
      }, 
      { 
        "offset": 20, 
        "length": 9, 
        "style": "bold" 
      } 
    ] 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_TEXT_ID>

To delete text:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

Photos

You should provide a PHOTO_ID for a photo uploaded to a Facebook Page.

To create a photo:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_photo' => array(
    'bottom_padding' => 20,
    'name' => 'Canvas Photo Name',
    'open_url_action' => array('url' => '<URL>'),
    'photo_id' => <PHOTO_ID>,
    'style' => 'FIT_TO_WIDTH',
    'top_padding' => 20,
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_photo={ 
    "bottom_padding": 20, 
    "name": "Canvas Photo Name", 
    "open_url_action": {"url":"<URL>"}, 
    "photo_id": "<PHOTO_ID>", 
    "style": "FIT_TO_WIDTH", 
    "top_padding": 20 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

To read one:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'action',
    'id',
    'name',
    'photo',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_PHOTO_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "action", 
    "id", 
    "name", 
    "photo" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_PHOTO_ID>

To update a photo:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'bottom_padding' => 20,
  'name' => 'Canvas Photo Name',
  'open_url_action' => array('url' => '<URL>'),
  'photo_id' => <PHOTO_ID>,
  'top_padding' => 20,
);

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_PHOTO_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'bottom_padding=20' \
  -F 'name=Canvas Photo Name' \
  -F 'open_url_action={"url":"<URL>"}' \
  -F 'photo_id=<PHOTO_ID>' \
  -F 'top_padding=20' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_PHOTO_ID>

To delete a photo:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

Options for photos include:

Name Required or Optional Description

style

Optional

FIT_TO_WIDTH, FIT_TO_WIDTH_EXPANDABLE, FIT_TO_HEIGHT

Using Photos with Product Tags

Create an ads experience that mimics browsing a printed, lifestyle catalog featuring desired products to promote. You can tag featured products in the image and a tag appears on the image.

This API is available on a limited basis to white-listed partners and advertisers. Contact your Facebook representative if you want to use this API.

When someone taps the tag, a thumbnail for that product appears in a rotating group of thumbnails, including all tagged products. Someone can tap the thumbnail to be taken to the product's product detail page. This uses the photo with product tags element API. For example:

curl 
  -F 'canvas_photo={ 
    "bottom_padding": 20, 
    "name": "Instant Experience Photo Name", 
    "open_url_action": {"url":"URL"}, 
    "photo_id": "PHOTO_ID", 
    "style": "FIT_TO_WIDTH", 
    "top_padding": 20,
    "product_tags": "[{product_id: PRODUCT_ID, coordinates: [0.65, 0.58]}, {product_id: PRODUCT_ID}]" 
  }' 
  }' 
  -F 'access_token=ACCESS_TOKEN' 
  https://graph.facebook.com/VERSION/PAGE_ID/canvas_elements

The options available for product tags are:

Field Name Description Type Required

product_tags

Provide a list of products for the photo

array

Yes

product_id

Product id for tapped photo

number

Yes

coordinates

Spot coordinates on the photo.

array, where x and y greater than zero and less than 1

No. If none specified, there is no spot on the photo

To read this:

curl -G 
  --data-urlencode 'fields=[ 
    "action", 
    "id", 
    "name", 
    "photo",
    "product_tags"
  ]' 
  -d 'access_token=ACCESS_TOKEN' 
  https://graph.facebook.com/VERSION/CANVAS_PHOTO_ID

And to update it:

curl \
  -F 'bottom_padding=20' \
  -F 'name=Instant Experience Photo Name' \
  -F 'open_url_action={"url":"URL"}' \
  -F 'photo_id=PHOTO_ID' \
  -F 'top_padding=20' \
  -F 'product_tags=[{product_id: PRODUCT_ID, coordinates: [0.65, 0.58]}, {product_id: PRODUCT_ID}]' \
  -F 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/CANVAS_ELEMENT_PHOTO_ID

If you want delete your tag:

curl -X DELETE 
  -d 'access_token=ACCESS_TOKEN' 
  https://graph.facebook.com/VERSION/CANVAS_ELEMENT_ID

Videos

You should provide a VIDEO_ID which refers to a video uploaded to a page.

To create an Instant Experience ad with a video:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_video' => array(
    'bottom_padding' => 24,
    'name' => 'Canvas Video Name',
    'style' => 'FIT_TO_WIDTH',
    'top_padding' => 24,
    'video_id' => <VIDEO_ID>,
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_video={ 
    "bottom_padding": 24, 
    "name": "Canvas Video Name", 
    "style": "FIT_TO_WIDTH", 
    "top_padding": 24, 
    "video_id": "<VIDEO_ID>" 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

Options for videos include:

Name Required or Optional Description

style

Optional

FIT_TO_WIDTH, FIT_TO_HEIGHT

To read an Instant Experience video ad:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'id',
    'name',
    'video',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_VIDEO_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "id", 
    "name", 
    "video" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_VIDEO_ID>

To update one:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'bottom_padding' => 20,
  'name' => 'Canvas Video Name',
  'style' => 'FIT_TO_WIDTH',
  'top_padding' => 20,
  'video_id' => <VIDEO_ID>,
);

$data = Api::instance()->call(
  '/'.<CANVAS_ELEMENT_VIDEO_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'bottom_padding=20' \
  -F 'name=Canvas Video Name' \
  -F 'style=FIT_TO_WIDTH' \
  -F 'top_padding=20' \
  -F 'video_id=<VIDEO_ID>' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_VIDEO_ID>

To delete one:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

Product Sets

Display products from a Dynamic Ads product catalog. For example:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_product_set' => array(
    'bottom_padding' => 8,
    'max_items' => 6,
    'name' => 'Canvas Product Set Name',
    'product_set_id' => <PRODUCT_SET_ID>,
    'top_padding' => 24,
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_product_set={ 
    "bottom_padding": 8, 
    "max_items": 6, 
    "name": "Canvas Product Set Name", 
    "product_set_id": "<PRODUCT_SET_ID>", 
    "top_padding": 24 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

To read one:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'id',
    'name',
    'product_set_id',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_PRODUCT_SET_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  --data-urlencode 'fields=[ 
    "id", 
    "name", 
    "product_set_id" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_PRODUCT_SET_ID>

To update the ad:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'bottom_padding' => 8,
  'max_items' => 6,
  'name' => 'Canvas Product Set Name',
  'product_set_id' => <PRODUCT_SET_ID>,
  'top_padding' => 24,
);

$data = Api::instance()->call(
  '/'.<CANVAS_ELEMENT_PRODUCT_SET_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'bottom_padding=8' \
  -F 'max_items=6' \
  -F 'name=Canvas Product Set Name' \
  -F 'product_set_id=<PRODUCT_SET_ID>' \
  -F 'top_padding=24' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_PRODUCT_SET_ID>

To delete it:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

To create a product set used in Collection ads from a set of products in Dynamic Ads:

curl \
  -F 'canvas_product_set={ 
    "bottom_padding": 8, 
    "max_items": 50, 
    "name": "Collection Product Set Name", 
    "product_set_id": "PRODUCT_SET_ID",
    "show_in_feed": true,
    "item_headline": "See more at {{product.brand | titleize}}",
    "item_description": "{{product.price}}",
    "retailer_item_ids": [
       "RETAILER_ID_1", 
       "RETAILER_ID_2", 
       "RETAILER_ID_3", 
       "RETAILER_ID_4",
    ], 
    "top_padding": 24 
  }' \
  -F 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/PAGE_ID/canvas_elements

Product Lists

Select a product catalog and then manually provide the product ID, name and color variations to promote in a collection's ad creative. Use this option if you or your advertiser does not want to set-up a product set from a catalog feed. This option makes creating of ads from product catalog simpler. Note that we do not save selected products as a product set for later reuse.

Use this option to select which item colors you want to show in an ad and control the order products appear. Because this is a manual ordering, we do not dynamically rank or display products based on popularity or relevancy to each viewer.

Only E-commerce and travel hotel vertical catalogs are currently supported.

To create a product list:

curl \
  -F 'canvas_product_list={ 
    "bottom_padding": 20, 
    "name": "Product List Name", 
    "product_id_list": "[product_id_1, product_id_2, product_id_3, product_id_4]",
    "item_headline": "See more at {{product.brand | titleize}}",
    "item_description": "{{product.price}}",
    "top_padding": 20 
  }' \
  -F 'access_token=TOKEN' \
  https://graph.facebook.com/VERSION/PAGE_ID/canvas_elements
  

To read one:

curl -G \--data-urlencode 'fields=[
"name",
"product_id_list"
]' \-d 'access_token=TOKEN' \
https://graph.facebook.com/VERSION/PRODUCT_LIST_ELEMENT_ID
  

To update one:

curl \
  -F 'bottom_padding=8' \
  -F 'name=Product List Name' \
  -F 'product_id_list=[product_id_1, product_id_2, product_id_3, product_id_4]' \
  -F 'item_headline=See more at {{product.url}}' \
  -F 'item_description={{product.current_price}}' \
  -F 'top_padding=24' \
  -F 'access_token=TOKEN' \
  https://graph.facebook.com/VERSION/CANVAS_ELEMENT_PRODUCT_LIST_ID
  

To delete it:

curl -X DELETE \
  -d 'access_token=TOKEN' \
  https://graph.facebook.com/VERSION/CANVAS_ELEMENT_ID
  

The options available for product lists are:

Field NameDescriptionTypeRequired

product_id_list

Provide a list of products for the element

array

Yes. Must be more than four IDs. IDs must be from Dynamic Ads product catalog or Dynamic Ads for Travel, hotel catalog

Instant Experiences Store Locator

Provide a store locator in your Instant Experience. For example:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'canvas_store_locator' => array(
    'header_background_color' => 'FF000000',
    'name' => 'Canvas Store Locator Name',
    'page_set_id' => <PLACE_PAGE_SET_ID>,
    'typeface' => 'HelveticaNeue-Light',
  ),
);

$data = Api::instance()->call(
  '/'.<PAGE_ID>.'/canvas_elements',
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'canvas_store_locator={ 
    "header_background_color": "FF000000", 
    "name": "Canvas Store Locator Name", 
    "page_set_id": "<PLACE_PAGE_SET_ID>", 
    "typeface": "HelveticaNeue-Light" 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PAGE_ID>/canvas_elements

To read it:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'fields' => array(
    'id',
    'name',
  ),
);

$data = Api::instance()->call(
  '/' . <CANVAS_STORE_LOCATOR_ID>,
  RequestInterface::METHOD_GET,
  $params)->getContent();
curl -G \
  -d 'fields=["id","name"]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_STORE_LOCATOR_ID>

To change it:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$params = array(
  'header_background_color' => 'FF000000',
  'name' => 'Canvas Store Locator Name',
  'page_set_id' => <PLACE_PAGE_SET_ID>,
  'typeface' => 'HelveticaNeue-Light',
);

$data = Api::instance()->call(
  '/'.<CANVAS_ELEMENT_STORE_LOCATOR_ID>,
  RequestInterface::METHOD_POST,
  $params)->getContent();
curl \
  -F 'header_background_color=FF000000' \
  -F 'name=Canvas Store Locator Name' \
  -F 'page_set_id=<PLACE_PAGE_SET_ID>' \
  -F 'typeface=HelveticaNeue-Light' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_STORE_LOCATOR_ID>

To delete it:

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;

$data = Api::instance()->call(
  '/' . <CANVAS_ELEMENT_ID>,
  RequestInterface::METHOD_DELETE,
  array())->getContent();
curl -X DELETE \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<CANVAS_ELEMENT_ID>

Creating Instant Experiences

In this example we create an Instant Experience ad using an existing ID. First we provide ad creative for the Instant Experience:

curl -X POST \ -F 'image_hash="<IMAGE_HASH>"' \ -F 'object_story_spec={ "page_id": "<PAGE_ID>", "link_data": { "image_hash": "<IMAGE_HASH>", "link": "<CANVAS_LINK>", "name": "Creative message", "call_to_action": { "type": "LEARN_MORE" } } }' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.1/act_<AD_ACCOUNT_ID>/adcreatives
const adsSdk = require('facebook-nodejs-ads-sdk'); const AdAccount = adsSdk.AdAccount; const AdCreative = adsSdk.AdCreative; 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 logApiCallResult = (apiCallName, data) => { console.log(apiCallName); if (showDebugingInfo) { console.log('Data:' + JSON.stringify(data)); } }; let fields, params; fields = [ ]; params = { 'image_hash' : '<imageHash>', 'object_story_spec' : {'page_id':'<pageID>','link_data':{'image_hash':'<imageHash>','link':'<canvasURI>','name':'Creative message','call_to_action':{'type':'LEARN_MORE'}}}, }; let adcreatives = (new AdAccount(id)).createAdCreative( fields, params ); logApiCallResult('adcreatives api call complete.', adcreatives);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\AdCreative; 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( 'image_hash' => '<imageHash>', 'object_story_spec' => array('page_id' => '<pageID>','link_data' => array('image_hash' => '<imageHash>','link' => '<canvasURI>','name' => 'Creative message','call_to_action' => array('type' => 'LEARN_MORE'))), ); echo json_encode((new AdAccount($id))->createAdCreative( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebookads.adobjects.adaccount import AdAccount from facebookads.adobjects.adcreative import AdCreative 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 = { 'image_hash': '<imageHash>', 'object_story_spec': {'page_id':'<pageID>','link_data':{'image_hash':'<imageHash>','link':'<canvasURI>','name':'Creative message','call_to_action':{'type':'LEARN_MORE'}}}, } print AdAccount(id).create_ad_creative( 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).createAdCreative() .setImageHash(\"<imageHash>\") .setObjectStorySpec( new AdCreativeObjectStorySpec() .setFieldLinkData( new AdCreativeLinkData() .setFieldCallToAction( new AdCreativeLinkDataCallToAction() .setFieldType(AdCreativeLinkDataCallToAction.EnumType.VALUE_LEARN_MORE) ) .setFieldImageHash(\"<imageHash>\") .setFieldLink(\"<canvasURI>\") .setFieldName(\"Creative message\") ) .setFieldPageId(\"<pageID>\") ) .execute(); } }
require 'facebook_ads' 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) adcreatives = ad_account.adcreatives.create({ image_hash: '<imageHash>', object_story_spec: {'page_id':'<pageID>','link_data':{'image_hash':'<imageHash>','link':'<canvasURI>','name':'Creative message','call_to_action':{'type':'LEARN_MORE'}}}, })

Then we create an ad:

curl -X POST \ -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/v3.1/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 logApiCallResult = (apiCallName, data) => { console.log(apiCallName); if (showDebugingInfo) { console.log('Data:' + JSON.stringify(data)); } }; let fields, params; fields = [ ]; params = { 'name' : 'My Ad', 'adset_id' : '<adSetID>', 'creative' : {'creative_id':'<adCreativeID>'}, 'status' : 'PAUSED', }; let ads = (new AdAccount(id)).createAd( fields, params ); logApiCallResult('ads api call complete.', ads);
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 Ad', 'adset_id' => '<adSetID>', 'creative' => array('creative_id' => '<adCreativeID>'), 'status' => 'PAUSED', ); echo json_encode((new AdAccount($id))->createAd( $fields, $params )->exportAllData(), 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 Ad', 'adset_id': '<adSetID>', 'creative': {'creative_id':'<adCreativeID>'}, '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 Ad\") .setAdsetId(<adSetID>L) .setCreative( new AdCreative() .setFieldId(\"<adCreativeID>\") ) .setStatus(Ad.EnumStatus.VALUE_PAUSED) .execute(); } }
require 'facebook_ads' 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) ads = ad_account.ads.create({ name: 'My Ad', adset_id: '<adSetID>', creative: {'creative_id':'<adCreativeID>'}, status: 'PAUSED', })

We create an ad set:

curl -X POST \ -F 'name="My Reach Ad Set"' \ -F 'optimization_goal="REACH"' \ -F 'billing_event="IMPRESSIONS"' \ -F 'bid_amount=2' \ -F 'daily_budget=1000' \ -F 'campaign_id="<AD_CAMPAIGN_ID>"' \ -F 'targeting={ "geo_locations": { "countries": [ "US" ] } }' \ -F 'status="PAUSED"' \ -F 'promoted_object={ "page_id": "<PAGE_ID>" }' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.1/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 logApiCallResult = (apiCallName, data) => { console.log(apiCallName); if (showDebugingInfo) { console.log('Data:' + JSON.stringify(data)); } }; let fields, params; fields = [ ]; params = { 'name' : 'My Reach Ad Set', 'optimization_goal' : 'REACH', 'billing_event' : 'IMPRESSIONS', 'bid_amount' : '2', 'daily_budget' : '1000', 'campaign_id' : '<adCampaignLinkClicksID>', 'targeting' : {'geo_locations':{'countries':['US']}}, 'status' : 'PAUSED', 'promoted_object' : {'page_id':'<pageID>'}, }; let adsets = (new AdAccount(id)).createAdSet( fields, params ); logApiCallResult('adsets api call complete.', adsets);
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 Reach Ad Set', 'optimization_goal' => 'REACH', 'billing_event' => 'IMPRESSIONS', 'bid_amount' => '2', 'daily_budget' => '1000', 'campaign_id' => '<adCampaignLinkClicksID>', 'targeting' => array('geo_locations' => array('countries' => array('US'))), 'status' => 'PAUSED', 'promoted_object' => array('page_id' => '<pageID>'), ); echo json_encode((new AdAccount($id))->createAdSet( $fields, $params )->exportAllData(), 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 Reach Ad Set', 'optimization_goal': 'REACH', 'billing_event': 'IMPRESSIONS', 'bid_amount': '2', 'daily_budget': '1000', 'campaign_id': '<adCampaignLinkClicksID>', 'targeting': {'geo_locations':{'countries':['US']}}, 'status': 'PAUSED', 'promoted_object': {'page_id':'<pageID>'}, } 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 Reach Ad Set\") .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH) .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS) .setBidAmount(2L) .setDailyBudget(1000L) .setCampaignId(\"<adCampaignLinkClicksID>\") .setTargeting( new Targeting() .setFieldGeoLocations( new TargetingGeoLocation() .setFieldCountries(Arrays.asList(\"US\")) ) ) .setStatus(AdSet.EnumStatus.VALUE_PAUSED) .setPromotedObject(\"{\\"page_id\\":\\"<pageID>\\"}\") .execute(); } }
require 'facebook_ads' 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) adsets = ad_account.adsets.create({ name: 'My Reach Ad Set', optimization_goal: 'REACH', billing_event: 'IMPRESSIONS', bid_amount: '2', daily_budget: '1000', campaign_id: '<adCampaignLinkClicksID>', targeting: {'geo_locations':{'countries':['US']}}, status: 'PAUSED', promoted_object: {'page_id':'<pageID>'}, })

Finally we create a campaign:

curl -X POST \ -F 'name="My campaign"' \ -F 'objective="LINK_CLICKS"' \ -F 'status="PAUSED"' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.0/act_<AD_ACCOUNT_ID>/campaigns
const adsSdk = require('facebook-nodejs-ads-sdk'); const AdAccount = adsSdk.AdAccount; const Campaign = adsSdk.Campaign; 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 logApiCallResult = (apiCallName, data) => { console.log(apiCallName); if (showDebugingInfo) { console.log('Data:' + JSON.stringify(data)); } }; let fields, params; fields = [ ]; params = { 'name' : 'My campaign', 'objective' : 'LINK_CLICKS', 'status' : 'PAUSED', }; let campaigns = (new AdAccount(id)).createCampaign( fields, params ); logApiCallResult('campaigns api call complete.', campaigns);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\Campaign; 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 campaign', 'objective' => 'LINK_CLICKS', 'status' => 'PAUSED', ); echo json_encode((new AdAccount($id))->createCampaign( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebookads.adobjects.adaccount import AdAccount from facebookads.adobjects.campaign import Campaign 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 campaign', 'objective': 'LINK_CLICKS', 'status': 'PAUSED', } print AdAccount(id).create_campaign( 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).createCampaign() .setName(\"My campaign\") .setObjective(Campaign.EnumObjective.VALUE_LINK_CLICKS) .setStatus(Campaign.EnumStatus.VALUE_PAUSED) .execute(); } }
require 'facebook_ads' 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) campaigns = ad_account.campaigns.create({ name: 'My campaign', objective: 'LINK_CLICKS', status: 'PAUSED', })

Using Templates

You can use a template as quick way to create an Instant Experience for a specific business goal. The layout for each template is fixed, however you can replace default content with your own images, videos, products, text and links.

This API is available on a limited basis to white-listed partners and advertisers. Contact your Facebook representative if you want to use this API

Facebook has several templates in our ads tools: "Instant Customer Acquisition", "Instant Storytelling", "Instant Storefront", "Instant Lookbook". See these examples to retrieve template contents via the API. You can use this to construct templates in your own tools.

Template ID Template

133471657203838

Instant Customer Acquisition, formerly 'Get New Customers'

1063217037112304

Instant Storytelling, formerly 'Showcase Your Business'

424787857903852

Instant Storefront, formerly 'Sell Products'

1369752616394017

Instant Lookbook, formerly 'Sell Products, Lifestyle Layout'

1932289657009030

Instant Storefront, formerly 'Sell Products, Grid'

First get the body elements, for example, get them from a 'Instant Customer Acquisition' template:

curl -G \
  --data-urlencode 'fields=[  
    "name", 
    "body_elements",
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/TEMPLATE_ID

Returns:

{
 "name": "Instant Customer Acquisition", 
"body_elements": [
 {
 "name": "Cover Image or Video", "element_type": "PHOTO", "id": "ELEMENT_ID" }, 
{
 "name": "Text", "element_type": "RICH_TEXT", "id": "ELEMENT_ID" 
}, {
 "name": "Text", "element_type": "RICH_TEXT", "id": "ELEMENT_ID" 
}, {
 "name": "Button", "element_type": "BUTTON", "id": "ELEMENT_ID" 
}, {
 "name": "Carousel", "element_type": "CAROUSEL", "id": "ELEMENT_ID" 
}
....
], 
"id": "TEMPLATE_ID",
}

Now you can then get element content, for example you can get a photo element:

curl -G \
  --data-urlencode 'fields=[ 
    "action", 
    "name", 
    "photo" 
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/ELEMENT_ID 

To retrieve a RICH_TEXT element:

curl -G \
  --data-urlencode 'fields=[
    "name", 
    "rich_text" 
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/ELEMENT_ID 

To retrieve a CAROUSEL element:

curl -G \
  --data-urlencode 'fields=[ 
    "name", 
    "child_elements",
    "style" 
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/ELEMENT_ID

To get a button element:

curl -G \
  --data-urlencode 'fields=[  
    "name", 
    "action", 
    "rich_text",
    "text_alignment",
    "text_color",
    "font_size",
    "button_color",
    "button_style",
    "background_color",
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/ELEMENT_ID

Template Examples

Here are additional examples that demonstrate how you can retrieve template content. To get body elements for "Instant Storytelling":

curl -G \
  --data-urlencode 'fields=[  
    "name", 
    "body_elements",
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/TEMPLATE_ID

This returns all elements:

{
 "name": "Instant Storytelling", 
"body_elements": [
 {
 "name": "Cover Image or Video", "element_type": "VIDEO", "id": "ELEMENT_ID" }, {
 "name": "Text", "element_type": "RICH_TEXT", "id": "ELEMENT_ID"
 }, {
 "name": "Image or Video", "element_type": "PHOTO", "id": "ELEMENT_ID" 
}, {
 "name": "Carousel", "element_type": "CAROUSEL", "id": "ELEMENT_ID" 
}, {
 "name": "Text", "element_type": "RICH_TEXT", "id": "ELEMENT_ID" 
}, {
 "name": "Image or Video", "element_type": "PHOTO", "id": "ELEMENT_ID" 
}, {
 "name": "Button", "element_type": "BUTTON", "id": "ELEMENT_ID" 
} 
], "id": "ELEMENT_ID"
}

Now you can get content for a specific element, such as the video:

curl -G \
  --data-urlencode 'fields=[ 
    "name", 
    "video" 
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/ELEMENT_ID

To get body elements for a "Sell Products" template:

curl -G \
  --data-urlencode 'fields=[  
    "name", 
    "body_elements",
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/TEMPLATE_ID

This returns:

{
 "name": "Instant Storefront", 
"body_elements": [
 {
 "name": "Cover Image or Video", "element_type": "PHOTO", "id": "1867119740170572 (https://developers.facebook.com/tools/explorer/ELEMENT_ID" }, {
 "name": "Text", "element_type": "RICH_TEXT", "id": "ELEMENT_ID" 
}, ....
], 
"id": "TEMPLATE_ID", 
}

To get body elements for a "Instant Lookbook" template:

curl -G \
  --data-urlencode 'fields=[  
    "name", 
    "body_elements",
  ]' \
  -d 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/TEMPLATE_ID

Results:

{
 "name": "Instant Storefront", 
"body_elements": [
 {
 "name": "Cover Image or Video", "element_type": "VIDEO", "id": "ELEMENT_ID" }, {
 "name": "Headline", "element_type": "RICH_TEXT", "id": "ELEMENT_ID" 
}, 
....
], 
"id": "TEMPLATE ID"
}

Once you have element IDs for your template, you can get content for the element. For example, to get content for a photo element, including product tags:

curl -G \
--data-urlencode 'fields=[
"name",
"action",
"photo" ,
"product_tags"
]' \
-d 'access_token=ACCESS_TOKEN' \
https://graph.facebook.com/VERSION/ELEMENT_ID

Engagement Audiences for Instant Experiences

Automatically create audiences for people who engaged with an Instant Experience, this is known as an engagement audience.

Create an engagement audience by creating a custom audience with subtype set to ENGAGEMENT, object_id to the <CANVAS_ID>, and the rule to track one of the following events:

People who opened the Instant Experience

curl \
  -F 'name=Instant Experience Engagement Audience' \
  -F 'subtype=ENGAGEMENT' \
  -F 'description=People who opened this Instant Experience' \
  -F 'rule=[{"object_id":"<CANVAS_ID>","event_name":"instant_shopping_document_open"}]' \
  -F 'access_token=<ACCESS_TOKEN>' \  
https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/customaudiences

People who clicked any links in the Instant Experience

curl \
  -F 'name=Instant Experience Engagement Audience' \
  -F 'subtype=ENGAGEMENT' \
  -F 'description=People who clicked any links in this Instant Experience' \
  -F 'rule=[{"object_id":"<CANVAS_ID>","event_name":"instant_shopping_element_click"}]' \
  -F 'access_token=<ACCESS_TOKEN>' \  
https://graph.facebook.com/<VERSION>/act_<AD_ACCOUNT_ID>/customaudiences

For more information about custom audiences, see Custom Audience, Reference.

Instant Experiences and Instagram Ads

Implementing Instant Experiences with Instagram uses the same API calls you use for Instant Experience on Facebook. Note there are limitations when you use Instagram and Instant Experiences:

  • Placements - Available for Instagram Feed and Instagram Stories. If you select Instagram Stories, you should select this as your exclusive ads placement.
  • Instant Experience Elements - Fully supports headers and product sets.

We partially support these Instant Experience elements on Instagram:

  • Footer - No swipe to open in clients this renders as Tap to open.
  • Carousel - No photos that link to another Instant Experience; in the client appears as a non-clickable link. For photos and videos, no fit to height, no fit to width or tilt to pan; this renders as fit to width.
  • Button - Cannot link to another Instant Experience or to the App Store.
  • Text - No RTL language support.
  • Video - No 360 videos.
  • Store Locators - Not supported.
  • Instant Forms, used for lead generation - Not supported.

Instant Experiences and Lead Generation

You can include an instant form for lead generation, in Instant Experience ad campaigns that you run with BRAND_AWARENESS, REACH and traffic objectives. In doing so you can collect contact information from prospective customers. For details and background see, Ads Help Center, Collect leads using Instant Forms.

This API is currently under limited availability. Contact your Facebook Representative for access.

To use this feature:

  • Create a new instant form with is_for_canvas set to true.
  • Create an instant form element using your new form.
  • Create an Instant Experience with the instant form element.

First, create a new instant form with is_for_canvas param. With this setting, you can create the instant form, otherwise you will get an error. See Lead Ads, Creating. For example:

curl \
 -F 'name=LeadAds Form Name' \
 -F 'follow_up_action_url=<URL>' \
 -F 'questions=[{"type":"EMAIL"}]' \
 -F 'context_card_id=<CONTEXT_CARD_ID>' \
 -F 'legal_content_id=<LEGAL_CONTENT_ID>' \
 -F 'is_for_canvas=true' \
 -F 'access_token=<ACCESS_TOKEN>' \
 https://graph.facebook.com/<VERSION>/<PAGE_ID>/leadgen_forms

Then create a new instant form element using the new form. Note you can only use this form to create one instant form element, not more. For example:

curl \
  -F 'canvas_lead_form={ 
    "name": "Instant Experience LeadGen Form Name", 
    "leadgen_data_id": <LEADGEN_FORM_ID>
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/<VERSION>/<PAGE_ID>/canvas_elements

Create an Instant Experience with the instant form element. Again, you can only use this element in one Instant Experience. After you create an Instant Experience containing this form, you can see the form element under Instant Experiences for your Page publishing tools. Or you can read the form element via the API:

curl -G \
  --data-urlencode 'fields=[ 
    "id",
    "name" 
  ]' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/<VERSION>/<CANVAS_LEADGEN_FORM_ID>

Updating the form element is similar to updating other elements such as a store locator:

curl \
  -F 'canvas_lead_form={ 
    "name": "Instant Experience LeadGen Form Name", 
    "leadgen_data_id": <NEW_LEADGEN_FORM_ID>
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/<VERSION>/<PAGE_ID>/canvas_elements

Note that you cannot delete an instant form element.

Ad Insights

See Ad Insights for an overview and descriptions for available metrics.

Instant Experiences Ads Dialog

You can use the Instant Experiences Ads Dialog to provide the Facebook Instant Experiences ad-creation user interfaces in your website. For details about the UI component, see Dialogs.

Set up the Facebook SDK for JavaScript, see:

The JavaScript SDK relies on the logged in user's permissions to create an Instant Experience. If the user does not have the necessary permissions to create an Instant Experience for the supplied page and business, the dialog will show an error. To ensure no errors, the user must be in the business and have 'create ads' permissions for the page.

Then trigger the dialog:

FB.ui({         
  display: 'popup',
  method: 'canvas_editor',
  business_id: '<BUSINESS_ID>',
  page_id: '<PAGE_ID>'
}, function(response) {
  // callback
});

You can provide these settings for the plugin:

Name Required Description

display

Yes

Necessary parameter with set value of popup

method

Yes

Necessary parameter with set value of canvas_editor

business_id

Yes

Your business ID

page_id

Yes

Page ID you want to associate the Instant Experience with

canvas_id

No

ID of Instant Experience you want to edit

The parameter canvas_id is optional and is meant to allow a user to edit or preview an existing Instant Experience. If an Instant Experience is complete, you cannot edit ir. To preview an Instant Experience, we recommend using the Instant Experiences Preview Dialog.

The plugin provides this response on success:

{
  "success": true,
  "id": "<CANVAS_ID>"
}

The ID returned is a published Instant Experience. You can now use it in ad campaigns. If no response or an undefined response is returned, that means a viewer closed the dialog before finishing the Instant Experience. The user may have saved the Instant Experiences, but not finished it. You can pull all Instant Experiences that belong to a page using the Graph API to see if there are any unfinished experiences.

Instant Experiences Preview Dialog

You can use this dialog to provide a preview of an Instant Experience as someone on Facebook would see it from your website. For details about the UI component, see Dialogs.

Set up the Facebook SDK for JavaScript, see:

The JavaScript SDK relies on the logged in user's permissions to create an Instant Experience. If the user does not have the necessary permissions to view the Instant Experience, the dialog shows an error.

Then trigger the preview dialog:

FB.ui({         
  display: 'popup',
  method: 'canvas_preview',
  canvas_id: '<CANVAS_ID>'
});

You can provide these settings for the plugin:

Name Required Description

display

Yes

Necessary parameter with set value of popup

method

Yes

Necessary parameter with set value of canvas_preview

canvas_id

Yes

ID of Instant Experience you want to preview