Facebook Ad Library API — Get an Advertiser’s Ads
Documentation menu
FetchLayer FetchLayer API

Get every ad one advertiser runs

Every ad one advertiser is running, from a page id, an Ad Library URL, a facebook.com page URL, a handle or the page’s exact name, with the same filters as a keyword search. Up to 30 ads a page. Every ad returned names this advertiser as advertiser, sponsor or a partnership account; any that does not is left out and listed in notes, and if none does the request is a 404. An advertiser with no ads matching your filters is an empty list.

POST /advertiser-ads Ads
https://api.fetchlayer.dev/facebook-ad-library/advertiser-ads
OpenAPI JSON

Headers

Authorization string required

Bearer token — your FetchLayer API key.

Parameters

advertiser string required

Advertiser page id (5–17 digits), Ad Library advertiser URL, facebook.com/<username> page URL, the page’s username with or without @ (even when it differs from the page’s name), or its full name. A page id of any other length, such as 20 digits, is a 400; a well-formed id that matches no advertiser is a 404. A URL or handle names that exact page. A name must be the page’s own username or full name (ignoring case and punctuation) — a page that merely contains it is not used; no match is a 404, and a name several pages share is a 400 listing their page ids. The page id is fastest and exact.

query string optional

Optional keyword to filter within the advertiser's ads.

includeProfiles boolean optional

Also fill in the Instagram username of every account on the returned ads — advertiser, sponsor and both partnership accounts — up to 30 distinct accounts per request. Usually adds under a second (a few seconds when nearly every ad names a different account), costs nothing extra, and a username that cannot be filled never fails the request: instagramUsernameStatus says why, account by account. (default: false)

country string optional

Two-letter country code, or ALL. (default: ALL)

countries string[] optional

Several countries at once (max 20). Overrides country.

activeStatus string optional

active, inactive, or all. (default: active)

adType string optional

ALL, POLITICAL_AND_ISSUE_ADS (POLITICAL is accepted for it), or a special ad category: HOUSING_ADS, EMPLOYMENT_ADS or FINANCIAL_PRODUCTS_AND_SERVICES_ADS (CREDIT_ADS is its earlier name and filters the same). Case-insensitive. (default: ALL)

mediaType string optional

all, image, meme, image_and_meme, video, or none.

publisherPlatforms string[] optional

FACEBOOK, INSTAGRAM, MESSENGER, AUDIENCE_NETWORK, WHATSAPP, THREADS, OCULUS, UNKNOWN.

contentLanguages string[] optional

Two-letter ad language codes, for example en or es.

bylines string[] optional

Political-ad disclaimers ("paid for by").

startDateFrom string optional

Only ads whose impressions start on or after this YYYY-MM-DD date.

startDateTo string optional

Only ads whose impressions start on or before this YYYY-MM-DD date.

isTargetedCountry boolean optional

Restrict to ads targeting the country rather than merely reaching it.

limit integer optional

Maximum ads returned (max 2000), or -1 for everything available. A request returns up to limit or pages × 30 ads, whichever is smaller. (default: 30)

pages integer optional

Pages of up to 30 ads to collect in one request (max 100), or -1 for the maximum allowed. A very large request stops early, with hasNextPage true, a nextCursor and a note, rather than running past the response time limit. (default: 1)

cursor string optional

Resume from a previous response's nextCursor. Send it with the same route, advertiser or query, country and filters; limit, pages, sortBy and format may change. A cursor from a different route, advertiser, query, country or set of filters, or one that was altered, is a 400 saying which. Cursors issued before October 2026 are still accepted, with a note, and the response carries a current nextCursor. Any other string is a 400: pass nextCursor back exactly as received.

delayMs integer optional

Milliseconds to wait between pages (max 30000).

sortBy string optional

start_date, end_date, total_active_time, or none. Orders the ads in this response, not the whole listing; collect more pages for a wider ordering.

sortDirection string optional

asc or desc.

format string optional

json or markdown, lowercase; any other value is a 400. Over MCP, markdown returns the result rendered as text; the REST API accepts it and returns JSON. (default: json)

timeoutMs integer optional

Time limit for the whole request, in milliseconds (1000–120000), counted from its arrival, time spent waiting in the queue included; a value outside that range is a 400. When it runs out, a paged request returns what it has with nextCursor and a note, billed for the pages it delivered; a request with nothing to return yet fails with a 503 you can retry, marked with the response header X-Timeout-Source: caller. Left out, the request runs as long as it needs.

Response Fields

advertiser-ads

Get every ad one advertiser runs

pageId string

The resolved advertiser page id.

pageName string | null

The advertiser’s page name; null when not known.

ads object[]

The matching ads, newest data first unless sortBy says otherwise. A field Facebook does not provide is null, or [] for a list — never left out; false and 0 are real values. An ad with odd or missing fields is always returned, with those fields null.

skippedAds object[]

Records in the listing that cannot be an ad at all — an empty entry, or one with no ad archive id — each with what is still known about it, and counted in notes; [] when none. Only that record is left out: the rest of the page and nextCursor are unaffected.

skippedAds[].reason string

not-an-object (an empty entry where an ad belongs), missing-ad-archive-id, or unreadable (a record with an id whose contents could not be used).

skippedAds[].adArchiveId string | null

The ad archive id, when the record had one.

skippedAds[].adId string | null

The ad’s own id, when the record had one.

skippedAds[].pageId string | null

The advertiser’s page id, when the record named one.

skippedAds[].fieldsPresent string[]

The ad fields the record carried values for, by their names on an ad, for example startDate, advertiser or creative.

notes string[]

Caveats about this result, such as an ad left out or a list that may be incomplete.

ads[].adArchiveId string

Ad Library archive id — the handle for ad-detail and ad-media.

