Content Allow Lists API

Content Allow Lists give advertisers the ability to work with trusted Meta Business Partners to review and customize lists of brand suitable videos for running Facebook in-stream campaigns. For example, a children's products manufacturer might only want to advertise on child-friendly content.

Note: Content Allow Lists were previously known as Dynamic Content Sets (DCS) and may still be listed in the code as dynamic_content_sets and so on.

Additional documentation you can review and/or share with advertisers:

Permissions

  • The app requires the brand_safety_third_party_partners capability grant.

Creating a Content Allow List

Make a POST request to the dynamic_content_sets edge:

curl -X POST \
 -F "name=hello_world" \
 -F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<API_VERSION>/<BUSINESS_ID>/create_dynamic_content_set"

The default response will be:

{"id": "<CONTENT_ALLOW_LIST_ID>"}

If reaching the max limit on the business level when creating a new Content Allow List, you’ll receive the response:

{
 "success": "false",
 "error_message": "You can only create {max_business_dcs_creation_allowed} content allow lists for each business. To create a new list, try deleting some of your existing lists."
}

Parameters:

Parameter Type Required (Y/N) Description

name

string

Y

The name of the content allow list to create.

This endpoint requires Business Admin permissions.

Delete Content Allow List

Make a DELETE request to the given content allow list:

curl -X DELETE \-F "access_token=<ACCESS_TOKEN>" \"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>

The default response will be:

{"success": "true"}

If trying to delete a content allow list which is in use (has applied ad accounts), you’ll receive the response:

{
 "success": "false",
 "error_message": "Cannot delete a content allow list which is in use."
}

This endpoint requires Business Admin permissions.

Get all Content Allow Lists owned by a Business Manager account

Make a GET request to the dynamic_content_sets edge:

 curl -X GET \
"https://graph.facebook.com/<API_VERSION>/<BUSINESS_ID>/dynamic_content_sets?access_token=<ACCESS_TOKEN>"

The default response will be:

{
  "data": [
    {
      "id": "<CONTENT_ALLOW_LIST_ID>",
      "name": "CAL example 1",
      "business_id": "<BUSINESS_ID>"
    },
    {
      "id": "<CONTENT_ALLOW_LIST_ID>",
      "name": "CAL example 2",
      "business_id": "<BUSINESS_ID>"
    }
  ]
}

Fields

Field Type Default (Y/N) Description

id

fbid

Y

ID of each Content Allow List.

name

string

Y

Name of the Content Allow List.

business_id

fbid

Y

Business Manager account that owns the Content Allow List.

Get specific content allow list metadata

Make a GET request to the CONTENT_ALLOW_LIST_ID edge:

curl -X GET \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>?fields=id,name,business_id&access_token=<ACCESS_TOKEN>"

The default response will be:

{"id":"<CONTENT_ALLOW_LIST_ID>","name":"<CONTENT_ALLOW_LIST_NAME>","business_id":"<BUSINESS_ID>"}

Fields

Field Type Default (Y/N) Description

id

fbid

Y

ID of each Content Allow List.

name

string

Y

Name of the Content Allow List.

business_id

fbid

Y

Business Manager account that owns the Content Allow List.

Get video_ids for a specific Content Allow List

Make a GET request to the CONTENT_ALLOW_LIST_ID/video_ids edge:

curl -X GET \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/video_ids?summary=total_count&limit=<9000>&access_token=<ACCESS_TOKEN>"

The response will be a list of the video IDs in JSON array format, and a summary object with total_count of videos in this Content Allow List when the summary=total_count parameter is attached to the request:

{
 "data": [
   {
     "video_id": "111"
   },
   {
     "video_id": "222"
   },
   {
     "video_id": "333"
   },
   ...
 ],
 "summary": {
   "total_count": 1000
 }
}

Page Limits

The following page limits apply to all paginated APIs for this product:

Default number of items per page: 25.

Maximum number of items per page: 9,000.

Note: It is recommended to use 9,000 or fewer to avoid hitting limits.

Fields:

Field Type Default (Y/N) Description

video_id

fbid

Y

ID of the video.

Summary:

Parameter Type Default (Y/N) Description

total_count

integer

N

Total number of videos in the Content Allow List.

Update Content Allow List Name

Make a POST request to the CONTENT_ALLOW_LIST_ID edge:

curl -X POST \
-F "name=hello_world" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>"

The response will be:

{"success":true}

Find videos to add to a Content Allow List

  1. Apply for the the Page Public Content Access permission for your App (under App Review → Permissions and Features)
  2. Download the latest In-Stream videos publisher list (make a GET call to the brand_safety_publisher_list edge). Note that page_id can be obtained from the field “url”.
  3. Make a GET call to the PAGE_ID/videos edge:
 curl -X GET \
"https://graph.facebook.com/<API_VERSION>/<PAGE_ID>/videos?fields=ad_breaks_enabled,published,id&access_token=<ACCESS_TOKEN>"

Fields

Reference the public Video API docs for a list of supported fields.

This edge also supports time-based pagination, e.g.:

curl -X GET \
"https://graph.facebook.com/<API_VERSION>/<PAGE_ID>/videos?fields=ad_breaks_enabled,published,id&since=<UNIX_TIMESTAMP>&access_token=<ACCESS_TOKEN>"

Note: "since" is based on create time of the video, it does not factor in updates.

For standard Video fields (reference: Video Reading Marketing API Documentation)

The default response will be a list of the videos in JSON array format:

{
 "data": [
   {
     "ad_breaks_enabled": true,
     "published": true,
     "id": "<VIDEO_ID>"
   },
   {
     "ad_breaks_enabled": false,
     "published": true,
     "id": "<VIDEO_ID>"
   }
 ]
}

