Migration Guide for targetingCriteria

Introduction

LinkedIn uses member facets to define a segment of members who will be either included or excluded from an advertising campaign's targeting.

targetingCriteria provides a generic AND / OR construct to include and exclude different targeting facets when defining the audience for an Ad campaign. targetingCriteria is attached to a campaign and is replacing the now deprecated targeting object.

This migration guide consolidates the details required to migrate from targeting to targetingCriteria object.

Limitations of Targeting Object

The current targeting object has certain limitations. Because of the way the structure was defined, a target audience could only be defined a combination of a forced “AND” across different targeting facets and a forced “OR” within the different values of a facet. Here’s an example:

"targeting": {
    "includedTargetingFacets": {
        "interfaceLocales": [
            {
                "country": "US",
                "language": "en"
            }
        ],
        "locations": [
            "urn:li:geo:103644278"
        ],
        "skills": [
            "urn:li:skill:17",
            "urn:li:skill:27"
        ],
        "titles": [
            "urn:li:title:1",
            "urn:li:title:2"
        ]
    }
}

In this example, the only members who match the targeting criteria are those with skills (JAVA or C++)  AND titles (Senior or Manager). Notice how the AND and OR operations are sequenced. With this structure, it is not possible to target a members who are either a (Manager with Skill Java)  OR (a Senior with Skill C++). You can only apply OR operation within a facet type and You can only apply AND operation across facets.

A few more examples highlighting the same:

  • You cannot target members who are either Managers OR have skill JAVA.  (because AND operation is forced across facets).
  • You cannot target members who have skill JAVA and skill C++ (because OR operation is forced within the same facet)

Benefits of New targetingCriteria Object

targetingCriteria provides a generic AND / OR construct to include and exclude different targeting facets when defining the audience for an Ad campaign.

targetingCriteria mitigates the limitations described above. When all phases of the launch are complete, targetingCriteria will offer a powerful boolean construct that will allow for any combination of facets to be clubbed together in different ways.

Also, any new targeting facets or features are only going to be launched or supported using the new targetingCriteria object.

The complete details about targetingCriteria structure can be found here.

Comparison Between Old and New Targeting Objects

old targeting object

"targeting":{
  "includedTargetingFacets":{
    "skills":[
      "urn:li:skill:17"
    ],
    "locations":[
      "urn:li:geo:102221843"
    ],
    "interfaceLocales":[
      {
        "country":"US",
        "language":"en"
      }
    ]
  }
}

new targetingCriteria object

"targetingCriteria":{
  "include":{
    "and":[
      {
        "or":{
          "urn:li:adTargetingFacet:skills":[
            "urn:li:skill:17"
          ]
        }
      },
      {
        "or":{
          "urn:li:adTargetingFacet:locations":[
            "urn:li:geo:102221843"
          ]
        }
      },
      {
        "or":{
          "urn:li:adTargetingFacet:interfaceLocales":[
            "urn:li:locale:en_US"
          ]
        }
      }
    ]
  }
}

Timeline for Migration

In order to facilitate a smooth migration from Targeting object to TargetingCriteria object, we are rolling out the changes in two phases.

  • In Phase 1, we expect out API partners to implement changes such that there is direct, lossless translation of the Targeting object to equivalent TargetingCriteria object.
  • In Phase 2, we will enable all targeting logic that can be expressed using the new TargetingCriteria object.  All the added benefits of TargetingCriteria object can be actualized.

Our goal has been to provide enough time for our API partners to migrate to the new schema and we will be working closely with you during this migration.

Technical Impact

Below is a list of changes that will be required to successfully migrate from using the old targeting object to the new targetingCriteria object.

Changes to Campaign Targeting

In the first phase of migration, when reading campaigns, TargetingCriteria will be published along Targeting. This will help in understanding the equivalence between the two objects. In this phase, when writing campaigns, you should provide TargetingCriteria. If you provide both Targeting and TargetingCriteria, the TargetingCriteria will be ignored.

