
If you have ever tried to get LinkedIn campaign numbers out of Campaign Manager and into a spreadsheet, a dashboard, or an AI tool, the LinkedIn ads reporting API is the thing you are reaching for.
It is the read-only analytics layer of the LinkedIn Marketing API, and it is the only sanctioned way to pull impressions, clicks, spend, and conversions out of ad accounts at scale.
The reporting API is genuinely useful.
It is also narrower than most practitioners assume, and the gaps it leaves (no effective click rate to your landing page, no CRM join, last-touch platform-only attribution) are exactly the gaps that decide whether LinkedIn reporting tells the truth about the pipeline.
This post does two things.
Here’s a quick overview of the article:
adAnalytics endpoint) returns performance and demographic data. It does not create or edit campaigns. That is a separate part of the Marketing API.r_ads_reporting permission. Every call needs a LinkedIn-Version header and respects a data throttle of 45 million metric values per 5-minute window.
There is no single “LinkedIn ads API.”
There is a family of Marketing APIs: some manage account structure, some create and edit campaigns and creatives, and some handle lead forms and conversions.
The LinkedIn ads reporting API is the slice that returns analytics, and it is read-only by design. It answers what happened. It cannot change anything.
In LinkedIn’s own words, the reporting APIs “provide key insights on performance such as clicks, impressions, ad spend and professional demographics information such as metrics by professional demographic values at the account, campaign or creative levels.”
Everything funnels through one endpoint:
GET https://api.linkedin.com/rest/adAnalytics
That adAnalytics endpoint is the whole reporting surface.
The difference between pulling campaign performance, creative performance, or a breakdown by company comes down to the query parameters attached, not different URLs. One endpoint, a handful of finders, a set of pivots, and a list of metrics to opt into.
The read-only constraint shapes how any integration gets built.
The reporting API cannot pause a decaying ad, shift budget, or change a bid.
Those actions live in the campaign management part of the Marketing API, behind different permissions.
A reporting integration is, by nature, a one-way pipe: it reads, it never writes, and it cannot touch live ad serving.

The adAnalytics endpoint exposes its data through finder methods.
The finder is selected with the q query parameter.
There are three options, and choosing the right one is the first real decision in any reporting build.
The Analytics Finder, q=analytics, groups results by a single element called a pivot.
Creative-level numbers for a campaign come from pivoting by CREATIVE. A breakdown of which companies saw the ads comes from pivoting by MEMBER_COMPANY. One pivot, one grouping.
A minimal call looks like this:
GET https://api.linkedin.com/rest/adAnalytics ?q=analytics &pivot=CREATIVE &timeGranularity=ALL &dateRange=(start:(year:2026,month:1,day:1)) &campaigns=List(urn:li:sponsoredCampaign:1234567)
By default LinkedIn returns only impressions and clicks.
To get anything else, list the metrics in the fields parameter, up to 20 at a time.
The Statistics Finder, q=statistics, does the same job but accepts up to three pivots at once through the pivots parameter.
A single query can group by CAMPAIGN, then CREATIVE, then MEMBER_JOB_TITLE, and return a multi-dimensional cut without firing three separate calls.
It is the finder to reach for when building a richer table rather than a single list.
The third finder, q=attributedRevenueMetrics, is the newest and the most interesting for anyone who cares about pipeline.
It returns revenue attribution metrics: returnOnAdSpend, openOpportunities, revenueWonInUsd, closedWonOpportunities, averageDealSizeInUsd, and averageDaysToClose.
The catch is significant: these metrics are only available for accounts that have connected their CRM to LinkedIn. LinkedIn Business Manager must be set up, ad accounts claimed, and Salesforce, Dynamics 365, or HubSpot connected before any of this returns a number.
It also only supports ACCOUNT, CAMPAIGN_GROUP, and CAMPAIGN pivots, and the date range must sit inside the last year. More on why this is not the CRM join most B2B teams actually need appears in the limits section below.
Pivots are how the data gets sliced, and they are the most powerful idea in the whole reporting API. A pivot tells LinkedIn what each row in the response represents.
The performance pivots are the obvious ones: ACCOUNT, CAMPAIGN, CAMPAIGN_GROUP, and CREATIVE.
Then there are the professional demographic pivots, which are what make LinkedIn reporting genuinely different from other ad platforms.

