Skip to content
Scrappa Get API key
LinkedIn API 1 credit/request

LinkedIn Ad Detail

GET https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501

Get one public LinkedIn Ad Library ad by its numeric ID: ad copy, advertiser, payer, run dates, and the targeting panel. The targeting keys are the panel headings as LinkedIn publishes them, lower-cased and underscored, so the set differs per ad and per region — the sample below is illustrative, not a fixed schema. The impression breakdown depends on where the ad actually ran and is returned as null when LinkedIn does not publish one. upstream_calls reports the number of real upstream requests made; it exceeds 1 only when a request was refused and retried, which is not a fan-out and not an extra charge. The Errors section lists the common cases rather than every code: any failed request carries an error_code, and none of them is billed.

LinkedIn Ad Detail 1 credit/request

Endpoint

Request preview
GET
https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501
Auth header
x-api-key
Cost
1 credit/request
ad_id = 541239876501
Response preview
200 OK
{
    "ad_id": "541239876501",
    "copy": "See the full platform in action.",
    "advertiser": "Acme Analytics",
    "payer": "Acme Analytics GmbH",
    "run_dates": "1 Mar 2026 - 30 Apr 2026",
    "targeting": {
        "language": "English",
        "location": "United States"
    },
    "impression_breakdown": null,
    "upstream_calls": 1
}

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.

ad_id string Required

Numeric LinkedIn Ad Library ad ID, as returned by the Ads Search endpoint.

Example value 541239876501

Request Examples

PHP
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501",
    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
<?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/detail?ad_id=541239876501');

if ($response->successful()) {
    echo $response->body();
} else {
    echo "Error: " . $response->status();
}
JavaScript
const options = {
    method: 'GET',
    headers: {
        'x-api-key': 'YOUR_API_KEY_HERE'
    }
};

fetch('https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501', 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));
JavaScript
const axios = require('axios');

const options = {
    method: 'GET',
    url: 'https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501',
    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);
}
Ruby
require 'net/http'
require 'uri'

uri = URI.parse("https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501")
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
Python
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/detail?ad_id=541239876501", headers=headers)
    res = conn.getresponse()
    data = res.read()
    print(data.decode("utf-8"))
except Exception as e:
    print(f"Error: {e}")
finally:
    conn.close()
Python
import requests

headers = {
    'x-api-key': 'YOUR_API_KEY_HERE',
}

try:
    response = requests.get('https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501', headers=headers)
    response.raise_for_status()
    print(response.text)
except requests.exceptions.RequestException as e:
    print(f"Error: {e}")
Java
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/detail?ad_id=541239876501")
        .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());
        }
    }
}
Go
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501", 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))
}
Terminal
#!/bin/bash

curl -X GET \
    -H "x-api-key: YOUR_API_KEY_HERE" \
    "https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501"
C#
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/detail?ad_id=541239876501"));
            var content = await response.Content.ReadAsStringAsync();
            Console.WriteLine(content);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
TypeScript
import axios from 'axios';

async function run(): Promise<void> {
    try {
        const response = await axios({
            method: 'GET',
            url: 'https://scrappa.co/api/linkedin/ads/detail?ad_id=541239876501',
            headers: {
        'x-api-key': 'YOUR_API_KEY_HERE',
            },
        });

        console.log(response.data);
    } catch (error) {
        console.error('Error:', error);
    }
}

void run();
RUST
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/detail?ad_id=541239876501")
        .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.

ad_id copy advertiser payer run_dates targeting impression_breakdown upstream_calls
JSON Response
200 OK
{
    "ad_id": "541239876501",
    "copy": "See the full platform in action.",
    "advertiser": "Acme Analytics",
    "payer": "Acme Analytics GmbH",
    "run_dates": "1 Mar 2026 - 30 Apr 2026",
    "targeting": {
        "language": "English",
        "location": "United States"
    },
    "impression_breakdown": null,
    "upstream_calls": 1
}

Errors

Handle these documented responses before retrying or showing customer-facing failures.

422

Validation Error

The ad_id parameter is missing or is not numeric.

{
    "message": "The request validation failed",
    "errors": {
        "ad_id": [
            "The ad_id field is required."
        ]
    }
}
404

Ad Not Found

No ad with this ID, or LinkedIn answered with a different ad than the one requested (a redirect, an expired ad, or a slug that moved). A bad or expired ad_id is served by LinkedIn as a 200 with no ad on it rather than a 404, so the id is checked before the page is read. Size discriminates only on a true 404: a 404 document far larger than a real absent ad means LinkedIn has dropped the route entirely and is answered with 503 below instead. A real answer rather than an outage, so do not retry. Not billed.

{
    "success": false,
    "message": "Ad not found",
    "status_code": 404,
    "error_code": "linkedin_ad_not_found"
}
503

Upstream Route Changed

LinkedIn answered with a full-size page instead of an ad, which is what a dropped route looks like. The ad may well still exist; our upstream route has moved. Retrying may succeed. Not billed, and not reported as "ad not found" because that would be untrue about your data.

{
    "success": false,
    "message": "LinkedIn Ad Library is temporarily unavailable. Please try again.",
    "status_code": 503,
    "error_code": "linkedin_ad_detail_upstream_drift"
}
403

Ad Library Refused

LinkedIn answered with a full-size page carrying no ad, which is how it refuses a blocked request. Retrying usually succeeds. Not billed.

{
    "success": false,
    "message": "LinkedIn Ad Library refused this request. Please try again.",
    "status_code": 403,
    "error_code": "linkedin_ad_detail_wall"
}
503

No Ad Details

LinkedIn returned the requested ad but none of its fields could be read, which is parser drift on a real ad page rather than a missing ad. Terminal rather than transient, so it is not retried. Not billed.

{
    "success": false,
    "message": "LinkedIn Ad Library returned no ad details.",
    "status_code": 503,
    "error_code": "linkedin_ad_detail_empty"
}
503

Upstream Error

LinkedIn answered with a non-success status that is neither a refusal wall nor a missing ad. Failed requests are never billed.

{
    "success": false,
    "message": "LinkedIn Ad Library detail is temporarily unavailable.",
    "status_code": 503,
    "error_code": "linkedin_ad_detail_upstream_error"
}
503

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 detail is temporarily unavailable.",
    "status_code": 503,
    "error_code": "upstream_unavailable"
}
503

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 detail 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

Try It Live

Test this endpoint in our interactive playground with real data.