Note that only published videos with ad_breaks_enabled set to “true” can be added to a Content Allow List.

Add Videos to a Content Allow List

Make a POST request to the add_videos edge:

curl -X POST \
-F "video_ids=[video_id, video_id, ...]" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/add_videos"

Parameters:

Parameter Type Required (Y/N) Description

video_ids

list(fbid)

Y

List of video IDs (max 1,000 per call; max 2,000,000 per Content Allow List)

The response will be:

{"success":true}

If there are any errors when adding the videos, you will receive the following response:

{"error": {
"message": "Some videos failed to add into content allow list",
"type": "OAuthException",
"code": 61000,
"error_data": {
  "failed_video_ids": [
  1234
  ],
  "processed_videos": 1
},
"error_subcode": 2349007,
"is_transient": false,
"error_user_title": "CAL Add Video Failed",
"error_user_msg": "Failed to add videos into Content Allow List.",
  }
}

Remove Videos from a Content Allow List

Make a DELETE request to the videos edge:

curl -X DELETE \
-F "video_ids=[video_id, video_id, ...]" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/videos"

Parameters:

Parameter Type Required (Y/N) Description

video_ids

list(fbid)

Y

List of video IDs (max 1,000 per call; max 2,000,000 per Content Allow List)

The response will be:

{"success":true}

If there are any errors when deleting the videos, you will receive the following response:

{
  "error": {
    "message": "Some videos failed to remove from content allow list",
    "type": "OAuthException",
    "code": 61002,
    "error_data": {
      "failed_video_ids": [
        123
      ]
    },
    "error_subcode": 2349006,
    "is_transient": false,
    "error_user_title": "CAL Remove Video Failed",
    "error_user_msg": "Failed to remove videos from Content Allow List.",
  }
}

Check if Video is in Content Allow List

Make a GET request to the contains edge:

curl -X GET \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>?fields=contains.video_id(<VIDEO_ID>)&access_token=<ACCESS_TOKEN>"

The response will be:

{"contains": true, "id": "<Content Allow List_ID">}

Apply Content Allow List to Ad Account

Make a POST request to the apply_to_ad_accounts edge:

curl -X POST \
-F "ad_account_id=<ACCOUNT_ID>" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/apply_to_ad_accounts"

The response will be:

{"success": true}

Unapply Content Allow List to Ad Account

Make a DELETE request to the unapply_to_ad_accounts edge:

curl -X DELETE \
-F "ad_account_id=<ACCOUNT_ID>" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/unapply_to_ad_accounts"

The response will be:

{"success": true}

Parameters:

Parameter Type Required (Y/N) Description

ad_account_id

fbid

Y

ID of the ad account.

Get all ad accounts a Content Allow List is applied to

curl -X GET \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/applied_ad_accounts?access_token=<ACCESS_TOKEN>"

The default response will be a list of the ad account IDs in JSON array format:

{
  "data": [
    {
      "id": "act_<ACCOUNT_ID>"
    },
    {
      "id": "act_<ACCOUNT_ID>"
    },
    ...
  ]
}

Fields

Reference the public Ad Account API docs for a list of supported fields.

Share Content Allow List to Business Manager account

Make a POST request to the agencies edge:

curl -X POST \
-F "agency_id=<BUSINESS_ID>" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/agencies"

The response will be:

{"success":true}

Parameters:

Parameter Type Required (Y/N) Description

business_id

fbid

Y

ID of the Business Manager account

Unshare Content Allow List from Business Manager account

Make a DELETE request to the agencies edge:

curl -X DELETE \
-F "agency_id=<BUSINESS_ID>" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/agencies"

The response will be:

{"success":true}

Parameters:

Parameter Type Required (Y/N) Description

business_id

fbid

Y

ID of the Business Manager account

Get all Business Manager accounts a Content Allow List is shared with

Make a GET request to the agencies edge:

curl -X GET \
"https://graph.facebook.com/<API_VERSION>/<CONTENT_ALLOW_LIST_ID>/agencies?access_token=<ACCESS_TOKEN>"

The response will be:

{
  "data": [
    {
      "id": "<BUSINESS_ID>",
      "name": "business name 1"
    },
    {
      "id": "<BUSINESS_ID>",
      "name": "business name 2"
    },
    ...
  ]
}

Error Codes

See also Marketing API | Error Reference

Code Subcode Description

2349013

In order to be able to delete a CAL, it should not be applied to any ad accounts.

2349055

You can only create {max_business_dcs_creation_allowed} content allow lists for each business. To create a new list, try deleting some of your existing lists.

2349006

Failed to remove videos from Content Allow List.

2349007

Failed to add videos into Content Allow List.

200

Permissions error.

80011

There have been too many calls to Brand Safety APIs. Wait a bit and try again.

fbtrace_id: Internal support identifier. When reporting a bug related to a Graph API call, include the fbtrace_id to help us find log data for debugging

Limits

One Content Allow List (CAL) can contain no more than 2,000,000 unique video IDs; in the unlikely case it is needed to support more than 2,000,000 active videos, multiple Content Allow Lists will need to be created.

A business is limited to creating 2500 Content Allow Lists.

FAQs

Q: Is there any indication from a video that you can pull to determine if the meta data (title/description) for that video has changed?

A: There is no field to indicate a video has changed. However, you could download the video fields regularly and run a script to see if there is a difference in the name, description etc.

Q: Can we remove any video IDs from a CAL if those Video IDs have been deleted from Facebook?

A: It is expected functionality. By default if a video is deleted, it also automatically gets removed from the CAL. Once a video is deleted it in near real time is removed from the CAL.