These include MEMBER_COMPANY (which company the viewer works at), MEMBER_JOB_TITLE, MEMBER_COMPANY_SIZE, MEMBER_INDUSTRY, MEMBER_SENIORITY, MEMBER_JOB_FUNCTION, MEMBER_COUNTRY_V2, MEMBER_REGION_V2, and MEMBER_COUNTY.
The MEMBER_COMPANY pivot is the one B2B and ABM teams care about most, because it answers which accounts actually saw and engaged with the ads.
One honest caveat on company-level pivots: LinkedIn warns that a company-name pivot “can include companies that were not targeted in a campaign” because members work at more than one company or because audience expansion is on.
The data is directional, not a clean targeting audit.
The timeGranularity parameter controls how time is bucketed.
Three options are available:
There is a subtle retention rule attached to this. Performance data is retained for ten years, but professional demographics data is only kept for two years.
When timeGranularity=ALL is used with a date outside the six-month daily retention window, LinkedIn rounds it to a month boundary automatically, so a request that looks precise can quietly return a wider window than intended.
Date ranges use a nested object syntax that trips up everyone the first time.
A range is written as dateRange=(start:(year:2026,month:1,day:1),end:(year:2026,month:3,day:31)).
Leaving the end off runs the range open to everything after the start. LinkedIn returns a START_DATE_AFTER_END_DATE or DATE_TOO_EARLY error when the syntax is wrong.

By default the LinkedIn ads reporting API returns only impressions and clicks.
Everything else must be requested explicitly through the fields parameter, up to 20 metrics per call.
The common ones to reach for:
A real request with explicit fields, pivoting by company to see which accounts engaged:
GET https://api.linkedin.com/rest/adAnalytics ?q=analytics &pivot=MEMBER_COMPANY &timeGranularity=DAILY &dateRange=(start:(year:2026,month:5,day:1),end:(year:2026,month:5,day:31)) &accounts=List(urn:li:sponsoredAccount:502840441) &fields=externalWebsiteConversions,dateRange,impressions,landingPageClicks,likes,shares,costInLocalCurrency,pivotValues
The response comes back as a list of elements, one per pivot value per time bucket, with the requested metrics:
{ “elements”: [ { “pivotValues”: [“urn:li:organization:1111”], “dateRange”: { “start”: {“year”:2026,”month”:5,”day”:29}, “end”: {“year”:2026,”month”:5,”day”:29} }, “impressions”: 165, “landingPageClicks”: 11, “costInLocalCurrency”: “19.91833”, “shares”: 0, “likes”: 0, “externalWebsiteConversions”: 0 } ] }
Notice that pivotValues come back as URNs, like urn:li:organization:1111, not human-readable names. Turning that into “Acme Corp” requires a second call to the URN resolution APIs.
That is a small thing, but it is the kind of small thing that adds up to a real engineering project when done across every company, job title, and creative in an account.
Getting data out requires four moving parts: access, auth, versioning, and the Rest.li protocol header.
First comes the application process.
Create a LinkedIn Page, register a developer application in the LinkedIn Developer Portal, and apply for the Advertising API under the Products tab.
Reporting calls need one permission: r_ads_reporting, which lets the application “retrieve reporting for advertising accounts.”
Development tier access maps to specific ad account IDs, and a tier upgrade request with a video demonstrating the platform is required to reach the standard tier.
Authentication is 3-legged OAuth 2.0. A user with access to the ad account authorizes the app, the code gets exchanged for an access token, and that token goes into the Authorization header as a Bearer token.
The token has a finite life, so any real integration also handles refresh. Tokens expire, scopes change, and a broken token means a silent gap in reporting.
Every reporting call carries two headers beyond auth.
A LinkedIn-Version header in YYYYMM format pins the API version, and X-Restli-Protocol-Version: 2.0.0 sets the protocol.
The versioning is monthly, and older versions get sunset on a schedule: the May 2025 marketing version has already been retired, so any integration built against it and left unmaintained will receive deprecation warnings.

