Search API Connector Documentation

Print

Import LinkedIn Ads Data to Google Sheets

premium

In this guide, we will pull data from the LinkedIn API directly into Google Sheets, using the API Connector add-on for Sheets.

The LinkedIn API is extremely limited and blocked off; don’t expect a way to pull out profile information for anyone but yourself. However, this API is perfect for pulling out advertising performance data from the LinkedIn Ads Reporting API.

Contents

Before You Begin

Click here to install the API Connector add-on from the Google Marketplace.

Part 1: Connect to the LinkedIn Ads API

If you haven’t connected API Connector to LinkedIn before, you’ll first need to initiate the connection as follows:

  1. Open up Google Sheets and click Extensions > API Connector > Manage Connections.
  2. In the list of available connections, find LinkedIn Ads and click Connect.
    linkedin-api-img3
  3. You will be directed to LinkedIn and asked to authorize the connection. Click Allow.
    linkedin-oauth
  4. You’ll now be returned to your Google Sheet, and can verify that your LinkedIn API connection is active in the Connections screen.

Part 2: Create a LinkedIn API Request URL

For our first request, we’ll get some basic information about your own LinkedIn account.

  • API root: https://api.linkedin.com/v2
  • Endpoint: /me

Putting it together, we get the full API Request URL.

https://api.linkedin.com/v2/me

Part 3: Pull LinkedIn API Data into Sheets

Now let’s copy that URL into API Connector.

  1. In the Create Request interface, enter the Request URL we just created.
    linkedin-api-img1
  2. We don’t need any headers for this API, so just leave that section blank.
  3. Under Authentication, choose LinkedIn Ads from the Connections dropdown.
    linkedin-api-img6
  4. Create a new tab and click Set current to use that tab as your data destination.
  5. Name your request and click Run. A moment later you’ll see some information about your account populate your sheet.
    linkedin-api-img7

Part 4: More Example URLs

Now that we’ve validated the connection, we can start pulling some more data. You can access the full list of metrics available in the ads reporting API here, but if you just want to get started, you can try the following URLs.

Get Metadata

LinkedIn has a rather inconveniently designed API that returns IDs without names, so I suggest first running all four of these metadata requests so that they’re available when you make your summary reports or dashboards. The metadata is where you can get campaign names, statuses, and other descriptive values.

  • List of ad accounts (note the ID that gets returned in the elements.id field, we can use this for subsequent requests).
    https://api.linkedin.com/v2/adAccountsV2?q=search
  • List of ad campaign groups
    https://api.linkedin.com/v2/adCampaignGroupsV2?q=search
  • List of ad campaigns (this produces a ton of columns so you can clean it up a bit with a fields parameter like this)
    https://api.linkedin.com/v2/adCampaignsV2?q=search&fields=id,account,status,format,locale,type,version,runSchedule,campaignGroup,changeAuditStamps,dailyBudget,costType,creativeSelection,unitCost,name,offsiteDeliveryEnabled,id,account,status
    linkedin-api-img9
  • List of ad creatives
    https://api.linkedin.com/v2/adCreativesV2?q=search

To filter for active campaigns or creatives, you’d add a filter like this to the end of your URL: &search.status.values[0]=ACTIVE. Other filters are shown in LinkedIn’s API documentation under “Search for Campaigns” (link).

Get Ad Performance