The documents for campaign creation and targeting have been updated. Here is a comparison between the two equivalent campaigns.

campaign with old targeting

{
    "account": "urn:li:sponsoredAccount:516821035",
    "audienceExpansionEnabled": false,
    "costType": "CPC",
    "creativeSelection": "OPTIMIZED",
    "dailyBudget": {
        "amount": "1800",
        "currencyCode": "USD"
    },
    "locale": {
        "country": "US",
        "language": "en"
    },
    "name": "Campaign Sponsored update",
    "offsiteDeliveryEnabled": false,
    "runSchedule": {
        "end": 9876543210123,
        "start": 1234567890987
    },
    "targeting": {
        "includedTargetingFacets": {
            "interfaceLocales": [
                {
                    "country": "US",
                    "language": "en"
                }
            ],
            "locations": [
                "urn:li:geo:103644278"
            ],
            "skills": [
                "urn:li:skill:17"
            ]
        }
    },
    "type": "SPONSORED_UPDATES",
    "unitCost": {
        "amount": "15",
        "currencyCode": "USD"
    }
}

campaign with new targetingCriteria object

{
    "account": "urn:li:sponsoredAccount:516521035",
    "audienceExpansionEnabled": false,
    "costType": "CPC",
    "creativeSelection": "OPTIMIZED",
    "dailyBudget": {
        "amount": "1800",
        "currencyCode": "USD"
    },
    "locale": {
        "country": "US",
        "language": "en"
    },
    "name": "Campaign Sponsored update",
    "offsiteDeliveryEnabled": false,
    "runSchedule": {
        "end": 9876543210123,
        "start": 1234567890987
    },
    "targetingCriteria": {
        "include": {
            "and": [
                {
                    "or": {
                        "urn:li:adTargetingFacet:skills": [
                            "urn:li:skill:17"
                        ]
                    }
                },
                {
                    "or": {
                        "urn:li:adTargetingFacet:locations": [
                            "urn:li:geo:103644278"
                        ]
                    }
                },
                {
                    "or": {
                        "urn:li:adTargetingFacet:interfaceLocales": [
                            "urn:li:locale:en_US"
                        ]
                    }
                }
            ]
        }
    },
    "type": "SPONSORED_UPDATES",
    "unitCost": {
        "amount": "15",
        "currencyCode": "USD"
    }
}

Note

Please Note: Only one of TargetingCriteria or Targeting can be used with Campaigns. Furthermore, if TargetingCriteria is ever used to create or update a Campaign, it must be used going forward with that Campaign, since TargetingCriteria is more expressive than Targeting. Mapping/validation logic will be updated to ensure this rule is enforced.

Please refer to the updated documentation for Create and Manage Campaigns.

Changes to AudienceCount API

A new FINDER has been introduced and the previous one is being deprecated. The q parameter has changed from targetingCriteria to targetingCriteriaV2 . A new query parameter based on targetingCriteria object is used in the URL instead of the old target.includedTargetingFacets object.

targetingCriteriaV2 uses 'X-Restli-Protocol-Version: 2.0.0'. Here is a quick look at the changes:

  • Old Finder  (to be deprecated)
  • New Finder (without encoding, for readability)
  • New Finder (encoded, actual API call)
OLD (GET) https://api.linkedin.com/v2/audienceCountsV2?q=targetingCriteria&target.includedTargetingFacets.locations[0]=urn:li:geo:102221843&target.includedTargetingFacets.skills[0]=urn:li:skill:5&target.includedTargetingFacets.skills[1]=urn:li:skill:17
New (GET) https://api.linkedin.com/v2/audienceCountsV2?q=targetingCriteriaV2&targetingCriteria=(include:(and:List((or:({encoded urn:li:adTargetingFacet:locations}:List({encoded urn:li:geo:102221843}))),(or:({encoded urn:li:adTargetingFacet:skills}:List({encoded urn:li:skill:17}))))))
New (GET) (encoding) https://api.linkedin.com/v2/audienceCountsV2?q=targetingCriteriaV2&targetingCriteria=(include:(and:List((or:(urn%3Ali%3AadTargetingFacet%3Alocations:List(urn%3Ali%3Ageo%3A102221843))),(or:(urn%3Ali%3AadTargetingFacet%3Askills:List(urn%3Ali%3Askill%3A5,urn%3Ali%3Askill%3A17))))))

