Marketing API Version

Ad Video

Uploaded videos to use in ads and ad creatives. You should upload video before you specify ad creative so you can reuse it in multiple creatives and to provide time to finish video processing. Due to video processing wait till the video status is ready. It may take several seconds, or even minutes for large videos. Videos must be at least one second long. See Ad Account, Ad Videos. For example, upload a video:

use FacebookAds\Object\AdVideo;
use FacebookAds\Object\Fields\AdVideoFields;

$video = new Advideo(null, 'act_<AD_ACCOUNT_ID>');
$video->{AdVideoFields::SOURCE} = '<VIDEO_PATH>';
$video->create();
from facebookads.adobjects.advideo import AdVideo

video = AdVideo(parent_id='act_<AD_ACCOUNT_ID>')
video[AdVideo.Field.filepath] = '<VIDEO_PATH>'
video.remote_create()
new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdVideo()
  .addUploadFile("source", new File(<VIDEO_PATH>))
  .execute();
curl \
  -F 'source=@<VIDEO_PATH>' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph-video.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/advideos

The response has a video's id. Then use this video in ad creative:

Create the creative

use FacebookAds\Object\AdCreative;
use FacebookAds\Object\AdCreativeVideoData;
use FacebookAds\Object\Fields\AdCreativeVideoDataFields;
use FacebookAds\Object\AdCreativeObjectStorySpec;
use FacebookAds\Object\Fields\AdCreativeObjectStorySpecFields;
use FacebookAds\Object\Fields\AdCreativeFields;
use FacebookAds\Object\Values\AdCreativeCallToActionTypeValues;

$video_data = new AdCreativeVideoData();
$video_data->setData(array(
  AdCreativeVideoDataFields::DESCRIPTION => 'try it out',
  AdCreativeVideoDataFields::IMAGE_URL => '<THUMBNAIL_URL>',
  AdCreativeVideoDataFields::VIDEO_ID => <VIDEO_ID>,
  AdCreativeVideoDataFields::CALL_TO_ACTION => array(
    'type' => AdCreativeCallToActionTypeValues::LIKE_PAGE,
    'value' => array(
      'page' => <PAGE_ID>,
    ),
  ),
));

$object_story_spec = new AdCreativeObjectStorySpec();
$object_story_spec->setData(array(
  AdCreativeObjectStorySpecFields::PAGE_ID => <PAGE_ID>,
  AdCreativeObjectStorySpecFields::VIDEO_DATA => $video_data,
));

$creative = new AdCreative(null, 'act_<AD_ACCOUNT_ID>');

$creative->setData(array(
  AdCreativeFields::NAME => 'Sample Creative',
  AdCreativeFields::OBJECT_STORY_SPEC => $object_story_spec,
));

$creative->create();
from facebookads.adobjects.adcreative import AdCreative
from facebookads.adobjects.adcreativeobjectstoryspec \
    import AdCreativeObjectStorySpec
from facebookads.adobjects.adcreativevideodata \
    import AdCreativeVideoData

video_data = AdCreativeVideoData()
video_data[AdCreativeVideoData.Field.description] = 'My Description'
video_data[AdCreativeVideoData.Field.video_id] = <VIDEO_ID>
video_data[AdCreativeVideoData.Field.image_url] = '<IMAGE_URL>'
video_data[AdCreativeVideoData.Field.call_to_action] = {
    'type': 'LIKE_PAGE',
    'value': {
        'page': <PAGE_ID>,
    },
}

object_story_spec = AdCreativeObjectStorySpec()
object_story_spec[AdCreativeObjectStorySpec.Field.page_id] = <PAGE_ID>
object_story_spec[AdCreativeObjectStorySpec.Field.video_data] = video_data

creative = AdCreative(parent_id='act_<AD_ACCOUNT_ID>')
creative[AdCreative.Field.name] = 'Video Ad Creative'
creative[AdCreative.Field.object_story_spec] = object_story_spec
creative.remote_create()
AdCreative adCreative = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdCreative()
  .setName("Sample Creative")
  .setObjectStorySpec(
    new AdCreativeObjectStorySpec()
      .setFieldPageId(<PAGE_ID>)
      .setFieldVideoData(
        new AdCreativeVideoData()
          .setFieldCallToAction(
            new AdCreativeLinkDataCallToAction()
              .setFieldType(AdCreativeLinkDataCallToAction.EnumType.VALUE_LIKE_PAGE)
              .setFieldValue(
                new AdCreativeLinkDataCallToActionValue()
                  .setFieldPage(<PAGE_ID>)
              )
          )
          .setFieldDescription("try it out")
          .setFieldImageUrl(<THUMBNAIL_URL>)
          .setFieldVideoId(<VIDEO_ID>)
      )
  )
  .execute();