A full call looks like this:
curl -X GET ‘https://api.linkedin.com/rest/adAnalytics?q=analytics&pivot=CAMPAIGN&timeGranularity=DAILY&dateRange=(start:(year:2026,month:1,day:1))&accounts=List(urn:li:sponsoredAccount:1234567)&fields=impressions,clicks,costInLocalCurrency,landingPageClicks’ -H ‘Authorization: Bearer {TOKEN}’ -H ‘LinkedIn-Version: 202605’ -H ‘X-Restli-Protocol-Version: 2.0.0’
The reporting API throttles on data volume, not just request count.
The ceiling is 45 million metric values in any rolling 5-minute window, where a metric value is one metric for one record: request 9 metrics across 2 daily records and that is 18 metric values.
Cross the ceiling, and the API returns a 429 TOO_MANY_REQUESTS.
There is also a 15,000-element cap on any single response and no pagination on this endpoint, so large pulls have to be chunked by date or facet.
None of this is difficult individually, but all of it is plumbing that must be maintained forever once built.
Everything above is the API working as designed.
This section covers where it stops, because that is what decides whether reporting is useful or merely accurate.
The reporting API gives you clicks and landingPageClicks, but a “click” on LinkedIn includes likes, comments, shares, and reactions, not just people who went to the landing page.
There is no field that gives the effective click-through rate to the landing page, which is what actually matters for a paid campaign. There is no effective cost per landing-page click either.
Both can be computed from landingPageClicks, impressions, and costInLocalCurrency, but that calculation has to be done deliberately and consistently across every ad format.
For Thought Leader Ads, where social engagement dwarfs landing-page traffic, the raw CTR number is wildly flattering, and the effective rate is the only one that tells the truth.
The conversions the reporting API reports are LinkedIn’s own.
They are last-touch within the LinkedIn ecosystem, measured by the Insight Tag or the Conversions API, and they stop at the platform boundary.
The Attributed Revenue Metrics finder helps, but it only works with Business Manager and a supported CRM wired up, and even then, it reasons in LinkedIn’s attribution model, not the advertiser’s.
Chris Chambers put the underlying problem well when describing a B2B account that looked perfect on platform metrics in his LinkedIn post:
“CPA was $180. They were getting 200+ leads per month. Conversion rate was climbing. The founder was pumped. Then I asked to see the closed deals over the last 6 months. Twelve. Twelve total customers from 1,200+ leads. Volume is a vanity metric in B2B SaaS. Pipeline is what matters.”
The example is from Google Ads, but the lesson is identical on LinkedIn.
The reporting API can confirm that a campaign generated activity.
It cannot confirm that the activity became revenue, because it cannot see the pipeline.
The reporting API has no idea which company in the MEMBER_COMPANY pivot has an open deal worth $80,000 and which is a tire-kicker.
Answering “which campaigns influenced closed-won revenue” requires joining LinkedIn’s company URNs to CRM accounts, deduplicating them, and stitching a timeline.
That is a data engineering job, not a reporting query.
Even the MEMBER_COMPANY pivot, the one ABM teams want most, comes with strings.
Demographic pivots only return the top 100 values per creative per day, drop any value with fewer than 3 events to protect privacy, do not support carousel metrics, and can lag 12 to 24 hours behind performance data.
Building a clean, complete, daily view of which accounts engaged with which ad is not a single call. It is many calls, deduplicated, resolved from URNs to names, and reconciled against the target account list.
ZenABM handles this resolution step automatically, mapping organization URNs to named accounts and linking them to their ABM funnel stage and CRM deal status, so the company-level view is immediately actionable rather than a list of URN strings.




And the best part is that all these and more capabilities of ZenABM can be directly accessed from your Claude Code or Codex terminal – you just have to set up the ZenABM MCP server.

