LinkedIn Ad Library Keyword & Advertiser Scraper
Search the public LinkedIn Ad Library by keyword, advertiser, country, or date range, and get headline, body copy, advertiser info, media URLs, and call-to-action for the ads each search returns.
Input schema
Input fields, types, required flags, descriptions, defaults, and prefills come from the published definition. Prefill examples are distinct from defaults.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | optional | What to collect: search the library, open specific ads, process pasted URLs, or count matches only. |
searchTerms | array | optional | One or more keyword searches, e.g. 'AI' or 'cloud computing'. Each keyword is an independent search (union), not a combination. |
advertisers | array | optional | Advertiser names (fuzzy accountOwner search) or LinkedIn company URLs. Each name is an independent search. Use companyIds for exact matching. |
Show all input fields
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | optional | What to collect: search the library, open specific ads, process pasted URLs, or count matches only. |
searchTerms | array | optional | One or more keyword searches, e.g. 'AI' or 'cloud computing'. Each keyword is an independent search (union), not a combination. |
advertisers | array | optional | Advertiser names (fuzzy accountOwner search) or LinkedIn company URLs. Each name is an independent search. Use companyIds for exact matching. |
companyIds | array | optional | Exact numeric LinkedIn company IDs (for example, Microsoft is 1035). Multiple IDs are OR-ed in one exact search. Company URLs are accepted too. |
companyUrls | array | optional | LinkedIn company page URLs. The actor resolves each public page to its numeric organization ID and searches it exactly. |
payer | array | optional | Search ads by the legal entity that paid for them, e.g. 'Microsoft Corporation'. Each payer is an independent search. |
advertiserMatch | string | optional | Client-side precision for advertiser-name searches. Exact company IDs are never filtered. 'Starts with' removes partner-noise results while keeping names such as 'Microsoft in Business'. |
countries | array | optional | ISO-3166 alpha-2 delivery country codes (US, GB, DE, ...) or ALL. Multiple codes are sent in one comma-separated filter. |
dateOption | string | optional | LinkedIn's date window. Use custom-date-range with startDate/endDate for an exact period (maximum 12 months back). |
startDate | string | optional | Start of a custom range (YYYY-MM-DD). Required when dateOption is custom-date-range. |
endDate | string | optional | End of a custom range (YYYY-MM-DD). Required when dateOption is custom-date-range. |
sortOrder | string | optional | Newest first or oldest first. |
impressionsMinValue | integer | optional | Lower bound of the impression range (EU transparency data only). LinkedIn requires both a minimum and a maximum value. |
impressionsMinUnit | string | optional | Unit for the minimum impression value. |
impressionsMaxValue | integer | optional | Upper bound of the impression range (EU transparency data only). Required together with the minimum value. |
impressionsMaxUnit | string | optional | Unit for the maximum impression value. |
targetingIncluded | array | optional | Filters ads that target any of these categories (EU transparency data only). Values: LANGUAGE, LOCATION, AUDIENCE, DEMOGRAPHIC, COMPANY, EDUCATION, JOB, INTERESTS_AND_TRAITS. |
targetingExcluded | array | optional | Filters ads that exclude any of these categories (EU transparency data only). Values: LANGUAGE, LOCATION, AUDIENCE, DEMOGRAPHIC, COMPANY, EDUCATION, JOB, INTERESTS_AND_TRAITS. |
includeDetails | boolean | optional | Open each ad's detail page for full copy, CTA, landing URL, video, payer, and EU transparency data. Adds one request per ad. |
decodeShortLinks | boolean | optional | Resolve lnkd.in and similar short links to their final landing URL. Adds one request per short link. |
adIds | array | optional | Numeric ad IDs or linkedin.com/ad-library/detail/... URLs. Used by mode adDetails. |
directUrls | array | optional | Pasted Ad Library search URLs, ad detail URLs, or LinkedIn company page URLs. Search filters are preserved. |
maxItems | integer | optional | Global cap on ads returned across all searches (1-4800). Each search can return at most 4,800 ads (200 pages of 24). |
Download the published input schema
View complete JSON
{
"description": "Search the public LinkedIn Ad Library, scrape specific ads, or count matches. Every keyword, advertiser, payer, and company-ID group becomes its own search; country, date, sort, impression, and targeting filters apply to all searches.",
"properties": {
"adIds": {
"default": [],
"description": "Numeric ad IDs or linkedin.com/ad-library/detail/... URLs. Used by mode adDetails.",
"editor": "stringList",
"example": [
"1611810664"
],
"items": {
"type": "string"
},
"title": "Ad IDs or Detail URLs",
"type": "array"
},
"advertiserMatch": {
"default": "startsWith",
"description": "Client-side precision for advertiser-name searches. Exact company IDs are never filtered. 'Starts with' removes partner-noise results while keeping names such as 'Microsoft in Business'.",
"editor": "select",
"enum": [
"any",
"startsWith",
"exact"
],
"enumTitles": [
"Any match",
"Starts with",
"Exact name"
],
"title": "Advertiser Name Match",
"type": "string"
},
"advertisers": {
"default": [],
"description": "Advertiser names (fuzzy accountOwner search) or LinkedIn company URLs. Each name is an independent search. Use companyIds for exact matching.",
"editor": "stringList",
"example": [
"Microsoft",
"Anthropic"
],
"items": {
"type": "string"
},
"title": "Advertisers",
"type": "array"
},
"companyIds": {
"default": [],
"description": "Exact numeric LinkedIn company IDs (for example, Microsoft is 1035). Multiple IDs are OR-ed in one exact search. Company URLs are accepted too.",
"editor": "stringList",
"example": [
"1035",
"3608"
],
"items": {
"type": "string"
},
"prefill": [
"1035"
],
"title": "LinkedIn Company IDs",
"type": "array"
},
"companyUrls": {
"default": [],
"description": "LinkedIn company page URLs. The actor resolves each public page to its numeric organization ID and searches it exactly.",
"editor": "stringList",
"example": [
"https://www.linkedin.com/company/microsoft"
],
"items": {
"type": "string"
},
"title": "Company URLs",
"type": "array"
},
"countries": {
"default": [],
"description": "ISO-3166 alpha-2 delivery country codes (US, GB, DE, ...) or ALL. Multiple codes are sent in one comma-separated filter.",
"editor": "stringList",
"example": [
"US",
"DE"
],
"items": {
"type": "string"
},
"title": "Countries",
"type": "array"
},
"dateOption": {
"default": "last-30-days",
"description": "LinkedIn's date window. Use custom-date-range with startDate/endDate for an exact period (maximum 12 months back).",
"editor": "select",
"enum": [
"any-time",
"last-30-days",
"current-month",
"current-year",
"last-year",
"custom-date-range"
],
"enumTitles": [
"Any time",
"Last 30 days",
"Current month",
"Current year",
"Last year",
"Custom date range"
],
"prefill": "last-30-days",
"title": "Date Range",
"type": "string"
},
"decodeShortLinks": {
"default": false,
"description": "Resolve lnkd.in and similar short links to their final landing URL. Adds one request per short link.",
"editor": "checkbox",
"title": "Decode Short Links",
"type": "boolean"
},
"directUrls": {
"default": [],
"description": "Pasted Ad Library search URLs, ad detail URLs, or LinkedIn company page URLs. Search filters are preserved.",
"editor": "requestListSources",
"example": [
{
"url": "https://www.linkedin.com/ad-library/search?keyword=AI&countries=US"
}
],
"title": "Direct URLs",
"type": "array"
},
"endDate": {
"description": "End of a custom range (YYYY-MM-DD). Required when dateOption is custom-date-range.",
"editor": "textfield",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"title": "End Date",
"type": "string"
},
"impressionsMaxUnit": {
"default": "none",
"description": "Unit for the maximum impression value.",
"editor": "select",
"enum": [
"none",
"thousand",
"million"
],
"enumTitles": [
"Units",
"Thousands",
"Millions"
],
"title": "Maximum Impressions Unit",
"type": "string"
},
"impressionsMaxValue": {
"description": "Upper bound of the impression range (EU transparency data only). Required together with the minimum value.",
"editor": "number",
"maximum": 1000000000,
"minimum": 0,
"title": "Maximum Impressions Value",
"type": "integer"
},
"impressionsMinUnit": {
"default": "none",
"description": "Unit for the minimum impression value.",
"editor": "select",
"enum": [
"none",
"thousand",
"million"
],
"enumTitles": [
"Units",
"Thousands",
"Millions"
],
"title": "Minimum Impressions Unit",
"type": "string"
},
"impressionsMinValue": {
"description": "Lower bound of the impression range (EU transparency data only). LinkedIn requires both a minimum and a maximum value.",
"editor": "number",
"maximum": 1000000000,
"minimum": 0,
"title": "Minimum Impressions Value",
"type": "integer"
},
"includeDetails": {
"default": true,
"description": "Open each ad's detail page for full copy, CTA, landing URL, video, payer, and EU transparency data. Adds one request per ad.",
"editor": "checkbox",
"prefill": true,
"title": "Include Detail Pages",
"type": "boolean"
},
"maxItems": {
"default": 50,
"description": "Global cap on ads returned across all searches (1-4800). Each search can return at most 4,800 ads (200 pages of 24).",
"editor": "number",
"maximum": 4800,
"minimum": 1,
"prefill": 3,
"title": "Maximum Records",
"type": "integer"
},
"mode": {
"default": "search",
"description": "What to collect: search the library, open specific ads, process pasted URLs, or count matches only.",
"editor": "select",
"enum": [
"search",
"adDetails",
"directUrls",
"count"
],
"enumTitles": [
"Search the Ad Library",
"Specific ad IDs / detail URLs",
"Pasted Ad Library / company URLs",
"Count matches only"
],
"prefill": "search",
"title": "Mode",
"type": "string"
},
"payer": {
"default": [],
"description": "Search ads by the legal entity that paid for them, e.g. 'Microsoft Corporation'. Each payer is an independent search.",
"editor": "stringList",
"example": [
"Microsoft Corporation"
],
"items": {
"type": "string"
},
"title": "Paid for by (payer)",
"type": "array"
},
"searchTerms": {
"default": [],
"description": "One or more keyword searches, e.g. 'AI' or 'cloud computing'. Each keyword is an independent search (union), not a combination.",
"editor": "stringList",
"example": [
"AI",
"cloud computing"
],
"items": {
"type": "string"
},
"title": "Keywords",
"type": "array"
},
"sortOrder": {
"default": "newest",
"description": "Newest first or oldest first.",
"editor": "select",
"enum": [
"newest",
"oldest"
],
"enumTitles": [
"Newest first",
"Oldest first"
],
"title": "Sort Order",
"type": "string"
},
"startDate": {
"description": "Start of a custom range (YYYY-MM-DD). Required when dateOption is custom-date-range.",
"editor": "textfield",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"title": "Start Date",
"type": "string"
},
"targetingExcluded": {
"default": [],
"description": "Filters ads that exclude any of these categories (EU transparency data only). Values: LANGUAGE, LOCATION, AUDIENCE, DEMOGRAPHIC, COMPANY, EDUCATION, JOB, INTERESTS_AND_TRAITS.",
"editor": "stringList",
"example": [
"COMPANY"
],
"items": {
"type": "string"
},
"title": "Excluded Targeting Facets",
"type": "array"
},
"targetingIncluded": {
"default": [],
"description": "Filters ads that target any of these categories (EU transparency data only). Values: LANGUAGE, LOCATION, AUDIENCE, DEMOGRAPHIC, COMPANY, EDUCATION, JOB, INTERESTS_AND_TRAITS.",
"editor": "stringList",
"example": [
"LANGUAGE",
"JOB"
],
"items": {
"type": "string"
},
"title": "Included Targeting Facets",
"type": "array"
}
},
"required": [],
"schemaVersion": 1,
"title": "LinkedIn Ad Library Scraper Input",
"type": "object"
}
Output schema
Published result links and storage locations. This schema is not an exhaustive contract for every field in a dataset record.
| Field | Type | Required | Description |
|---|---|---|---|
ads | string | optional | All scraped ad records and count rows. Use recordType to separate them. |
Download the published output schema
View complete JSON
{
"actorOutputSchemaVersion": 1,
"description": "Dataset of LinkedIn Ad Library ads (recordType='ad') or match-count rows (recordType='count'). Empty fields are omitted at every depth.",
"properties": {
"ads": {
"description": "All scraped ad records and count rows. Use recordType to separate them.",
"template": "{{links.apiDefaultDatasetUrl}}/items",
"title": "LinkedIn Ad Library records",
"type": "string"
}
},
"title": "LinkedIn Ad Library Output"
}
Dataset schema
Published dataset views and any declared field definitions. A view can select only a subset of the returned record fields.
Download the published dataset schema
View complete JSON
{
"actorSpecification": 1,
"title": "LinkedIn Ad Library",
"views": {
"creatives": {
"display": {
"component": "table",
"properties": {
"ad_format": {
"format": "text",
"label": "Format"
},
"ad_url": {
"format": "link",
"label": "Ad URL"
},
"advertiser_name": {
"format": "text",
"label": "Advertiser"
},
"body_text_full": {
"format": "text",
"label": "Full copy"
},
"headline": {
"format": "text",
"label": "Headline"
},
"image_urls": {
"format": "text",
"label": "Images"
},
"landing_url": {
"format": "link",
"label": "Landing"
},
"video_poster_url": {
"format": "image",
"label": "Poster"
},
"video_urls": {
"format": "text",
"label": "Videos"
}
}
},
"title": "Creatives",
"transformation": {
"fields": [
"advertiser_name",
"ad_format",
"headline",
"body_text_full",
"image_urls",
"video_urls",
"video_poster_url",
"landing_url",
"ad_url"
]
}
},
"euTargeting": {
"display": {
"component": "table",
"properties": {
"ad_url": {
"format": "link",
"label": "Ad URL"
},
"advertiser_name": {
"format": "text",
"label": "Advertiser"
},
"country": {
"format": "text",
"label": "Country"
},
"impressions_by_country": {
"format": "text",
"label": "Country shares"
},
"targeting_language": {
"format": "text",
"label": "Language"
},
"targeting_location_included": {
"format": "text",
"label": "Locations"
},
"targeting_parameters": {
"format": "text",
"label": "Targeting parameters"
},
"total_impressions": {
"format": "text",
"label": "Impressions"
}
}
},
"title": "EU Transparency",
"transformation": {
"fields": [
"advertiser_name",
"country",
"total_impressions",
"impressions_by_country",
"targeting_language",
"targeting_location_included",
"targeting_parameters",
"ad_url"
]
}
},
"overview": {
"display": {
"component": "table",
"properties": {
"ad_format": {
"format": "text",
"label": "Format"
},
"ad_url": {
"format": "link",
"label": "Ad URL"
},
"advertiser_name": {
"format": "text",
"label": "Advertiser"
},
"body_text": {
"format": "text",
"label": "Copy preview"
},
"country": {
"format": "text",
"label": "Country"
},
"cta_text": {
"format": "text",
"label": "CTA"
},
"end_date": {
"format": "date",
"label": "End"
},
"headline": {
"format": "text",
"label": "Headline"
},
"start_date": {
"format": "date",
"label": "Start"
},
"total_impressions": {
"format": "text",
"label": "Impressions"
}
}
},
"title": "Overview",
"transformation": {
"fields": [
"advertiser_name",
"ad_format",
"headline",
"body_text",
"cta_text",
"start_date",
"end_date",
"total_impressions",
"country",
"ad_url"
]
}
}
}
}
Key-value schema
Published key-value store definitions, when provided by this build.
This definition is not present in the default published build. See the published README for available documentation.
Published README
Read the full published documentation
LinkedIn Ad Library Keyword & Advertiser Scraper
Search the public LinkedIn Ad Library without an account, cookies, or a login. Collect paginated ads by keyword, advertiser name, payer, exact company ID, or a pasted Ad Library URL — then enrich each ad with its full copy, CTA, landing URL, video, paying entity, and the EU transparency block (run dates, impression range, country shares, and targeting).
The actor is built for competitor research, creative monitoring, and B2B ad intelligence. It reads the same public pages a logged-out visitor sees, so it works with zero credentials.
Modes
| Mode | What it does | Inputs it uses |
|---|---|---|
search (default) |
Builds one search per keyword / advertiser / payer / company-ID group, paginates it, dedupes by ad ID, and optionally opens every detail page. | searchTerms, advertisers, companyIds, companyUrls, payer, filters |
adDetails |
Re-scrapes specific ads from their IDs or detail URLs. | adIds, directUrls (detail URLs) |
directUrls |
Accepts pasted Ad Library search URLs, company URLs, and ad detail URLs. Search filters are preserved. | directUrls |
count |
Returns the total number of matching ads per search, without pagination. | The same search inputs |
Every keyword, advertiser, payer, and company-ID group is an independent search (a union). Filters such as country, date, sort, impressions, and targeting apply to all of them.
Inputs
| Input | Type | Default | Description |
|---|---|---|---|
mode |
Select | search |
search, adDetails, directUrls, or count. |
searchTerms |
String list | [] |
Keyword searches. |
advertisers |
String list | [] |
Advertiser names (fuzzy) or LinkedIn company URLs. |
companyIds |
String list | [] |
Exact numeric LinkedIn company IDs; multiple IDs are OR-ed. URLs are accepted. |
companyUrls |
String list | [] |
Company page URLs, resolved to their numeric organization ID. |
payer |
String list | [] |
Legal entity that paid for the ad. |
advertiserMatch |
Select | startsWith |
Client-side precision for advertiser-name searches: any, startsWith, exact. |
countries |
String list | [] |
ISO-3166 alpha-2 codes (US, GB, DE) or ALL. Multiple codes are comma-joined. |
dateOption |
Select | last-30-days |
any-time, last-30-days, current-month, current-year, last-year, custom-date-range. |
startDate / endDate |
String | — | Required for custom-date-range (YYYY-MM-DD, within the last 12 months). |
sortOrder |
Select | newest |
newest or oldest. |
impressionsMinValue / impressionsMaxValue |
Integer | — | EU impression range. LinkedIn requires both values. |
impressionsMinUnit / impressionsMaxUnit |
Select | none |
none, thousand, or million. |
targetingIncluded / targetingExcluded |
String list | [] |
EU targeting facets: LANGUAGE, LOCATION, AUDIENCE, DEMOGRAPHIC, COMPANY, EDUCATION, JOB, INTERESTS_AND_TRAITS. |
includeDetails |
Boolean | true |
Open each ad's detail page for full copy, CTA, landing URL, video, payer, and EU data. |
decodeShortLinks |
Boolean | false |
Resolve lnkd.in and similar short links to the final landing URL. |
adIds |
String list | [] |
Ad IDs or detail URLs, for adDetails. |
directUrls |
URL list | [] |
Pasted Ad Library search/detail URLs or company URLs. |
maxItems |
Integer | 50 |
Global cap per run (1–4,800). |
Prefill
The default prefill is the smallest run with a reliable result: Microsoft's exact company ID, the last 30 days, three ads, and detail enrichment on.
{
"mode": "search",
"companyIds": ["1035"],
"dateOption": "last-30-days",
"includeDetails": true,
"maxItems": 3
}
Example — keyword search, card data only
{
"searchTerms": ["AI", "machine learning"],
"countries": ["US", "DE"],
"dateOption": "last-30-days",
"includeDetails": false,
"maxItems": 100
}
Example — exact advertiser with EU transparency
{
"companyIds": ["1035"],
"countries": ["DE"],
"dateOption": "last-year",
"includeDetails": true,
"maxItems": 200
}
Example — re-scrape specific ads
{
"mode": "adDetails",
"adIds": ["1611810664", "https://www.linkedin.com/ad-library/detail/1658527466"]
}
Example — count only
{
"mode": "count",
"searchTerms": ["AI"],
"countries": ["US"],
"dateOption": "last-30-days"
}
Output
Each ad is one dataset row with recordType: "ad". Count mode emits recordType: "count" rows. Empty values are removed at every depth — there are no null, empty-string, empty-array, or sentinel rows.
Ad fields
| Field | Description |
|---|---|
ad_id |
LinkedIn ad / creative ID. |
ad_url |
Public Ad Library detail URL. |
recordType |
ad. |
sourceUrl |
The search URL or detail URL that produced the row. |
scrapedAt / scraped_at |
ISO 8601 UTC scrape timestamp (scraped_at is the legacy alias). |
advertiser_name, advertiser_id, advertiser_url, advertiser_logo, advertiser_tagline |
Advertiser identity. advertiser_id is a numeric company ID when available, otherwise a member/showcase slug. |
paid_for_by |
Paying legal entity from the detail page. |
ad_format, creative_type, format_label |
Normalized format (image, video, carousel, document, message, spotlight, job, event, article, follow_company, dynamic, text) plus the raw creative type and LinkedIn's label. |
headline |
Ad headline when present. |
body_text |
Copy preview from the search card (or the full preview when scraping a detail URL directly). |
body_text_full |
Full detail-page copy (up to roughly 2,700 characters). |
cta_text |
CTA button text (Learn more, Register, ...). |
landing_url, landing_url_raw, landing_domain, is_shortlink |
Cleaned landing URL (only the trk parameter is removed), original URL, hostname, and short-link flag. |
media |
List of {type, url, expiresAt} entries (image, poster, video). |
media_urls, image_urls, video_urls, video_poster_url |
Flat media lists for compatibility and convenience. |
start_date, end_date, duration_days, is_active |
Run dates and duration from the EU transparency block. is_active is only present when an end date exists. |
total_impressions, impressions_min, impressions_max |
Impression range label and parsed bounds. |
impressions_by_country |
{country, shareRaw, sharePct, isUpperBound?, isLowerBound?, estimatedMin?, estimatedMax?} rows. |
targeting_language, targeting_location_included, targeting_location_excluded, targeting_parameters |
EU targeting data. Parameters are {category, targeted, excluded} rows. |
has_dsa_data |
Always a boolean. false means LinkedIn did not publish the EU transparency block for that ad. |
country, top_country |
The single delivery-country filter when one is set; the largest impression-share country from the DSA block. |
variants_count |
Number of creative variants on the detail page. |
Count fields
| Field | Description |
|---|---|
recordType |
count. |
sourceUrl |
The search URL used. |
scrapedAt / scraped_at |
ISO timestamp. |
query, queryType, queryValue |
The search label, e.g. keyword, advertiser, payer, companyIds, filters. |
totalCount |
LinkedIn's reported number of matching ads. |
Pagination, dedupe, and limits
- The Ad Library returns 24 ads per page and exposes a pagination token.
- The actor follows up to 200 pages (4,800 ads) per search, then stops. This is the practical ceiling the Ad Library accepts.
- Results are deduplicated by
ad_idacross pages and searches. maxItemsis a global cap across all searches (1–4,800). It trims the final page exactly.- Broad searches can match hundreds of thousands of ads. Slice them by country, date window, keyword, or exact company IDs to reach more than 4,800 rows.
maxItemslimits rows, not requests: withincludeDetails: true, one detail request is made per collected ad (up to the cap).
Reliability and errors
- The actor uses
curl_cffiwith a Chrome 131 TLS fingerprint and a fresh Apify Proxy AUTO session/IP for every request (sticky sessions fail when they land on a blocked IP). Each request is retried up to five times with backoff. - If AUTO stays blocked, the actor tries a headless browser on AUTO, then the Apify UNBLOCKER group for that request. Proxy setup is automatic; there is no proxy input.
- Partial runs are reported honestly in the status message. If some searches are blocked and others return data, the dataset keeps the good rows and the status says how many queries were blocked.
- If every request is blocked, or a search that should return data comes back empty, the run fails with a clear message. It never pushes a fake "blocked" row.
- Detail-page failures (404/410 or a transient block) keep the card record and log the failure.
- A legitimate
0 resultssearch also fails the run with an explicit "0 results" message rather than silently succeeding with an empty dataset. - A run summary (pages, details, query statuses) is saved to the key-value store as
run_summary.
FAQ
Do I need a LinkedIn account or cookies? No. The Ad Library is public guest content. The actor makes the same anonymous requests the public site does.
Do I need to configure a proxy? No. The actor selects and rotates its proxy automatically.
Why do some ads lack impressions, dates, or targeting?
LinkedIn only publishes that transparency block for ads served in the EU. Non-EU ads have no run dates, impression range, country shares, or targeting data. The has_dsa_data flag tells you which is which. This is a source limitation, not a scraper bug.
Why are media URLs signed?
LinkedIn CDN URLs carry an e= expiry parameter. The actor exposes the URL and its expiresAt date in media[].expiresAt. Download or archive media before it expires if you need a permanent copy.
What is the difference between advertisers and companyIds?
advertisers is a fuzzy name search and can include partners or resellers. companyIds is exact and is the best way to collect only a specific company's ads.
Why is body_text shorter than body_text_full?
The search card shows a truncated preview. body_text_full comes from the detail page and is only present when includeDetails is on (or when the mode is adDetails).
How do I get more than 4,800 ads?
Split the request by country, date range, keyword, or company ID and run each slice separately. Deduplicate downstream by ad_id if slices overlap.
Can I see spend, budget, CTR, or conversions? No. LinkedIn does not publish those values in the Ad Library. Impressions are ranges, not exact counts.
Is this affiliated with LinkedIn? No. This is an independent third-party actor that reads LinkedIn's public Ad Library. It is not affiliated with or endorsed by LinkedIn Corporation.
Limitations
- Only public Ad Library ads are available; Campaign Manager data is not accessible.
- EU transparency data (dates, impressions, country shares, targeting) is published only for EU-served ads.
- LinkedIn reports impression ranges rather than exact impressions.
- Each search is capped at 4,800 ads (200 pages × 24).
- Media URLs are signed and expire;
expiresAtis provided for archival planning. - Per-ad delivery country is not published.
countryreflects a single-country search filter;top_countryis the largest DSA share. - Carousel/document slide text and non-EU active status are not published by the source.
- LinkedIn may rate-limit aggressive runs; the actor retries and reports partial results rather than fabricating rows.
Python quickstart
Use a schema-derived input and the Python standard library to start a run. An Apify account and token are required for execution.
Source build wrUve4WlpfpUTcaYq. Documentation is regenerated from the default published build; private drafts are not included.