# Ad Library ad details

> Full detail for one ad from Meta's Ad Library, by its id or URL.

- **Request:** `GET https://api.lurkapi.com/v1/facebook/adLibrary/ad`
- **Auth:** `x-api-key` header ([get a free key](https://lurkapi.com/login?next=/dashboard))
- **Cost:** 1 credit per call. Validation errors, `401`/`402`/`429` rejections and `5xx` failures are free; `not_found` is charged ([how charging works](https://lurkapi.com/docs.md#credits)).
- **MCP tool:** `facebook_ad` on `https://api.lurkapi.com/mcp`
- **Freshness:** responses are cached for up to 6 hours
- **Try it live:** https://lurkapi.com/docs/facebook/ad#try (no signup)
- **Platform:** [Facebook](https://lurkapi.com/docs/facebook.md) (facebook.com/ads/library)
- **Web page:** https://lurkapi.com/docs/facebook/ad

## When to use this

Use it for one ad's full creative after a search: pass its `ad_archive_id` as `id`, or an Ad Library link as `url`. Top-level keys here are camelCase (`adArchiveID`, `isActive`).

Everything about a single ad: copy, every image and video, landing page, platforms and run dates. Unlike the list endpoints, top-level keys are camelCase (`adArchiveID`, `pageName`, `isActive`), `publisherPlatform` values are lowercase and `snapshot.body` is a plain string. Ads with several versions keep their creative in `snapshot.cards`.

Returns 404 `not_found` if the ad doesn't exist.

## Parameters

All parameters go in the query string.

| Name | Type | Required | Default | Allowed values | Description | Example |
| --- | --- | --- | --- | --- | --- | --- |
| `id` | string | no |  |  | The ad's Ad Library id (`ad_archive_id`), e.g. `1016451784037642`. Required unless you pass `url`. | `1016451784037642` |
| `url` | string | no |  |  | An Ad Library link containing `?id=…`, e.g. `https://www.facebook.com/ads/library/?id=1016451784037642`. |  |
| `trim` | boolean | no | `false` | `true`, `false` | `true` drops image and video URLs (inside `snapshot.cards` too). All text is kept. |  |

## Example request

Replace `YOUR_API_KEY` with your key, or set `LURKAPI_KEY` for the code. [Get a free key](https://lurkapi.com/login?next=/dashboard).

curl:

```bash
curl "https://api.lurkapi.com/v1/facebook/adLibrary/ad?id=1016451784037642" \
  -H "x-api-key: YOUR_API_KEY"
```

JavaScript:

```js
const params = new URLSearchParams({
  id: "1016451784037642",
});
const res = await fetch(`https://api.lurkapi.com/v1/facebook/adLibrary/ad?${params}`, {
  headers: { "x-api-key": process.env.LURKAPI_KEY },
});
const data = await res.json();
if (!data.success) throw new Error(`${data.code}: ${data.error}`);
console.log(data.publisherPlatform);
```

Python:

```python
import os
import requests

res = requests.get(
    "https://api.lurkapi.com/v1/facebook/adLibrary/ad",
    params={
        "id": "1016451784037642",
    },
    headers={"x-api-key": os.environ["LURKAPI_KEY"]},
    timeout=60,
)
data = res.json()
if not data["success"]:
    raise RuntimeError(f"{data['code']}: {data['error']}")
print(data["publisherPlatform"])
```

## Example response

A real response from this endpoint, captured from the live API and trimmed to a couple of items. Strings over 96 characters (mostly signed media URLs) are cut short and end in `…`.

200 OK (application/json):

```json
{
  "success": true,
  "credits_remaining": 997,
  "credits_charged": 1,
  "adArchiveID": "1016451784037642",
  "adid": null,
  "categories": [
    "UNKNOWN"
  ],
  "collationCount": null,
  "collationID": null,
  "containsDigitallyCreatedMedia": false,
  "containsSensitiveContent": false,
  "currency": "",
  "endDate": 1756364400,
  "endDateString": null,
  "fevInfo": null,
  "gatedType": "eligible",
  "hasUserReported": false,
  "hideDataStatus": "NONE",
  "impressionsWithIndex": {
    "impressionsText": null,
    "impressionsIndex": -1
  },
  "isAAAEligible": false,
  "isActive": true,
  "menuItems": [],
  "pageID": "15087023444",
  "pageIsDeleted": false,
  "pageName": "Nike",
  "publisherPlatform": [
    "facebook",
    "instagram"
  ],
  "reachEstimate": null,
  "regionalRegulationData": {
    "finserv": {
      "is_deemed_finserv": false,
      "is_limited_delivery": false
    },
    "tw_anti_scam": {
      "is_limited_delivery": false
    }
  },
  "reportCount": null,
  "snapshot": {
    "additional_info": null,
    "branded_content": null,
    "brazil_tax_id": null,
    "byline": null,
    "caption": "NIKE.COM",
    "cards": [
      {
        "body": "Get the gear that goes hard on and off the field.",
        "caption": "nike.com",
        "cta_text": "Shop Now",
        "cta_type": "SHOP_NOW",
        "image_crops": [],
        "link_description": "",
        "link_url": "https://www.nike.com/t/air-monarch-iv-mens-workout-shoes-extra-wide-p8qN…",
        "original_image_url": "https://scontent-sjc3-1.xx.fbcdn.net/v/t39.35426-6/509269099_74052692168…",
        "resized_image_url": "https://scontent-sjc3-1.xx.fbcdn.net/v/t39.35426-6/509269099_74052692168…",
        "title": "Nike Air Monarch IV ",
        "video_hd_url": null,
        "video_preview_image_url": null,
        "video_sd_url": null,
        "watermarked_resized_image_url": "",
        "watermarked_video_hd_url": null,
        "watermarked_video_sd_url": null
      },
      {
        "body": "Get the gear that goes hard on and off the field.",
        "caption": "nike.com",
        "cta_text": "Shop Now",
        "cta_type": "SHOP_NOW",
        "image_crops": [],
        "link_description": "",
        "link_url": "https://www.nike.com/t/tempo-shorts-toddler-shorts-Gx0CH3/267358-019?dplnk=member",
        "original_image_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/508839160_17958205780…",
        "resized_image_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/508839160_17958205780…",
        "title": "Nike Tempo Shorts ",
        "video_hd_url": null,
        "video_preview_image_url": null,
        "video_sd_url": null,
        "watermarked_resized_image_url": "",
        "watermarked_video_hd_url": null,
        "watermarked_video_sd_url": null
      },
      {
        "body": "Get the gear that goes hard on and off the field.",
        "caption": "nike.com",
        "cta_text": "Shop Now",
        "cta_type": "SHOP_NOW",
        "image_crops": [],
        "link_description": "",
        "link_url": "https://www.nike.com/t/air-monarch-iv-mens-workout-shoes-p8qNlT/415445-001?dplnk=member",
        "original_image_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/509290535_73016820272…",
        "resized_image_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/509290535_73016820272…",
        "title": "Nike Air Monarch IV ",
        "video_hd_url": null,
        "video_preview_image_url": null,
        "video_sd_url": null,
        "watermarked_resized_image_url": "",
        "watermarked_video_hd_url": null,
        "watermarked_video_sd_url": null
      },
      {
        "body": "Get the gear that goes hard on and off the field.",
        "caption": "nike.com",
        "cta_text": "Shop Now",
        "cta_type": "SHOP_NOW",
        "image_crops": [],
        "link_description": "",
        "link_url": "https://www.nike.com/t/air-monarch-iv-mens-workout-shoes-extra-wide-p8qN…",
        "original_image_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/509359383_12428901607…",
        "resized_image_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/509359383_12428901607…",
        "title": "Nike Air Monarch IV ",
        "video_hd_url": null,
        "video_preview_image_url": null,
        "video_sd_url": null,
        "watermarked_resized_image_url": "",
        "watermarked_video_hd_url": null,
        "watermarked_video_sd_url": null
      },
      {
        "body": "Get the gear that goes hard on and off the field.",
        "caption": "nike.com",
        "cta_text": "Shop Now",
        "cta_type": "SHOP_NOW",
        "image_crops": [],
        "link_description": "",
        "link_url": "https://www.nike.com/t/air-monarch-iv-mens-workout-shoes-p8qNlT/415445-102?dplnk=member",
        "original_image_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/508595289_38944231908…",
        "resized_image_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/508595289_38944231908…",
        "title": "Nike Air Monarch IV ",
        "video_hd_url": null,
        "video_preview_image_url": null,
        "video_sd_url": null,
        "watermarked_resized_image_url": "",
        "watermarked_video_hd_url": null,
        "watermarked_video_sd_url": null
      },
      {
        "body": "Get the gear that goes hard on and off the field.",
        "caption": "nike.com",
        "cta_text": "Shop Now",
        "cta_type": "SHOP_NOW",
        "image_crops": [],
        "link_description": "",
        "link_url": "https://www.nike.com/t/air-monarch-iv-mens-workout-shoes-extra-wide-p8qN…",
        "original_image_url": "https://scontent-sjc3-1.xx.fbcdn.net/v/t39.35426-6/509094198_14858974427…",
        "resized_image_url": "https://scontent-sjc3-1.xx.fbcdn.net/v/t39.35426-6/509094198_14858974427…",
        "title": "Nike Air Monarch IV ",
        "video_hd_url": null,
        "video_preview_image_url": null,
        "video_sd_url": null,
        "watermarked_resized_image_url": "",
        "watermarked_video_hd_url": null,
        "watermarked_video_sd_url": null
      }
    ],
    "country_iso_code": null,
    "cta_text": "Shop now",
    "cta_type": "SHOP_NOW",
    "disclaimer_label": null,
    "display_format": "DPA",
    "ec_certificates": [],
    "event": null,
    "extra_images": [],
    "extra_links": [],
    "extra_texts": [],
    "extra_videos": [],
    "images": [],
    "is_reshared": false,
    "link_description": null,
    "link_url": "https://www.nike.com/us/en_us",
    "page_categories": [
      "Sportswear"
    ],
    "page_id": "15087023444",
    "page_is_deleted": false,
    "page_like_count": 39514042,
    "page_name": "Nike",
    "page_profile_picture_url": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.35426-6/509357337_40881708814…",
    "page_profile_uri": "https://facebook.com/nike",
    "root_reshared_post": null,
    "title": "{{product.name}}",
    "videos": [],
    "body": "Get the gear that goes hard on and off the field.",
    "final_url": null
  },
  "spend": null,
  "startDate": 1750402800,
  "startDateString": null,
  "stateMediaRunLabel": null,
  "totalActiveTime": null,
  "url": null,
  "aaa_info": null
}
```

## Response fields

Every field of a successful response. `[]` marks a list: `a[].b` is the `b` of each item in `a`. **nullable** fields can be `null`; **optional** fields can be missing.

| Field | Type | Description |
| --- | --- | --- |
| `success` | `true` | Always true here; errors have `success: false`. |
| `credits_remaining` | `number` | Your balance after this call. On anonymous playground calls: free tries left today. |
| `credits_charged` | `number` | Credits this call cost; 0 on free endpoints. On anonymous playground calls: tries used (1). |
| `adArchiveID` | `string`, nullable | The Ad Library id. Pass it as `id` to the ad details endpoint. |
| `adid` | `string`, nullable | Meta's internal ad id. null in every response we've seen; use the Ad Library id. |
| `pageID` | `string`, nullable | The advertiser's Facebook page id. Pass it as `pageId` to the company ads endpoint. |
| `pageName` | `string`, nullable | The advertiser's page name. |
| `isActive` | `boolean` | Whether the ad is running now. |
| `startDate` | `number`, nullable | When the ad started running, Unix seconds (UTC). |
| `endDate` | `number`, nullable | When the ad stopped, or its latest delivery date if still running, Unix seconds (UTC). |
| `startDateString` | `string`, nullable | The same date as ISO 8601 text when Facebook includes it; often null, so prefer the Unix seconds field. |
| `endDateString` | `string`, nullable | The same date as ISO 8601 text when Facebook includes it; often null, so prefer the Unix seconds field. |
| `totalActiveTime` | `number`, nullable | Seconds the ad has run, when Facebook reports it; usually null. |
| `publisherPlatform` | `string[]` | Where it ran, lowercase: facebook, instagram, audience_network, messenger, threads. |
| `collationCount` | `number`, nullable | How many near-identical versions are grouped under this ad. A high count means the advertiser is scaling it; null for a single version. |
| `collationID` | `string`, nullable | Id shared by the grouped versions of this ad; null for a single version. |
| `snapshot` | `object` | The creative: copy, media, landing page and advertiser details (snake_case inside). |
| `snapshot.page_id` | `string`, nullable | The advertiser's page id (same as the ad's). |
| `snapshot.page_name` | `string`, nullable | The advertiser's page name as shown on the ad. |
| `snapshot.page_profile_uri` | `string`, nullable | The advertiser's Facebook page URL. |
| `snapshot.page_profile_picture_url` | `string`, nullable | The advertiser's profile picture, 60×60 px. |
| `snapshot.page_like_count` | `number`, nullable | Followers of the advertiser's page. |
| `snapshot.page_categories` | `string[]` | Page categories, e.g. ["Outdoor & Sporting Goods Company"]. |
| `snapshot.page_is_deleted` | `boolean` | Whether the advertiser's page has been deleted. |
| `snapshot.title` | `string`, nullable | Headline under the creative; null when there is none. |
| `snapshot.caption` | `string`, nullable | Display link under the creative, usually the domain (e.g. HOKA.com). |
| `snapshot.link_url` | `string`, nullable | Landing page the ad sends people to, UTM tags included. |
| `snapshot.link_description` | `string`, nullable | Text under the headline; null when there is none. |
| `snapshot.cta_text` | `string`, nullable | Button label, e.g. "Shop now". |
| `snapshot.cta_type` | `string`, nullable | Button type, e.g. SHOP_NOW, LEARN_MORE, NO_BUTTON. |
| `snapshot.display_format` | `string`, nullable | Creative format, e.g. IMAGE, VIDEO, DCO (dynamic creative), DPA (dynamic product ad) or MULTI_IMAGES. For DCO and DPA ads the creative is in `cards`. |
| `snapshot.images` | `object[]` | Image creatives. Empty for video and card-based ads, and with trim=true. |
| `snapshot.images[].original_image_url` | `string`, nullable | Full-size image URL. Facebook CDN links expire after a few days; download what you need. |
| `snapshot.images[].resized_image_url` | `string`, nullable | 600 px image URL, good for thumbnails. |
| `snapshot.images[].watermarked_resized_image_url` | `string` | Watermarked copy; empty or null in every response we've seen. |
| `snapshot.images[].image_crops` | `any[]` | Facebook internal field; an empty array in every response we've seen. Crop hints for the image. |
| `snapshot.videos` | `object[]` | Video creatives. Empty for image and card-based ads, and with trim=true. |
| `snapshot.videos[].video_hd_url` | `string`, nullable | HD video file URL; null if Facebook has no HD version. |
| `snapshot.videos[].video_sd_url` | `string`, nullable | SD video file URL. |
| `snapshot.videos[].video_preview_image_url` | `string`, nullable | Poster frame (still image) URL. |
| `snapshot.videos[].watermarked_video_hd_url` | `string`, nullable | Watermarked copy; empty or null in every response we've seen. |
| `snapshot.videos[].watermarked_video_sd_url` | `string`, nullable | Watermarked copy; empty or null in every response we've seen. |
| `snapshot.cards` | `object[]` | Carousel, dynamic-creative and product versions, each with its own copy and media. With trim=true the text stays and media URLs are null. |
| `snapshot.cards[].title` | `string`, nullable | This version's headline. |
| `snapshot.cards[].body` | `string`, nullable | This version's primary text. |
| `snapshot.cards[].caption` | `string`, nullable | This version's display link, usually the domain. |
| `snapshot.cards[].cta_text` | `string`, nullable | Button label, e.g. "Shop now". |
| `snapshot.cards[].cta_type` | `string`, nullable | Button type, e.g. SHOP_NOW, LEARN_MORE. |
| `snapshot.cards[].link_url` | `string`, nullable | This version's landing page URL. |
| `snapshot.cards[].link_description` | `string`, nullable | Text under the headline; null when there is none. |
| `snapshot.cards[].original_image_url` | `string`, nullable | Full-size image URL; null for video versions. |
| `snapshot.cards[].resized_image_url` | `string`, nullable | 600 px image URL; null for video versions. |
| `snapshot.cards[].watermarked_resized_image_url` | `string` | Watermarked copy; empty or null in every response we've seen. |
| `snapshot.cards[].image_crops` | `any[]` | Facebook internal field; an empty array in every response we've seen. Crop hints for the image. |
| `snapshot.cards[].video_hd_url` | `string`, nullable | HD video file URL; null for image versions. |
| `snapshot.cards[].video_sd_url` | `string`, nullable | SD video file URL; null for image versions. |
| `snapshot.cards[].video_preview_image_url` | `string`, nullable | Poster frame URL; null for image versions. |
| `snapshot.cards[].watermarked_video_hd_url` | `string`, nullable | Watermarked copy; empty or null in every response we've seen. |
| `snapshot.cards[].watermarked_video_sd_url` | `string`, nullable | Watermarked copy; empty or null in every response we've seen. |
| `snapshot.byline` | `string`, nullable | Line under the page name, when shown; null or empty in most ads. |
| `snapshot.disclaimer_label` | `string`, nullable | "Paid for by" line on political and issue ads; null otherwise. |
| `snapshot.country_iso_code` | `string`, nullable | Facebook internal field; null in every response we've seen. A country code on some ads. |
| `snapshot.is_reshared` | `boolean` | Whether the ad reshares an existing post (see `root_reshared_post`). |
| `snapshot.root_reshared_post` | `any` | The original post when `is_reshared` is true; null otherwise. |
| `snapshot.branded_content` | `any` | Paid partnership details when the ad is branded content; null otherwise. |
| `snapshot.additional_info` | `any` | Facebook internal field; null in every response we've seen. |
| `snapshot.brazil_tax_id` | `any` | Advertiser tax id shown on ads under Brazil's rules; null otherwise. |
| `snapshot.ec_certificates` | `any[]` | Facebook internal field; an empty array in every response we've seen. |
| `snapshot.event` | `any` | Event details on event ads; null otherwise. |
| `snapshot.extra_images` | `any[]` | More images from dynamic creative; usually empty. |
| `snapshot.extra_links` | `any[]` | More landing page URLs from dynamic creative; usually empty. |
| `snapshot.extra_texts` | `any[]` | More text variations from dynamic creative; usually empty. |
| `snapshot.extra_videos` | `any[]` | More videos from dynamic creative; usually empty. |
| `snapshot.body` | `string`, nullable | The ad's primary text as a plain string; null when the copy is only in `cards`. |
| `snapshot.final_url` | `string`, nullable | Final landing URL after redirects, when Facebook reports it; usually null. |
| `categories` | `string[]` | Special ad categories Facebook assigned. ["UNKNOWN"] for ordinary ads. |
| `currency` | `string` | Currency code of `spend` (e.g. USD) when spend is reported; an empty string otherwise. |
| `spend` | `any` | Spend range, reported for political and issue ads only; null otherwise. |
| `impressionsWithIndex` | `object` | Impressions range, reported for political and issue ads only. |
| `impressionsWithIndex.impressionsText` | `string`, nullable | The range as Facebook shows it; null when not reported. |
| `impressionsWithIndex.impressionsIndex` | `number` | Facebook's bucket number for the range; -1 when not reported. |
| `reachEstimate` | `any` | Estimated reach, which Facebook reports for some EU-delivered ads; null otherwise. |
| `url` | `string`, nullable | Ad Library link for this ad. Often null; build it as https://www.facebook.com/ads/library/?id=<Ad Library id>. |
| `containsDigitallyCreatedMedia` | `boolean` | Whether Facebook labels the creative as AI-generated or digitally altered. |
| `containsSensitiveContent` | `boolean` | Facebook internal field; false in every response we've seen. Facebook's sensitive-content flag. |
| `gatedType` | `string` | Facebook internal field; ELIGIBLE (lowercase in ad details) in every response we've seen. |
| `hasUserReported` | `boolean` | Whether the viewing user reported the ad. Always false: we read the Ad Library logged out. |
| `hideDataStatus` | `string` | Facebook internal field; NONE in every response we've seen. |
| `isAAAEligible` | `boolean` | Facebook flag, true on a few ads; meaning undocumented. Ad details' `aaa_info` holds the related data when present. |
| `menuItems` | `any[]` | Facebook internal field; an empty array in every response we've seen. |
| `pageIsDeleted` | `boolean` | Whether the advertiser's page has been deleted. |
| `regionalRegulationData` | `object` | Delivery limits under regional ad rules. |
| `regionalRegulationData.finserv` | `object` | Financial-services ad rules. |
| `regionalRegulationData.finserv.is_deemed_finserv` | `boolean` | Facebook treats the ad as a financial-services ad. |
| `regionalRegulationData.finserv.is_limited_delivery` | `boolean` | Delivery is limited under financial-services rules. |
| `regionalRegulationData.tw_anti_scam` | `object` | Taiwan's anti-scam ad rules. |
| `regionalRegulationData.tw_anti_scam.is_limited_delivery` | `boolean` | Delivery is limited under Taiwan's anti-scam rules. |
| `reportCount` | `number`, nullable | Times the ad was reported, when disclosed; null in every response we've seen. |
| `fevInfo` | `any` | Facebook internal field; null in every response we've seen. |
| `stateMediaRunLabel` | `any` | Label for ads run by state-controlled media; null otherwise. |
| `aaa_info` | `any` | Extra transparency data on some ads (see `isAAAEligible`); null in every response we've seen. |

## Caching and freshness

Responses are cached for up to 6 hours, so a repeat call within that window can return the same data. It still costs 1 credit.

## Errors

Errors return `{ success: false, error, code, docs }` with the HTTP status below. Validation errors, `401`/`402`/`429` rejections and `5xx` failures are free; `not_found` is charged ([how charging works](https://lurkapi.com/docs.md#credits)). [All error codes](https://lurkapi.com/docs.md#errors).

| Status | Code | Meaning |
| --- | --- | --- |
| 401 | `missing_api_key` | No API key. Send it in the `x-api-key` header. |
| 401 | `invalid_api_key` | The key is unknown or was revoked. |
| 402 | `insufficient_credits` | Not enough credits for this call. Buy a pack or wait for tomorrow's top-up. |
| 404 | `not_found` | The endpoint, or the thing you asked for (ad, post, subreddit), doesn't exist. Charged when the platform was checked. |
| 405 | `method_not_allowed` | Endpoints take GET with query params. |
| 429 | `rate_limited` | Too many calls at once. Wait for the `retry-after` seconds, then retry. |
| 500 | `internal_error` | Something broke on our side. Retry; 5xx errors are free. |
| 502 | `upstream_error` | The platform didn't give a usable answer. Retry; 5xx errors are free. |
| 503 | `upstream_busy` | All our connections to the platform are busy. Retry in a few seconds; 5xx errors are free. |
| 504 | `upstream_timeout` | The platform took over 30 seconds to answer. Retry; timeouts are free. |

## Use it in Claude

Once LurkAPI is [connected to Claude](https://lurkapi.com/docs.md#claude), this endpoint is the `facebook_ad` tool. Ask in plain English, for example:

Ask Claude:

```text
Use LurkAPI's facebook_ad with id "1016451784037642" and summarize what you find.
```

Claude calls `facebook_ad` with arguments like these, and each call costs 1 credit:

Tool arguments:

```json
{
  "id": "1016451784037642"
}
```

Tool results skip nulls and empty lists to save tokens, and `trim` defaults to `true`.

---

Previous: [Ad Library ads by company](https://lurkapi.com/docs/facebook/company-ads.md) · Next: [Search Ad Library companies](https://lurkapi.com/docs/facebook/search-companies.md)