String ad_creative_id = adCreative.getId();
curl \
  -F 'name=Sample Creative' \
  -F 'object_story_spec={ 
    "page_id": "<PAGE_ID>", 
    "video_data": { 
      "call_to_action": {"type":"LIKE_PAGE","value":{"page":"<PAGE_ID>"}}, 
      "description": "try it out", 
      "image_url": "<THUMBNAIL_URL>", 
      "video_id": "<VIDEO_ID>" 
    } 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/adcreatives

To reuse a video for ads upload it to a:

  • Page, see Page, Videos with Page management permissions, or
  • Ad account with requires ad management permissions.

You can then use videos in an account to create ads in that ad account, as long as you have permissions to create ads for that account. You can create ads for a Page's' videos as long as you can create ads for that Page; for example if you are admin of that Page.

Chunked Upload

You should upload most ad videos by chunk, for better stability. If the video file is small, like a few megabytes or less, you can also upload it at once, see Create. The endpoint accepting video upload is graph-video instead of graph as in most Marketing APIs.

Send one start request, one or multiple transfer requests, and one finish request at the end. Make a POST to:

https://graph-video.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/advideos

A sample of response is:

{
  "upload_session_id": "10153169544814116",
  "video_id": "10153169544799116",
  "start_offset": "0",
  "end_offset": "1048576"
}

In your request, use these fields:

NameTypeDescriptionRequired

upload_phase

string

Use start

Yes

file_size

int

Size of the video file in bytes

Yes

The response contains these fields:

NameTypeDescription

upload_session_id

numeric string

session ID of this chunked upload

video_id

numeric string

ID of ad video created

start_offset

numeric string

Start position in byte of next chunk that should be sent, inclusive

end_offset

numeric string

End position in byte of next chunk that should be sent, exclusive

Use session ID to manage the process. If end_offset equals the video's file size, you can upload the video in a single chunk.

Otherwise, upload the video with the two returned offset numbers. The chunk size depends on various factors, such as the file size, network speed, server load, and so on. Take your two offset numbers, and create chunked files. Then send a POST request to the same endpoint as above, with these fields:

NameTypeDescriptionRequired

upload_phase

string

Use transfer

Yes

upload_session_id

int

The session ID received during start phase

Yes

start_offset

int

The start offset in byte of the video being uploaded by this request

Yes

video_file_chunk

binary file

The chunk of the video, between start_offset and end_offset

Yes

The response contains these fields:

NameTypeDescription

start_offset

numeric string

Start position in byte of next chunk to send, inclusive

end_offset

numeric string

End position in byte of next chunk to send, exclusive

The response:

{
  "start_offset": "5242880",
  "end_offset": "12848512"
}

With these new offsets, continue uploading the video chunk by chunk. When you completely upload all chunks, start_offset equals end_offset. At this point, you should send a last POST request to the same endpoint to finalize the upload session.

NameTypeDescriptionRequired

upload_phase

string

Use finish

Yes

upload_session_id

int

The session ID received during start phase

Yes

title

string

The name of the video being uploaded

No

The response has these fields:

NameTypeDescription

success

boolean

Whether upload successful

{
  "success": true
} 

Example

Due to the nature of this feature, you will need write a script to handle the chunked upload.

If you use Facebook Python Ads SDK, you can simply create an AdVideo object and call remote_create function, without dealing with how to upload it in chunks. Behind the scences, the actual upload logic can be found here.

To handle the chunking by yourself, in your script, start the upload session by sending a POST request:

curl \
-F "access_token=<ACCESS_TOKEN>" \
-F "upload_phase=start" \
-F "file_size=<Video_file_size_in_bytes>" \
"https://graph-video.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/advideos"

Then you handle the response of this call, to get the id, start_offset, and end_offset. The id value would be the <SESSION_ID> in the steps below. Now, your script shall has a loop logic like this:

