
Instagram Reel Scraper
scrape.ly/store/echofield/instagram-reel-scraperSocial mediaVideos
1 monthly user

Scrape the public LinkedIn Ad Library by company, keyword, payer or URL. Get ad copy, creatives, CTA, payer, run dates, impressions, country split and targeting. No login.
Turn the public LinkedIn Ad Library into clean, structured rows. Search by company, keyword or payer (or paste Ad Library URLs) and get the full ad copy, headline, call to action, destination URL, creatives, run dates, impression ranges, country split and targeting for every ad. No LinkedIn account, no cookies, pay only for the ads you save.
| Field | What it does |
|---|---|
companies | Advertiser names, one search each (e.g. HubSpot). |
keywords | Words or phrases in ad copy, one search each. |
payers | Paying entities, one search each. |
startUrls | Ad Library search URLs or single ad URLs (/ad-library/detail/<id>). |
maxItems | Total ads to save across all searches (default 20). |
countries | 2-letter country codes; empty means worldwide. |
dateOption / startDate / endDate | Preset range or custom dates (the Ad Library covers the last 12 months). |
impressionsMinValue / impressionsMaxValue (+ units) | Impression range filter. |
includedTargetingFacetCategories / excludedTargetingFacetCategories | Targeting categories the ad must include or exclude. |
adTypes | Formats to keep (skipped ads are never charged). |
scrapeAdDetails | Read each ad's detail page (default on). Off gives faster preview-only rows. |
maxItemsPerSearch | Cap per search or URL. |
searches | Independent searches, each with its own filters. |
{
"companies": ["HubSpot"],
"keywords": ["cybersecurity"],
"countries": ["US", "GB"],
"dateOption": "last-30-days",
"maxItems": 50,
"maxItemsPerSearch": 25
}
| Field | Description |
|---|---|
adId, adLibraryUrl | Ad id and its public Ad Library page |
format, formatLabel | Normalized format (VIDEO, CAROUSEL, ...) and LinkedIn's label |
advertiserName, advertiserUrl, advertiserLogo | Who ran the ad |
paidBy | Entity that paid for the ad |
headline, body, ctas, clickUrl | Ad copy, call to action and destination |
imageUrl, imageUrls, videoUrl, carouselCards, document, event | Creative media and format details |
firstShownAt, lastShownAt, daysRunning, adStatus | Run dates, when LinkedIn shows them |
totalImpressionsRaw, totalImpressionsMin, totalImpressionsMax | Impression range |
impressionsByCountry | Share of impressions per country |
targeting, targetingParameters | Targeted segments and which parameters were used or excluded |
b2bIntentScore, b2bIntentSignals | A simple 0–100 score of how B2B-oriented the ad looks, with reasons |
startUrl, scrapedAt | Where the row came from and when |
Example (fictional advertiser, real shape):
{
"adId": "1600000001",
"adLibraryUrl": "https://www.linkedin.com/ad-library/detail/1600000001",
"type": "AD",
"format": "VIDEO",
"formatLabel": "Video Ad",
"creativeType": "SPONSORED_VIDEO",
"advertiserName": "Northwind Analytics",
"advertiserUrl": "https://www.linkedin.com/company/00000001",
"advertiserLogo": "https://media.licdn.com/dms/image/v2/.../company-logo_100_100/...",
"advertiserBio": null,
"isPromoted": true,
"paidBy": "Northwind Analytics GmbH",
"headline": "Your CRM data, finally clean.",
"body": "Most pipeline reports are built on stale data. See how teams keep their CRM up to date automatically.",
"ctas": ["Learn more"],
"clickUrl": "https://www.example.com/crm-cleanup?utm_source=linkedin",
"externalLinksInText": [],
"imageUrl": "https://media.licdn.com/dms/image/v2/.../videocover-high/...",
"videoUrl": "https://dms.licdn.com/playlist/vid/v2/.../mp4-720p-30fp-crf28/...",
"carouselCards": [],
"document": null,
"event": null,
"availabilityRaw": "Ran from Oct 9, 2026 to Oct 14, 2026",
"firstShownAt": "2026-10-09",
"lastShownAt": "2026-10-14",
"daysRunning": 6,
"adStatus": "ACTIVE",
"totalImpressionsRaw": "200k-300k",
"totalImpressionsMin": 200000,
"totalImpressionsMax": 300000,
"impressionsByCountry": [
{"country": "Germany", "percentage": 92, "raw": "92%", "lessThan": false},
{"country": "Austria", "percentage": 1, "raw": "< 1%", "lessThan": true}
],
"targeting": [
{"category": "Language", "included": ["German"], "excluded": [], "raw": "Targeting includes German"},
{"category": "Location", "included": ["Germany"], "excluded": [], "raw": "Targeting includes Germany"}
],
"targetingParameters": [
{"parameter": "Company", "targeted": true, "excluded": true},
{"parameter": "Job", "targeted": true, "excluded": false}
],
"b2bIntentScore": 35,
"b2bIntentSignals": ["Professional targeting: company, job", "B2B copy terms: crm, pipeline"],
"detailsScraped": true,
"startUrl": "https://www.linkedin.com/ad-library/search?accountOwner=Northwind+Analytics",
"scrapedAt": "2026-10-14T18:00:00Z"
}
You pay $1.00 per 1,000 ads saved ($0.001 per ad), the same with or without detail pages. 1,000 ads ≈ $1.00 in ad fees. Platform usage (compute and residential proxy traffic) is billed separately at the normal rates and is small for this actor: it reads plain HTML pages with 256 MB of memory.
Is it legal? The actor reads only the public LinkedIn Ad Library, which LinkedIn publishes for ad transparency. You are responsible for how you use the data, including any personal data in ads run by individuals.
Do I need a LinkedIn account or proxy? No account and no cookies. Residential exits are selected by default because LinkedIn refuses most datacenter IPs; the traffic is small (pages are compressed, well under 50 KB per ad).
How many ads can I get? As many as the Ad Library lists for your searches, within the last 12 months. Each search pages through LinkedIn's results until it runs out or reaches your limits.
Why are run dates, impressions or targeting empty for some ads? LinkedIn shows those details only for some ads (mainly ads shown in the EU). When the Ad Library does not display a value, the field is null or an empty list.
Can I schedule it or use the API? Yes. Save your input as a task, schedule it, and read the dataset through the API or integrations.
Every field below can be set in the run form, passed through the API, or saved as a task. Unset fields fall back to the defaults shown.
companiesarrayOptionalCompanies / advertisers
Company or advertiser names to search for, e.g. HubSpot or Microsoft. Each name runs as its own search.
keywordsarrayOptionalKeywords
Words or phrases to find in ad copy. Each keyword runs as its own search.
payersarrayOptionalPayers
Entities that paid for the ads (can differ from the advertiser). Each payer runs as its own search.
startUrlsarrayOptionalAd Library URLs
LinkedIn Ad Library search URLs (https://www.linkedin.com/ad-library/search?...) or single ad URLs (https://www.linkedin.com/ad-library/detail/). Search URLs keep their own filters.
maxItemsintegerOptionaldefault 20Maximum ads
Total number of ads to save across all searches. Duplicates across searches are saved once.
Narrow the searches the same way the Ad Library filters do.
countriesarrayOptionalCountries
Only ads shown in these countries. 2-letter ISO codes such as US, GB or DE. Empty means worldwide.
dateOptionenumOptionaldefault "all-time"Date range
When the ads ran. Custom start or end dates below override this.
startDatestringOptionalCustom start date
Only ads that ran on or after this date (YYYY-MM-DD). The Ad Library covers the last 12 months.
endDatestringOptionalCustom end date
Only ads that ran on or before this date (YYYY-MM-DD).
impressionsMinValueintegerOptionalMin impressions
Only ads with at least this many impressions, combined with the unit (100 + Thousand = 100,000). Set one side only and the other is left open.
impressionsMinUnitenumOptionaldefault "thousand"Min impressions unit
Multiplier for the minimum.
impressionsMaxValueintegerOptionalMax impressions
Only ads with at most this many impressions, combined with the unit.
impressionsMaxUnitenumOptionaldefault "thousand"Max impressions unit
Multiplier for the maximum.
includedTargetingFacetCategoriesarrayOptionalTargeting includes
Only ads whose targeting includes these categories.
excludedTargetingFacetCategoriesarrayOptionalTargeting excludes
Only ads whose targeting excludes these categories. A category in both lists matches LinkedIn's 'Both' option.
adTypesarrayOptionalAd formats to keep
Keep only these formats. Filtered before detail pages load, so skipped ads cost nothing. Empty keeps all formats.
scrapeAdDetailsbooleanOptionaldefault trueScrape full ad details
Open each ad's detail page for the full copy, headline, CTA, destination URL, payer, run dates, impressions, country split, targeting and media links. Turn off for faster preview-only rows. Same price either way.
maxItemsPerSearchintegerOptionalMax ads per search
Cap for each single search or URL, so one big advertiser does not use the whole budget when you batch many searches.
searchesarrayOptionalIndependent searches
Several unrelated searches in one run, each with its own filters. Keys: company, keyword, payer, countries, dateOption, startDate, endDate, impressions fields, targeting fields, maxItems. Missing keys fall back to the settings above. Example: [{"company":"Nike","countries":["DE"],"dateOption":"last-30-days"}]
maxConcurrencyintegerOptionaldefault 16Concurrency
How many pages load in parallel (each on its own exit). The default suits most runs.
proxyConfigurationobjectOptionaldefault {"useScrapelyProxy":true,"scrapelyProxyGroups":["RESIDENTIA…Proxy
Residential exits are used by default because LinkedIn refuses most datacenter exits. If you pick datacenter, the actor switches to residential by itself when it is refused.
Every run writes its results to a dataset. Preview it in the dashboard, then export it or read it through the API.
| Field | Type | Description |
|---|---|---|
| adId | string | null | LinkedIn ad id |
| adLibraryUrl | string | null | Public Ad Library page of the ad |
| type | string | null | Row type, always AD |
| format | string | null | Normalized format: SINGLE_IMAGE, VIDEO, CAROUSEL, DOCUMENT, TEXT, EVENT, MESSAGE, FOLLOW_COMPANY, SPOTLIGHT, ARTICLE, JOBS or OTHER |
| formatLabel | string | null | Format as LinkedIn labels it, e.g. Video Ad |
| creativeType | string | null | LinkedIn's internal creative type |
| advertiserName | string | null | Advertiser shown on the ad |
| advertiserUrl | string | null | Advertiser's LinkedIn page |
| advertiserLogo | string | null | Advertiser logo URL |
| advertiserBio | string | null | Headline under the advertiser name, when shown |
| isPromoted | boolean | null | Shown as Promoted |
| paidBy | string | null | Entity that paid for the ad |
| headline | string | null | Ad headline |
| body | string | null | Full ad copy |
| ctas | array | null | Call-to-action button labels |
| clickUrl | string | null | Destination URL |
| externalLinksInText | array | null | Links found in the ad copy |
| imageUrl | string | null | Main creative image or video poster |
| imageUrls | array | null | All creative image URLs |
| videoUrl | string | null | Playable MP4 URL |
| videoUrls | array | null | All MP4 renditions, best first |
| carouselCards | array | null | Carousel or multi-image cards |
| document | object | null | Document ad title, preview pages and manifest |
| event | object | null | Event ad name, time, organizer and location |
| availabilityRaw | string | null | Run dates as shown |
| firstShownAt | string | null | First day the ad ran (YYYY-MM-DD) |
| lastShownAt | string | null | Last day the ad ran (YYYY-MM-DD) |
| daysRunning | integer | null | Days between first and last run date, inclusive |
| adStatus | string | null | ACTIVE when the ad ran within the last day, else INACTIVE |
| totalImpressionsRaw | string | null | Total impressions range as shown |
| totalImpressionsMin | integer | null | Lower bound of the impressions range |
| totalImpressionsMax | integer | null | Upper bound of the impressions range |
| impressionsByCountry | array | null | Share of impressions per country |
| targeting | array | null | Targeting segments per category |
| targetingParameters | array | null | Which targeting parameters were used or excluded |
| b2bIntentScore | integer | null | 0-100 score of how B2B-oriented the ad looks |
| b2bIntentSignals | array | null | Reasons behind the score |
| detailsScraped | boolean | null | True when the detail page was read |
| startUrl | string | null | Search or URL this ad came from |
| scrapedAt | string | null | Scrape time (UTC) |
You pay for the events the actor reports, such as each result or page it produces. Platform usage is included in the event prices.
| Event | Charged when | Price |
|---|---|---|
| Ad | One ad saved to the dataset, with full details when available | $0.001 |
Run this actor from your own code. Swap in your API token and the examples work as-is.
import { ScrapelyClient } from 'scrapely-client'
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN })
// Start the actor and wait for the run to finish.
const run = await client.actor('echofield/linkedin-ads-scraper').call({
"companies": [
"HubSpot"
],
"maxItems": 20,
"proxyConfiguration": {
"useScrapelyProxy": true,
"scrapelyProxyGroups": [
"RESIDENTIAL"
]
}
})
// Read the dataset the run produced.
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)Tokens live in your account settings. Keep them server-side: a token carries the full permissions of your account.
Connect the Scrape.ly MCP server once and your agent can run this actor as a tool. Pick your tool:
Fetch scrape.ly/agents.md and run echofield/linkedin-ads-scraperPaste into Claude Code, Codex, Cursor or any AI agent. It signs you in once in the browser.
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp?tools=actors,runs,storage,docs&actors=echofield/linkedin-ads-scraper"
}
}
}No key in the file: your client opens the browser to sign you in the first time it connects.
Inputs the developer prepared for common jobs. Open one to see its input, then copy it to your account to run it as-is or adjust it.
Ads from one advertiser with full ad details.
Ad library keyword search filtered by country.
Recent ads from one advertiser with impression ranges.
Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.