The real limit is not any single missing metric. It is that the LinkedIn ads reporting API hands over raw materials and leaves the construction to the buyer: OAuth refresh, monthly version bumps, URN resolution, throttle math, chunking, the CRM join, the eCTR calculation.
Every piece is doable, but together they constitute a standing engineering commitment that quietly breaks when LinkedIn ships a new version or a token lapses.
ZenABM is built precisely on the gaps above.
Under the hood, it reads the same LinkedIn ads reporting API described here.
On top of it, it does the work that would otherwise be done by hand.
It adds the two metrics the API does not give natively: eCTR, the effective click-through rate to your landing page, and eCPC, the effective cost per landing-page click. It performs the CRM and deal join, so a company in the reporting output is linked to its open and closed-won deals rather than an anonymous organization URN.
And it exposes all of it over the Model Context Protocol, so instead of writing finder calls, the question gets asked in plain English inside Claude, ChatGPT, or Cursor, and the AI picks from 60+ tools, pulls the live data, and returns a structured answer.


Questions that previously required a finder call, a URN resolution pass, and a spreadsheet formula become a single sentence.
On safety, the design mirrors the read-only nature of the reporting API.
Read queries never change anything.
Write actions, like pausing an ad, are flagged as destructive and require explicit confirmation before they run, so there is no risk of the AI quietly turning off a campaign.
Because the deal join is built in, the revenue questions the reporting API cannot answer become answerable.
For where the numbers should land, the 2026 LinkedIn ABM benchmarks provide a reference point.




The LinkedIn ads reporting API is one of the most useful read-only data sources in B2B advertising, and one of the most misunderstood.
It returns rich performance and demographic data across campaigns, creatives, and accounts. It does not return the numbers that actually tell the pipeline story: no eCTR to your landing page, no eCPC, no deal join, and no attribution beyond LinkedIn’s own last-touch model.
Understanding what the API gives and what it withholds is what separates a reporting setup that answers “what happened” from one that answers “what it was worth.”
The finders, pivots, and metric fields covered here are the building blocks.
The gaps are in the construction project.
ZenABM sits on top of the reporting API and closes those gaps without requiring construction of the project.
It adds eCTR, eCPC, and the CRM deal join, exposes everything over MCP so it can be queried in plain English, and keeps the read-only safety contract intact. If the goal is LinkedIn reporting that ends in a pipeline rather than a spreadsheet of impressions, it is the shortest path from the API to an answer.
Start a free 37-day trial and connect your LinkedIn Ads account in under five minutes, or book a demo to know more!
It is the read-only analytics layer of the LinkedIn Marketing API. It pulls campaign, creative, account, and demographic performance data (impressions, clicks, spend, landing-page clicks, conversions) out of ad accounts at scale, into a spreadsheet, dashboard, warehouse, or AI tool. It does not create or edit campaigns.
Both hit the same adAnalytics endpoint. The Analytics Finder (q=analytics) groups by a single pivot, making it the right choice for one-dimensional lists like creative-level performance. The Statistics Finder (q=statistics) groups by up to three pivots at once, making it the right choice for multi-dimensional tables in a single call.
By default just impressions and clicks. Through the fields parameter, up to 20 metrics can be requested per call, including costInLocalCurrency, landingPageClicks, externalWebsiteConversions, likes, shares, comments, follows, and video watch time. There is no native effective click-through rate or effective cost per landing-page click, so eCTR and eCPC must be computed manually or through a tool that adds them.
Authentication uses 3-legged OAuth 2.0 with the r_ads_reporting permission. Every call also needs a LinkedIn-Version header in YYYYMM format and the X-Restli-Protocol-Version: 2.0.0 header. Advertising API access requires an application in the LinkedIn Developer Portal first.
Only partially. The Attributed Revenue Metrics finder returns return-on-ad-spend and opportunity data, but only for accounts with a supported CRM connected to LinkedIn Business Manager, and it reasons in LinkedIn’s last-touch attribution model. For a flexible CRM and deal join using a custom attribution model, the reporting data needs to be connected to the CRM separately, or a tool like ZenABM can handle the join and add eCTR and eCPC on top.