Take a look at these examples, but it’s probably easiest to use the API request builder to create your ad performance requests.

  • Summary ad account performance, daily from 2021 (substitute in the account ID value from elements.id where it says 502849368).
    https://api.linkedin.com/v2/adAnalyticsV2?q=analytics&pivot=ACCOUNT&dateRange.start.year=2021&dateRange.start.month=1&dateRange.start.day=1&dateRange.end.year=2021&dateRange.end.month=3&dateRange.end.day=31&timeGranularity=DAILY&fields=externalWebsiteConversions,dateRange,impressions,landingPageClicks,likes,shares,costInLocalCurrency,pivot,pivotValue&accounts[0]=urn:li:sponsoredAccount:502849368
    Valid timeGranularity values include DAILY, MONTHLY, YEARLY, and ALL

  • Summary performance by campaign
    https://api.linkedin.com/v2/adAnalyticsV2?q=analytics&dateRange.start.year=2021&dateRange.start.month=1&dateRange.start.day=1&dateRange.end.year=2021&dateRange.end.month=3&dateRange.end.day=31&timeGranularity=DAILY&pivot=CAMPAIGN&fields=dateRange,impressions,approximateUniqueImpressions,videoViews,clicks,videoStarts,videoFirstQuartileCompletions,videoMidpointCompletions,videoThirdQuartileCompletions,externalWebsiteConversions,comments,reactions,totalEngagements,costInLocalCurrency,pivot,pivotValue&accounts[0]=urn:li:sponsoredAccount:502849368 
    linkedin-api-img10
  • Suggested bid amounts for a campaign targeting LinkedIn members between the ages of 18 and 24
    https://api.linkedin.com/v2/adBudgetPricing?account=urn:li:sponsoredAccount:502849368&bidType=CPM&campaignType=SPONSORED_INMAILS&matchType=EXACT&q=criteria&target.includedTargetingFacets.ageRanges[0]=AGE_18_24
  • Campaign reporting for a specific campaign, daily from 2019 (where it says 124782804, substitute in the campaign ID value retrieved from the list of ad campaigns):
    https://api.linkedin.com/v2/adAnalyticsV2?q=analytics&pivot=CAMPAIGN&dateRange.start.year=2021&dateRange.start.month=1&dateRange.start.day=1&dateRange.end.year=2021&dateRange.end.month=3&dateRange.end.day=31&timeGranularity=DAILY&campaigns[0]=urn:li:sponsoredCampaign:124782804&fields=externalWebsiteConversions,dateRange,impressions,landingPageClicks,likes,shares,costInLocalCurrency,pivot,pivotValue
    linkedin-api-img8

Part 5: Notes

  • As mentioned above, LinkedIn’s API requires pulling IDs and names separately, and then matching them up. This is easier when you have the ID in the first column to use as a key, so I suggest sorting each response through the visual field editor (click “Edit Fields” before you run your request).
  • There are 2 types of calls you can make to the Ads Reporting API: q=analytics and q=statistics. q=analytics is the method used in the examples above, and is used when you are only breaking your data down by a single pivot value. If you have two pivot values, use the q=statistics query string. According to LinkedIn’s documentation, you can pull in multiple pivot values at once with the q=statistics query string, but it doesn’t seem to work reliably.
  • This integration pulls advertising data from LinkedIn’s API into Google Sheets. It enables the following scopesr_ads (retrieve your advertising accounts), r_ads_reporting (retrieve reporting for your advertising accounts), and r_basicprofile (use your basic profile including your name, photo, headline, and current positions)

Part 6: Handle Pagination

For certain endpoints, LinkedIn’s API limits response data as described here:
linkedin-pagination-docs

To use API Connector’s automatic pagination handling, use offset-limit pagination as follows:
linkedin-pagination-offset

Part 7: API Documentation

Official API documentation: https://docs.microsoft.com/en-us/linkedin/marketing/integrations/ads-reporting/ads-reporting

Appendix: API Request Builder

This is a convenient tool for easily building LinkedIn API request URLs. Enter your account ID and select your dates, pivot dimension, and fields.

Once you’ve constructed your URL, you can copy and paste it into API Connector’s request URL input field. It will produce a performance report by ID, so run the metadata request URLs above, too, to get the corresponding account & campaign names. Here’s the link to get your own copy: LinkedIn API Request Builder

Previous Import Kraken Data to Google Sheets
Next Import Mailchimp Data to Google Sheets