Please refer to the updated documentation for AudienceCountsV2 API

Changes to adBudgetPricing API

A new FINDER has been introduced and the previous one is being deprecated.The q parameter has changed from criteria to criteriaV2 . A new query parameter based on targetingCriteria object is used in the URL instead of the old target.includedTargetingFacets object.

criteriaV2 uses Rest.li 2.0, so the encoding has also changed. encoded API request examples must pass the header X-Restli-Protocol-Version: 2.0.0 and the URN must be URL encoded, for example, a colon should be translated to %3A, so

  • urn:li:organization:12345
    is URL encoded to
  • urn%3Ali%3Aorganization%3A12345

Here is a quick look at the last change:

Old Finder (deprecated)

GET https://api.linkedin.com/v2/adBudgetPricing?account=urn:li:sponsoredAccount:12345&bidType=CPM&campaignType=SPONSORED_INMAILS&matchType=EXACT&q=criteria&target.includedTargetingFacets.staffCountRanges[0]=SIZE_501_TO_1000&dailyBudget.amount=300&dailyBudget.currencyCode=USD

New Finder (un-encoded)

GET https://api.linkedin.com/v2/adBudgetPricing?account=urn:li:sponsoredAccount:12345&bidType=CPM&campaignType=SPONSORED_INMAILS&matchType=EXACT&q=criteriaV2&targetingCriteria=(include:(and:List((or:({encoded urn:li:adTargetingFacet:staffCountRanges}:List({encoded urn:li:staffCountRange:(501,1000)}))))))&dailyBudget=(amount:300,currencyCode:USD)

New Finder (encoded, actual API call)

GET (URL encoded) https://api.linkedin.com/v2/adBudgetPricing?account=urn%3Ali%3Aorganization%3A12345&bidType=CPM&campaignType=SPONSORED_INMAILS&matchType=EXACT&q=criteriaV2&&targetingCriteria=(include:(and:List((or:(urn%3Ali%3AadTargetingFacet%3AstaffCountRanges:List(urn%3Ali%3AstaffCountRange%3A%28501%2C1000%29))))))&dailyBudget=(amount:300,currencyCode:USD)

Please refer to the updated documentation for adBudgetPricing API.

Changes to adSupplyForecasts API

A new FINDER has been introduced and the previous one is being deprecated.The q parameter has changed from criteria to criteriaV2 . A new query parameter based on targetingCriteria object is used in the URL instead of the old target.includedTargetingFacets object.

Please also note: account is now a required input parameter.

criteriaV2 uses Rest.li 2.0, so the encoding has also changed. Here is a quick look at the changes:

  • Old Finder   (to be deprecated)
  • New Finder (without encoding, for readability)
  • New Finder (encoded, actual API call)
