Developer News from Facebook

How It Works Before Oct 1st, 2014

With Facebook API, one can delete an "ad object", i.e. a campaign, an ad set, or an ad, by either sending an HTTP DELETE request, or updating the object's status to DELETED. Those deleted ad objects are still in Facebook's system. You can query DELETED objects by specifying the status. For example, to get all the deleted ad groups of a campaign, you can use:

 https://graph.facebook.com/{campaign id}/adgroups?fields=adgroup_status&adgroup_status=['DELETED']
    

However, as some ad accounts have such a big number of DELETED objects, that a query of them may result in a response too big to be handled, you may get unexpected errors.

We are now going to have two statuses: the new ARCHIVED objects will still be returned as connection objects, a.k.a edges, with an upper limit of the archived object numbers of each ad account; and the new DELETED objects will not be returned as edges.


New Status

After Oct 1, 2014, adgroup_status of an ad, campaign_status of an ad set, and campaign_group_status of a campaign can be of one additional value: ARCHIVED. Also, the meaning of DELETED will also be changed.

Query DELETED before ARCHIVED after DELETED after

Exists in database

Yes

Yes

Yes

Maximum number per ad account

No limit

50,000

NO Limit

Query as edges w/o filter

No

No

No

Query as edges with DELETED status filter

Yes

Error

Error

Query as edges with ARCHIVED status filter

Yes

Yes

No

Query by its own ID

Yes

Yes

Yes

Stats aggregated in /{parent object id}/stats

Yes

Yes

Yes

Stats included in the result list of /{parent object id}/reportstats

Yes

Yes

Yes

Stats included in the result list of /{parent object id}/{obj name}stats

No

No

No

Stats included in the result list of /{parent object id}/{obj name}stats?include_deleted=true

Yes

Yes

No

Stats shown with /{obj id}/stats

Yes

Yes

Yes

Status can be changed to

Cannot change

DELETED

Cannot change

All ad objects which were DELETED before Oct 1 would be of ARCHIVED status after this change automatically. In the meantime, the DELETED status would still be available, but none of your pre-migration ad objects would be of that status.

All those API calls which used to cause objects DELETED in the past, HTTP DELETE request or update status to DELETED, will cause them to have the status DELETED after the migration, instead of ARCHIVED. For example, if you deleted A using Ads API on Sept 27th, 2014, and later deleted B using the same API on Oct 2nd, 2014, A would be ARCHIVED because it would have been migrated on Oct 1st, while B would be DELETED.

One aspect worth attention is that the ads statistics, including conversions, of a parent object is the aggregation of statistics of all its children, regardless of their status. As the result, if your application shows the ads statistics of objects broken down by its sub-objects, to avoid inconsistent numbers in statistics, you need to wait for at least 28 days after the last date of delivery of the objects, and store the statistics or at least ids of those to be deleted objects in your own system, before you delete them.


Handle the Limitation of ARCHIVED Object Number

No matter how many deleted objects you have before Oct 1st, they will all be converted to archived objects. But if you have 50,000 or more archived objects of each type in an ad account, you will not be able to archive in that ad account any more: either you can delete them instead, or you can delete some archived ones to make space.

For example, if you have 60,000 deleted ads in an ad account before Oct 1st, they will all be converted to archived ones during the change. However, you cannot archive any more ads unless you delete at least 10,001 ads of this ad account first. If you try to archive one before there is any space, you would get an error in reply.

As an Ads API developer, you should make sure that your system does not archive too many objects per ad account, and move some archived ones to deleted once you approach the limit.

The following sample code, using Facebook Ads SDK, shows how the number of archived ads can be detected, and then some ad groups are deleted if the limit is close. You can decide when this logic will be triggered based on your business requirements. For example, you can run this kind of logic periodically, or once per user session. And, instead of only handling ads as in this sample, you will also need to handle campaigns and ad sets.

<?php

// Set your access token here:
$access_token = null;
$app_id = null; // the number
$app_secret = null;
$account_id = null; // in "act_xxxxx" format
$threshold = 45000; // Set a number below 50,000 with some buffer

