Search the public LinkedIn Ad Library by keyword, country, and date range. Returns ad rows with their numeric ad IDs so you can request full ad details. One request performs exactly one upstream lookup, so one credit buys one page. When more results exist the response carries pagination_token; send it back as pagination_token on the next request, which is a separate, separately billed lookup. upstream_calls reports the real upstream request count and exceeds 1 only when a request was refused and retried, which is a retry of the same page rather than a fan-out and costs no extra credit. An Ad Library page that returns no ads is never billed. The Errors section lists the common cases rather than every code: any failed request carries an error_code, and none of them is billed.
Run this endpoint
Endpoint
Parameters
Start with the required fields, then add optional filters only when your use case needs them.
Runnable path
1 required parameter needed before sending a request.
6 optional filters available.
string
Required
Search phrase.
analytics platform
string
Optional
Repeatable 2-letter country code (e.g., countries[]=US&countries[]=DE).
example
string
Optional
last-30-days or custom-date-range.
example
string
Optional
Range start as YYYY-MM-DD. Only used with custom-date-range.
example
string
Optional
Range end as YYYY-MM-DD. Only used with custom-date-range.
example
string
Optional
Restrict results to one advertiser.
example
string
Optional
Continuation token from a previous response, for the next page. It is one separately billed lookup.
example
Request Examples
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_API_KEY_HERE"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
<?php
use Illuminate\Support\Facades\Http;
$response = Http::timeout(30)
->withHeaders(['x-api-key' => 'YOUR_API_KEY_HERE'])
->get('https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US');
if ($response->successful()) {
echo $response->body();
} else {
echo "Error: " . $response->status();
}
const options = {
method: 'GET',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE'
}
};
fetch('https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US', options)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.text();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
const axios = require('axios');
const options = {
method: 'GET',
url: 'https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US',
headers: {
x-api-key: 'YOUR_API_KEY_HERE',
}
};
try {
const response = await axios(options);
console.log(response.data);
} catch (error) {
console.error('Error:', error.message);
}
require 'net/http'
require 'uri'
uri = URI.parse("https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = 'YOUR_API_KEY_HERE'
begin
response = http.request(request)
puts response.body
rescue => e
puts "Error: #{e.message}"
end
import http.client
import json
conn = http.client.HTTPSConnection("scrappa.co")
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
conn.request("GET", "/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
except Exception as e:
print(f"Error: {e}")
finally:
conn.close()
import requests
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
response = requests.get('https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US', headers=headers)
response.raise_for_status()
print(response.text)
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class ApiExample {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US")
.addHeader("x-api-key", "YOUR_API_KEY_HERE")
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
System.out.println(response.body().string());
} else {
System.out.println("Error: " + response.code());
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US", nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("x-api-key", "YOUR_API_KEY_HERE")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(string(body))
}
#!/bin/bash
curl -X GET \
-H "x-api-key: YOUR_API_KEY_HERE" \
"https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US"
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY_HERE");
try
{
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US"));
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
import axios from 'axios';
async function run(): Promise<void> {
try {
const response = await axios({
method: 'GET',
url: 'https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE',
},
});
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
}
void run();
use reqwest::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let response = client
.get("https://scrappa.co/api/linkedin/ads/search?keyword=analytics+platform&countries%5B0%5D=US")
.header("x-api-key", "YOUR_API_KEY_HERE")
.send()
.await?;
println!("{}", response.text().await?);
Ok(())
}
Response Schema
Example response fields are illustrative; inspect the JSON before integrating.
Example response fields
Scan these fields before integrating.
ads
ad_count
upstream_calls
is_last_page
pagination_token
Common ads fields
ad_id
url
{
"ads": [
{
"ad_id": "541239876501",
"url": "https://www.linkedin.com/ad-library/detail/541239876501"
}
],
"ad_count": 1,
"upstream_calls": 1,
"is_last_page": false,
"pagination_token": "next-page-token"
}
Errors
Handle these documented responses before retrying or showing customer-facing failures.
Validation Error
The keyword parameter is missing, or a filter value is out of range.
{
"message": "The request validation failed",
"errors": {
"keyword": [
"The keyword field is required."
]
}
}No Ads Found
LinkedIn returned an Ad Library page with no ads, which means this search matched nothing or the pagination token reached the end of the result set. Not billed.
{
"success": false,
"message": "No ads matched this query.",
"status_code": 404,
"error_code": "linkedin_ads_search_no_results"
}Ad Library Refused
LinkedIn answered with a full-size page carrying no ads, which is how it refuses a blocked request. Retrying usually succeeds. Not billed, so this is never mistaken for a search that matched nothing.
{
"success": false,
"message": "LinkedIn Ad Library refused this search. Please try again.",
"status_code": 403,
"error_code": "linkedin_ads_search_wall"
}Upstream Error
LinkedIn answered with a non-success status that is neither a refusal wall nor an empty result. Failed requests are never billed.
{
"success": false,
"message": "LinkedIn Ad Library search is temporarily unavailable.",
"status_code": 503,
"error_code": "linkedin_ad_search_upstream_error"
}Request Not Dispatched
Scrappa could not send this request to LinkedIn at all, so no data was retrieved. Please try again in a moment. Failed requests are never billed.
{
"success": false,
"message": "LinkedIn Ad Library search is temporarily unavailable.",
"status_code": 503,
"error_code": "upstream_unavailable"
}Transport Unavailable
The request never produced a usable answer, so the retrieval path was unavailable. Failed requests are never billed.
{
"success": false,
"message": "LinkedIn Ad Library search is temporarily unavailable.",
"status_code": 503,
"error_code": "linkedin_ad_library_transport_unavailable"
}Generate Code with AI
Copy a ready-made prompt with all the endpoint details, parameters, and example responses. Paste it into ChatGPT, Claude, or any AI assistant to instantly generate working code.
Related LinkedIn API docs
LinkedIn Profile API
Get public profile identity, headline, experience, education, skills, activity, and similar profiles.
LinkedIn Company API
Enrich profile and recruiting workflows with company page details and metadata.
LinkedIn API overview
Browse profile, company, search, jobs, job details, and post endpoints from one hub.
Try It Live
Test this endpoint in our interactive playground with real data.