ads[].adLibraryUrl string

Public Ad Library permalink for this ad.

ads[].isActive boolean

Whether the ad was still running at the time of the request.

ads[].startDate string | null

The day the ad started running, as a UTC date (YYYY-MM-DD); null when not published.

ads[].endDate string | null

The day the ad stopped running, as a UTC date; for a running ad Facebook reports the current day. null when not published.

ads[].startDateUnix integer | null

startDate as Unix seconds (UTC); null when not published.

ads[].endDateUnix integer | null

endDate as Unix seconds (UTC); for a running ad, the current day. null when not published.

ads[].totalActiveTimeSeconds integer | null

How long the ad has been live — the usual proxy for what is working. null when not published.

ads[].publisherPlatforms string[]

Surfaces the ad ran on (Facebook, Instagram, Messenger, Threads…).

ads[].advertiser object

The account the ad appears under: page id, name, URL, categories, like count, political byline, pageAlias, instagramUsername and instagramUsernameStatus. On a partnership ad this is partnership.postedBy.

ads[].advertiser.pageAlias string | null

The account’s Facebook username; null when it publishes none.

ads[].advertiser.instagramUsername string | null

The Instagram username; null when the page links none or it is not known — instagramUsernameStatus says which. Without includeProfiles most Facebook Pages on these listings are not-looked-up.

ads[].advertiser.instagramUsernameStatus string

found: instagramUsername is the account’s username. not-published: the page’s own details link no Instagram account. not-looked-up: not known here — an ad names an Instagram account only when it is shown under one, so null says nothing about whether there is one; includeProfiles fills it in, as do ad-detail for the advertiser and advertiser-profile (as igUsername). With includeProfiles: lookup-failed (no answer for this account this time; asking again may fill it), skipped-cap (past the 30 accounts filled per request) or skipped-time (not filled in the time available). A username that cannot be filled never fails the request. sponsor and both partnership accounts carry it too.

ads[].sponsor object

The account that ran the ad: pageId, pageName, pageUrl, pageIsDeleted, pageAlias, instagramUsername and instagramUsernameStatus. The same account as advertiser except on some partnership ads.

ads[].isPartnershipAd boolean

Whether the ad carries Facebook’s “Paid partnership with” label (branded content).

ads[].partnership object | null

On a paid-partnership or collaboration ad, the two accounts by position, each with pageId, pageName, pageUrl, pageIsDeleted, pageAlias, instagramUsername and instagramUsernameStatus: postedBy (A in “A with B”) and taggedPartner (B), plus runBy, brand, creator and relationship. null on every other ad.

ads[].partnership.postedBy object

The account the ad appears under: A in “A with B”. To show “A with B” for any partnership ad, use postedBy as A and taggedPartner as B.

ads[].partnership.taggedPartner object

The account the ad tags: B in “A with B”.

ads[].partnership.runBy string

Which of the two ran (paid for) the ad: creator (postedBy), brand (taggedPartner) or other (neither). It says who ran the ad, not which party is the business.

ads[].partnership.brand object

The same account as taggedPartner, named after Meta’s branded-content convention that the tagged account is the brand. That does not always hold: when a brand posts a collaboration and tags a creator, brand is the creator. Example, ad 2076260499666267: Red Bull Argentina posts and runs it, tagging the Instagram creator martibenza — postedBy and creator are Red Bull Argentina, taggedPartner and brand are martibenza, runBy is creator.

ads[].partnership.creator object

The same account as postedBy; see brand on why these names are positions.

ads[].partnership.relationship string

paid_partnership, for paid partnerships and Instagram collaborations alike: Facebook publishes no difference between them.

ads[].collationId string | null

The version group Facebook files the ad under, or null when it files it under none (which also means a single version). ad-detail lists the versions in variations.

ads[].collationCount integer | null

How many versions Facebook counts in that group for your filters; 1 means the ad runs alone in its group. null when there is no group.

ads[].creative object

Title, body, caption, link, CTA, display format, plus videos, images and carousel cards. Media URLs here are Facebook’s own signed links, which expire within hours; for a download that keeps working, use the downloadUrl from ad-media.

ads[].transparency object

Spend, currency, impressions and reach bands, published for political and issue ads. categories lists the special ad categories the ad declared — POLITICAL, HOUSING, EMPLOYMENT, CREDIT, possibly more than one — or [] for other ads.

adCount integer

Number of ads in this response.

pagesScraped integer

How many pages of up to 30 ads this response delivered — a stable count that depends only on how many ads came back. Billing follows it: 1 credit per page of up to 30 ads, and an empty result still costs the 1 credit every request pays.

pagesFetched integer

A diagnostic that can vary between identical requests, so do not rely on it. It is never billed.

totalCount integer | null

Facebook’s own estimate of how many ads match the whole listing. Usually present on the first page of a listing for a single country or ALL, and exact when the response reached the end of the listing. null means not known — including on some first pages — not zero.

nextCursor string | null

Pass back as cursor to continue from where this response stopped — at the first ad not yet returned, also when limit ended the response partway through a page.

hasNextPage boolean

Whether more results are available beyond this response.

Request

curl -X POST "https://api.fetchlayer.dev/facebook-ad-library/advertiser-ads" \
  -H "Authorization: Bearer ss-your-key" \
  -H "Content-Type: application/json" \
  -d '{"advertiser":"https://www.facebook.com/ads/library/?view_all_page_id=15087023444","activeStatus":"active","pages":3}'

Response

{
  "pageId": "15087023444",
  "pageName": "Nike",
  "adCount": 42,
  "pagesScraped": 2,
  "pagesFetched": 5,
  "totalCount": 42,
  "hasNextPage": false,
  "nextCursor": null,
  "ads": []
}