if(is_null($access_token) || is_null($app_id) || is_null($app_secret)) {
throw new \Exception(
'You must set your access token, app id and app secret before executing'
);
}
if (is_null($account_id)) {
throw new \Exception(
'You must set your account id before executing');
}
define('SDK_DIR', __DIR__ . '/.'); // Path to the SDK directory
$loader = include SDK_DIR.'/vendor/autoload.php';

use FacebookAds\Api;
use Facebook\FacebookSession;
use FacebookAds\Object\AdAccount;
use FacebookAds\Object\Fields\AdGroupFields;

FacebookSession::setDefaultApplication($app_id, $app_secret);
$session = new FacebookSession($access_token);
$api = new Api($session);

$params = array (
AdGroupFields::ADGROUP_STATUS => ['ARCHIVED'],
'summary' => 'true');
$result = $account->getAdGroups([AdGroupFields::ID], $params);
$count = $result->getResponse()->getResponse()->summary->total_count;

if ($count > $threshold) {
// If the limit is close, purge some
foreach ($result as $adgroup) {
if ( xxxx ) { 
// implement some purging condition. For example, you can
// purge the oldest N objects based on created_date, or you can
// purge objects created more than 1 year ago, and so on
$adgroup->delete();
}
}
}

More utilities to help you on this task are planned and will be released in the future.

As you may have noticed that with Ads API's PHP SDK or Python SDK, there are separate methods to either archive or delete ad objects. The delete() method is used in the sample code above. When you use archive(), the system does not delete old archived objects to make space if the limit is reached, thus you will need to handle the too many archived objects case by yourself, like in the sample above.


Behavior on Facebook UI

When you're working in a Facebook user interface, such as Ads Manager or Power Editor, you can delete an ad object. The following screen shots explains how to delete an ad object with Ad Manager or Power Editor respectively. Deleting objects in any of Facebook's ads interfaces is equivalent to setting their status to ARCHIVED with API.

Since there are limits on the number of archived objects per ad account, a way to remove objects from the archive, based on the date they were archived, will be provided in the near future. Please note that to remove an ad object means to set their status to DELETED with API.


FAQ

  • If I do nothing, what will happen after Oct 1, 2014?
    • All deleted ad objects will be archived. And if your application deletes objects in the same way as before, those objects will be deleted.
  • Can I just change all delete API calls to archive, so that everything will be same as before?
    • You can do that only if there are fewer than 50,000 ad objects of each type per ad account. Once you reach that limit, your archive calls will fail, i.e. you need extra logic to handle that error case. Also, if you have logic in your code to compare the status with DELETED, you would need to change the code to use ARCHIVED to compare.
  • If with an ad account, I have 20,000 campaigns, 15,000 ad sets, and 40,000 ads in ARCHIVED status, can I archive more?
    • Yes, you can. You can have up to 50,000 ad objects of each type.
  • If I do not need deleted or archived objects to appear as connection objects, i.e. I do not retrieve deleted/archived objects from edges, can I ignore the new archived status, and just delete everything?
    • Yes, you can. And you do not need to deal with the 50,000 item limit. But if your application shows stats breakdown by it sub-objects, you may have inconsistent numbers, as DELETED objects are not visible on your application now, but their stats are still included.
  • I want to use connection objects to retrieve archived ad objects, but I have more than 50,000 ads in that status. What should I do?
    • Sorry, you will have to delete some archived ad objects first.
  • So, should I delete or archive an object when my user "deletes" an object in my application?
    • If that object is no longer needed as a connection object of another object, to delete it is recommended. If you still need it to be included in the result from the edges, you need to archive it, but you will need to check the maximum limit.
  • Do you have any utilities to help me to delete old archived objects?
    • It is under consideration, but currently when the 50,000 limitation is reached, you will need to do that, including to decide which objects to delete and actually to delete them, by yourself.
  • I would like to use the ARCHIVED status, along with DELETED status before Oct 1st, 2014. Can I do that?
    • Yes. Go to your Facebook App setting, and turn on "Adding the Archived status to Ads objects". Your application will behave as if past Oct 1st, except now you can change a DELETED object to ARCHIVED, which you would not be able to do after Oct 1st. It is recommended for you to turn on that setting before the date, to make sure that this migration would not break your application.