OLD (GET) https://api.linkedin.com/v2/adSupplyForecasts?q=criteria&timeRange.start=1526348264000&timeRange.end=1529026664000&campaignType=SPONSORED_UPDATES&competingBid.bidType=CPM&competingBid.bidPrice.currencyCode=USD&competingBid.bidPrice.amount=10&target.includedTargetingFacets.locations[0]=urn:li:geo:101174742&target.includedTargetingFacets.locations[1]=urn:li:geo:103644278&target.excludingTargetingFacets.staffCountRanges[0]=SIZE_10001_OR_MORE
New (GET) https://api.linkedin.com/v2/adSupplyForecasts?q=criteriaV2&account=urn:li:sponsoredAccount:518121035&timeRange=(start:1526348264000,end:1529026664000)&campaignType=SPONSORED_UPDATES&competingBid=(bidType:CPM,bidPrice:(currencyCode:USD,amount:10))&targetingCriteria=(include:(and:List((or:({encoded urn:li:adTargetingFacet:locations}:List({encoded urn:li:geo:102221843}))))),exclude:(or:({encoded urn:li:adTargetingFacet:staffCountRanges}:List({encoded urn:li:staffCountRange:(10001,2147483647)}))))
New (GET) (Enc) https://api.linkedin.com/v2/adSupplyForecasts?q=criteriaV2&account=urn%3Ali%3AsponsoredAccount%3A518121035&timeRange=(start:1526348264000,end:1529026664000)&campaignType=SPONSORED_UPDATES&competingBid=(bidType:CPM,bidPrice:(currencyCode:USD,amount:10))&targetingCriteria=(include:(and:List((or:(urn%3Ali%3AadTargetingFacet%3Alocations:List(urn%3Ali%3Ageo%3A102221843))))),exclude:(or:(urn%3Ali%3AadTargetingFacet%3AstaffCountRanges:List(urn%3Ali%3AstaffCountRange%3A%2810001%2C2147483647%29))))

Please refer to the updated documentation for adSupplyForecasts API.

Changes to adTargetingFacets API

The only change is this API is that a new field “$URN” is returned in the GET_ALL method.

The new targetingCriteria object requires all targeting facets to be fully qualified names. This new field “$URN” gives that name.

Facet discovery earlier returned just facetNames like genders, industries, seniorities. Now, the corresponding URNs are returned in ‘$URN’ field.

  • urn:li:adTargetingFacet:genders
  • urn:li:adTargetingFacet:industries
  • urn:li:adTargetingFacet:seniorities (and so on.)

It is important to store the URN names as those are the ones to be used in all the new APIs when using the targetingCriteria object.

Please refer to the updated documentation for adTargetingFacets API.

Changes to adTargetingEntities API

A new ‘queryVersion’ parameter has been added to existing FINDERs (adTargetingFacet,similarEntities, typeahead)

This ENUM denotes the version of the targeting expression that the desired entity should correspond to. The expression version determines whether the 'value' or 'urn' field will be populated as these both represent the value of the segment but in different formats.

  • QUERY_USES_MIXED corresponds to the Targeting expression which takes varying types (like enum) in the 'value' field.
  • QUERY_USES_URNS corresponds to the TargetingCriteria expression which takes a string urn in the 'urn' field.

Additionally, A new FINDER 'q=urns' has been introduced This FINDER can be used to get the metadata and value information for a collection of urns in the given locale. The metadata and value information is encapsulated in a collection of AdTargetingEntity.

Please refer to the updated documentation for adTargetingEntities API.

FAQ

When can I begin migration (Phase 1)?

You can start using the new finders and new targetingCriteria object in campaigns as early as 07/01/2018.

By what date should migration (Phase 1) be completed?

We expect all our API partners to complete Phase 1 migration by 03/31/2019.  This will make it easier to incorporate Phase 2 changes and launch full targeting expressiveness (Phase 2) alongside the UI feature launch in June 2019. We highly recommend migrating as per our proposed phases as we will be able to support your needs better.

Will the old APIs be deprecated?  What if I don't migrate?

The old APIs will be deprecated on 06/15/2019.  You have enough time to migrate and you can choose to do so in phases as we have recommended or all at once before the depreciation date.

When will LinkedIn enable advanced Targeting Expressiveness? (Phase 2)

Full targeting expressiveness feature is set to launch in June 2019

By what date should migration (Phase 2) be completed?

Ideally, our API partners could be launching this feature alongside UI feature launch in June 2019.  The hard date for deprecation of old APIs is 06/15/2019.  All migration should be completed by that time.