// open the video file;
while ($start_offset < $end_offset) {

  // use a function such as 'seek' to get to the position $start_offset;
  // read a chunk of ($end_offset - $start_offset) bytes and save it
  // to a temp location to pass to the 'video_file_chunk' field;

  curl \
  -F "access_token=<ACCESS_TOKEN>" \
  -F "upload_phase=transfer" \
  -F "upload_session_id=<SESSION_ID>" \
  -F "start_offset=<START_OFFSET>" \
  -F "video_file_chunk=@<BINARY_CHUNK_FILE_NAME>" \
  "https://graph-video.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/advideos"

  // update $start_offset and $end_offset from the response
}
// close the video file;

Once those two offsets are identical, it means that all chunks have been uploaded. You can now send the last POST request to end the whole upload session:

curl \
-F "access_token=<ACCESS_TOKEN>" \
-F "upload_phase=finish" \
-F "upload_session_id=<SESSION_ID>" \
-F "title=MyBigVideo" \
"https://graph-video.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/advideos"

Simple Uploads

Only use this for small video files whcih are a few megabytes or less. Otherwise, you should use Chunked Upload. Upload a video encoded as multi-part or form-data to:

https://graph-video.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/advideos

Use these fields:

NameTypeDescriptionRequired

name

string

Name of video

No

source

multi-part form

Video, encoded as form data. See Page, Videos for details on formats.

Yes

The response contain these fields:

NameDescription

id

ID of ad video

You can then use a video in ad creative. When you provide it with Ad Creative, Object Story Spec, specify the video's ID in video_id. See Ad Account Ad Videos, Reference.

Example

To load a list of all available thumbnails for a video, use:

use FacebookAds\Object\AdVideo;


$video = new AdVideo(<VIDEO_ID>);
$thumbs = $video->getVideoThumbnails();
from facebookads.adobjects.advideo import AdVideo

video = AdVideo(<VIDEO_ID>)
thumbnails = video.get_thumbnails()
curl -G \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/<VIDEO_ID>/thumbnails

The response should be a list of VideoThumbnail objects:

{
  "thumbnails": [
    {
      "height": 360,
      "id": "123456",
      "is_preferred": false,
      "scale": 1,
      "uri": "https://fbcdn-...",
      "width": 640
    }, 
    {
      "height": 360,
      "id": "123457",
      "is_preferred": false,
      "scale": 1,
      "uri": "https://fbcdn-...",
      "width": 640
    }, 
    {
      "height": 360,
      "id": "1234568",
      "is_preferred": true,
      "scale": 1,
      "uri": "https://fbcdn-...",
      "width": 640
    }, 
  ], 
  "id": "<VIDEO_ID>", 
  "updated_time": "2014-07-25T18:36:18+0000"
}

Create from image slideshows

Supported Image Formats: jpg, jpeg, png, bmp, ico Note that if the images don't have the same width and height, we will crop and resize them to 600*600px to create a squared video. But if the sizes are the same, we will keep the original size for the video.

Limitations Number of images: 3-7 images, each image should be less than 10 MB.

Param

NameTypeDescription

slideshow_spec

object

An object required for slideshow video.

images_urls

object

A 3-7 element array of the URLs of the images. Required.

duration_ms

number (>0)

The duration in milliseconds of each image. Default value is 1000.

transition_ms

number (>=0)

The duration in milliseconds of the crossfade transition between images. Default value is 1000.

Video Slideshows

To create a video slideshow:

curl \
-F 'slideshow_spec={\
     "images_urls":[\
       "https://example.com/picture1.png",\
       "https://example.com/picture2.png",\
       "https://example.com/picture3.png",\
     ],\
     "duration_ms": 2000,\
     "transition_ms": 200\
   }'\
-F 'access_token=<USER_ACCESS_TOKEN>' \
"https://graph-video.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/advideos"

The response is a video ID to use in an Ad Creative:

{"id":"<VIDEO_ID>"}

You can also create the slideshow at /{page-id}/videos.

Read

To retrieve ad account videos, make a HTTP GET:

https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/advideos

The response is an array of video objects. To get a video by ID, make an HTTP GET:

https://graph-video.facebook.com/<API_VERSION>/<VIDEO_ID>

The response is a video object.