42 thoughts on “Import LinkedIn Ads Data to Google Sheets”

  1. Can you post an example api using the q=statistics call? I’m trying to pull in multiple pivot values but I can’t seem to get it to work.

    Thanks

    Reply
    • Hey Brian! Can you please try something like this?
      https://api.linkedin.com/v2/adAnalyticsV2?q=statistics&pivots[0]=CAMPAIGN&pivots[1]=CREATIVE&dateRange.start.day=1&dateRange.start.month=1&dateRange.start.year=2019&timeGranularity=DAILY&campaigns[0]=urn:li:sponsoredCampaign:124782804&fields=externalWebsiteConversions,dateRange,impressions,landingPageClicks,likes,shares,costInLocalCurrency,pivot,pivotValues

      That seemed to work for me but I have a pretty limited data set to test on. Let me know how it goes.

      Reply
  2. Hi! This was incredibly helpful. Unfortunately all the campaign, campaign groups, creatives, and companies are coming in as numbers instead of using the actual names. So it’s very hard to match up which campaign goes with which campaign code. Is there an API that pulls in the name instead of just the value?

    Reply
    • Hey Kat! Thanks for the message. Can you please try this?
      https://api.linkedin.com/v2/adCampaignsV2/?q=search

      I believe it will return a list of all your campaigns with both names and IDs, so you can use that to match up the data from the other queries. There might be a better way but that’s how I did it :p. Let me know if that works for you.

      Reply
  3. Hi I was hoping you might be able to give me some guidance.
    I have all the data coming in fine, GREAT JOB, but i’m not able to pull any lead or conversion data from an Ad Campaign that is counting conversions as a download from LinkedIn itself.
    Do you have any ideas the ExternalConversions won’t work because its happening on LinkedIn. Thanks in Advance.

    Reply
    • I can’t say for sure, but if you click this #metrics-available link, you can see all the metrics that LinkedIn provides. I just looked through and some of these look they might be what you’re looking for: actionClicks, adUnitClicks, cardClicks, clicks, companyPageClicks, landingPageClicks, oneClickLeadFormOpens, oneClickLeads, totalEngagements. If you check the link you can see the descriptions of each metric, so please check and see if they get you what you need. If so, you’d just add them into the fields parameter of your request URL. Let me know if that works or you have any questions.

      Reply
  4. I cant seem to do a POST request using LinkedIn Connection?
    What is the reason for this? Is it because it is a paid feature or something else?

    Reply
    • Hey Ben, this is because LinkedIn’s API requires approval for each specific scope (permission). API Connector limits the scopes it requests to r_ads, r_ads_reporting, and r_basicprofile, which only allow getting, not posting, data. Sorry for the inconvenience. One option would be for you to create your own custom OAuth2 connection to Linkedin, then you could request whatever scopes you need. Or could you please let me know a bit more about what you’re trying to do? I will consider requesting additional scopes in the future.

      Reply
      • Hi Ana, I’m looking to generate many ads & campaigns in bulk for an ABM use case where we cite a company name. I have a Custom App with the necessary permissions.
        Maybe I can connect using that Connection using your custom Connection option?

      • Yeah, if you’ve already made your app on LinkedIn’s side, you should be able to set up API Connector’s custom OAuth2 connection like this:
        Name: Custom LinkedIn
        Authorization Base URL: https://www.linkedin.com/oauth/v2/authorization?scope=r_ads,r_ads_reporting,r_basicprofile (add on other scopes here)
        Token URL: https://www.linkedin.com/oauth/v2/accessToken
        Client ID: provided by LinkedIn
        Client Secret: provided by LinkedIn

        Custom OAuth gets added in the Manage Connections screen. As long as you add your ad management scopes to the base URL, you will be able to access whatever you need in LinkedIn’s API. Can you please try that and see how it goes?

  5. For this example, can I include 2 campaigns instead of 1? Also when I execute this request, I can only see data group by Campaign but not by Creative?

    https://api.linkedin.com/v2/adAnalyticsV2?q=statistics&pivots[0]=CAMPAIGN&pivots[1]=CREATIVE&dateRange.start.day=1&dateRange.start.month=1&dateRange.start.year=2019&timeGranularity=DAILY&campaigns[0]=urn:li:sponsoredCampaign:124782804&fields=externalWebsiteConversions,dateRange,impressions,landingPageClicks,likes,shares,costInLocalCurrency,pivot,pivotValues

    I want to pull data with basic metrics (impression, clicks etc) breakdown by date, campaigns (all campaigns in the account). Can I do it?

    Reply
    • I’m not sure why Campaign and Creative don’t work together. Based on LinkedIn’s documentation, you should be able to pivot 2 values together, but in my own tests I can only get one at a time, too. So to see all your campaigns you’ll need a query like this: https://api.linkedin.com/v2/adAnalyticsV2?q=statistics&pivots[0]=CAMPAIGN&dateRange.start.day=1&dateRange.start.month=1&dateRange.start.year=2021&timeGranularity=DAILY&fields=dateRange,impressions,approximateUniqueImpressions,videoViews,clicks,comments,reactions,totalEngagements,costInLocalCurrency,pivot,pivotValue&accounts[0]=urn:li:sponsoredAccount:502849368

      Substitute in your own account ID where it says 502849368.

      That will return a list of campaign IDs, so to get the campaign names you’ll need to run a second query to https://api.linkedin.com/v2/adCampaignsV2/?q=search

      Reply
  6. Hi,
    Thanks you so much for this instruction, very helpful and I came from knowing nothing how this works to almost managed to get everything I need 🙂 Could you maybe help me with the last bit? I managed to get demographic data with pivot on “member_company”, where I can see the company’s organization id. I need to match the ids with the organization names, but I can’t get the organization endpoint to work. Do you maybe have experience with this? Thanks in advance.

    Reply
    • You can get it via the projection and pivotValue~(localizedName) parameters, like this:
      https://api.linkedin.com/v2/adAnalyticsV2?q=analytics&dateRange.start.year=2021&dateRange.start.month=5&dateRange.start.day=28&dateRange.end.year=2021&dateRange.end.month=9&dateRange.end.day=30&timeGranularity=MONTHLY&accounts=urn:li:sponsoredAccount:502849368&pivot=MEMBER_COMPANY&projection=(*,elements*(externalWebsiteConversions,dateRange(*),impressions,landingPageClicks,likes,shares,costInLocalCurrency,approximateUniqueImpressions,pivot,pivotValue~(localizedName)))&fields=externalWebsiteConversions,dateRange,impressions,landingPageClicks,likes,shares,costInLocalCurrency,pivot,pivotValue

      Reply
  7. Hey, can you please help me to what the event registration refers to which field?
    And the api to get the event registration, click event registration, and view event registration.

    Thanks.

    Reply
  8. Hi, Can you help me providing an example of an api for pivot = CONVERSION?
    “pivot” (aka breakdown) values:
    COMPANY – Group results by advertiser’s company.
    ACCOUNT – Group results by account.
    CAMPAIGN – Group results by campaign.
    CREATIVE – Group results by creative.
    CONVERSION – Group results by conversion.

    Reply
    • I think it would be similar to the examples above, but with fields that make sense with the Conversions pivot, e.g.
      https://api.linkedin.com/v2/adAnalyticsV2?q=analytics&pivot=CONVERSION&dateRange.start.day=1&dateRange.start.month=1&dateRange.start.year=2021&timeGranularity=DAILY&accounts[0]=urn:li:sponsoredAccount:502849368&fields=conversionValueInLocalCurrency,externalWebsiteConversions,externalWebsitePostClickConversions,externalWebsitePostViewConversions,viralExternalWebsiteConversions,viralExternalWebsitePostClickConversions,viralExternalWebsitePostViewConversions
      Let me know if that works for you!

      Reply
  9. It looks like the ad creatives section is incorrect. What is posted is below and it looks like a call for Campaign Groups listed under ad creatives. Can you confirm this is incorrect and post the correct call? Thank you!

    List of ad creatives
    https://api.linkedin.com/v2/adCampaignGroupsV2?q=search

    Reply
    • Thank you, you’re right! It was a copy/paste error, I’ve updated it now. The correct URL is https://api.linkedin.com/v2/adCreativesV2?q=search

      Reply
  10. Hi Ana,
    I am having trouble with getting Creative names. For campaigns I can use “name” as a field and pull all the names from certain account in one call. But with the adCreatives I can’t seem to get it to work. Could you help? Thank you.

    Reply
    • Does https://api.linkedin.com/v2/adCreativesV2?q=search work for you? Or can you please share the URL you’re using for campaigns so I can better understand what you mean?

      Reply
      • Hi Ana,
        This will give a “Request would return too many entities” error. I’ve tried to narrow it down by campaign id (we have too many creatives so many other filters also give the too many entities error) from the link you mentioned in the article, (“Other filters are shown in LinkedIn’s API documentation under “Search for Campaigns”). When calling “https://api.linkedin.com/v2/adCreativesV2?q=search&search.id.values[0]=187020804” there is no error but there is no actual data returned either, I got “paging.start:0, paging.count:10, paging.llinks.1:empty, paging.total:0, elements.1:empty”. When trying to add field to the query, such as https://api.linkedin.com/v2/adCreativesV2?q=search&search.id.values[0]=187020804&fields=name, then I got “”serviceErrorCode”:100,”message”:”not enough permissions to access field name for GET-search /adCreativesV2″,”status”:403″.

      • This request worked for me:
        https://api.linkedin.com/v2/adCreativesV2?q=search&search.id.values[0]=43040964
        So if it didn’t work, I think that means you have the wrong ID.
        Also, I get the “not enough permissions to access field name for GET-searc” error too, but only if I include the fields=name fragment.

      • Continue from previous reply:
        BTW if I call https://api.linkedin.com/v2/adAnalyticsV2?q=statistics&pivots[0]=ACCOUNT&pivots[1]=CAMPAIGN&pivots[2]=CREATIVE…. I do get the correct data, so I guess it means I have permission to access this data. But with the adCreativesV2, I can’t get it working and I need the adCreativesV2 to see the names of the creatives

      • Can you try a request like this? That should cut down on the total number of fields.
        https://api.linkedin.com/v2/adCreativesV2?q=search&fields=id,campaign,type,status,variables

        I found a similar discussion here, based on that, the above should work for text ads but maybe not for video or other ads.

    • Hi Ana,
      thanks for your quick reply.

      This call still gives empty result, there is no error but the cells are empty. Could it be because we don’t have any Text Ads? The most we have are Sponsored Content. I read the post you sent as well, but I don’t know how to use projection in this case. Could you help? Thanks in advance.

      Reply
      • Yeah it looks like sponsored content requires a different kind of call. You’ll need to do it like this:
        1) get your ad creatives for a specific campaign: https://api.linkedin.com/v2/adCreativesV2?q=search&search.campaign.values[0]=urn:li:sponsoredCampaign:11111111
        2) It will return a field called elements.reference. Plug that value into a URL like this: https://api.linkedin.com/v2/adDirectSponsoredContents/urn:li:ugcPost:11111111
        That will return the name of your sponsored content.
        This is really a very awkward and inconvenient API. Maybe there’s an easier way but their documentation is too confusing for me to figure out 😛

  11. Hi. I have built a request for data with Account and Campaign pivots for multiple accounts – I am observing that the projection decoration does only work for single accounts – so now I do multiple requests for each account to get account + campaign details. Have you observed this too?

    Reply
    • Sorry, I don’t know much about using projection, but if you’d like to share your request URL, I could run it on this side and let you know if I get the same results.

      Reply
      • Single accounts request URL (= the one I am working with now):

        https://api.linkedin.com/v2/adAnalyticsV2?q=statistics&dateRange=(start:(day:1,month:1,year:2020))&timeGranularity=MONTHLY&pivots=List(CAMPAIGN,ACCOUNT)&fields=dateRange,impressions,clicks,costInLocalCurrency,costInUsd,totalEngagements,likes,comments,follows,shares,companyPageClicks,landingPageClicks,opens,externalWebsiteConversions,pivot,pivotValues&accounts=List(urn%3Ali%3AsponsoredAccount%3A${accountId})&count=500&projection=(*,elements*(*,pivotValues(*~sponsoredCampaign(id,name,type,status)~sponsoredAccount(id,name,type,status))))

        URL with a multiple advertising accounts – where I do not receive any data from the projected pivot fields:

        https://api.linkedin.com/v2/adAnalyticsV2?q=statistics&dateRange=(start:(day:1,month:1,year:2020))&timeGranularity=MONTHLY&pivots=List(CAMPAIGN,ACCOUNT)&fields=dateRange,impressions,clicks,costInLocalCurrency,costInUsd,totalEngagements,likes,comments,follows,shares,companyPageClicks,landingPageClicks,opens,externalWebsiteConversions,pivot,pivotValues&accounts=List(urn%3Ali%3AsponsoredAccount%3A${accountId1},urn%3Ali%3AsponsoredAccount%3A${accountId2},urn%3Ali%3AsponsoredAccount%3A${accountId3})&count=500&projection=(*,elements*(*,pivotValues(*~sponsoredCampaign(id,name,type,status)~sponsoredAccount(id,name,type,status))))

      • I can’t even get the first URL to run, I got errors related to the date format, the urn format, and permissions. Switching it to use Restli V1.0 helped, but still couldn’t resolve all the errors. Sorry about that, don’t think I can help with this one.

Leave a Comment

Table of Contents