A Meta Ad Library API, for someone building a tool, is a keyword search over the ads in the library. GET /v1/facebook/ad-library/search does that. It is a SocialScrape route. It is not Meta's official API, and it does not create or edit ads.
Send the key in x-api-key. See authentication.
Parameters
query- is required.
keywordandqare aliases.regionis the one country to search. Use a two-letter code, orALLfor every country. The recorded search usesquery=nikeandregion=US. sort- is
relevance,impressionsornewest.impressionsis most impressions first.newestis most recent. Changing sort restarts the cursor chain.matchisany_wordsorexact_phrase.ad_typeisallorpolitical(political and issue ads only).statusisactive,inactiveorall.active_statusis an alias ofstatus.media_typeisall,image,video,meme,image_and_memeornone. The reference saysmemeis Meta's word for text on an image.languageis a 2-letter code such asEN,ESorFR.start_dateandend_dateare the impressions window,YYYY-MM-DD. cursor- pages. The route is also available as POST with a JSON body, for cursors too long for a URL. The recorded GET below is a later page: it includes a cursor. For the first page, send
queryandregiononly.
A first page for the recorded query:
1curl -G "https://api.socialscrape.dev/v1/facebook/ad-library/search" \2 -H "x-api-key: $SOCIALSCRAPE_API_KEY" \3 --data-urlencode "query=nike" \4 --data-urlencode "region=US"The recorded request, cursor included, in three languages:
1curl -G "https://api.socialscrape.dev/v1/facebook/ad-library/search" \2 -H "x-api-key: $SOCIALSCRAPE_API_KEY" \3 --data-urlencode "query=nike" \4 --data-urlencode "region=US" \5 --data-urlencode "cursor=eyJrIjoiZmJhZHMiLCJjIjoiQVFIVHR6TWN1R1ZGekcxSF85UzBpNjN5VTVMYjFzZHFDZmZaRjRYeHRHS205dXlVNG1BTUpkT2F3VEg1YUM4VWdvV2EifQ"1import os2import requests34params = {5 "query": "nike",6 "region": "US",7 "cursor": "eyJrIjoiZmJhZHMiLCJjIjoiQVFIVHR6TWN1R1ZGekcxSF85UzBpNjN5VTVMYjFzZHFDZmZaRjRYeHRHS205dXlVNG1BTUpkT2F3VEg1YUM4VWdvV2EifQ",8}9res = requests.get(10 "https://api.socialscrape.dev/v1/facebook/ad-library/search",11 headers={"x-api-key": os.environ["SOCIALSCRAPE_API_KEY"]},12 params=params,13)14body = res.json()1516if body["ok"]:17 print(body["data"])18else:19 print(body["error"]["code"], body["error"]["message"])1const url = new URL("https://api.socialscrape.dev/v1/facebook/ad-library/search");2url.search = new URLSearchParams({3 "query": "nike",4 "region": "US",5 "cursor": "eyJrIjoiZmJhZHMiLCJjIjoiQVFIVHR6TWN1R1ZGekcxSF85UzBpNjN5VTVMYjFzZHFDZmZaRjRYeHRHS205dXlVNG1BTUpkT2F3VEg1YUM4VWdvV2EifQ"6}).toString();7const res = await fetch(url, {8 headers: { "x-api-key": process.env.SOCIALSCRAPE_API_KEY! },9});10const body = await res.json();1112if (body.ok) {13 console.log(body.data);14} else {15 console.error(body.error.code, body.error.message);16}Check ok. invalid_params and not_found are not retryable. rate_limited is.
What an ad contains
data.items are ads. data.object is list. Each ad has:
objectad,platform,id,url(an Ad Library link).advertiser, with its ownid,nameandurlwhen the library sends them.status,started_at,ended_at.title,body,cta_text,landing_url,format.media:thumbnail_url,video_url,audio_url,image_urls,width,height. Long CDN links expire.extra.media_expires_atis the time on the recording.regions,publisher_platforms.impressionsandspend.
In the recorded sample, impressions and spend are null on the ads shown. The fields exist so a number can be carried when the library publishes one. Null is not a zero. Political and regulated ads add transparency data under extra, including impressions_text, page_spend and reach_estimate on the single-ad endpoint. Do not assume a keyword search of ordinary ads fills spend.
extra on a search hit also includes caption, cards (carousel bodies, titles, cta_text, link_url), categories, collation_count, collation_id, link_description, contains_digital_created_media, contains_sensitive_content and video_urls.
publisher_platforms in the sample lists where the ad ran, such as facebook, instagram and messenger, when the library says so.
Sample. The recorded payload is shortened. Ad copy and landing URLs in it are from that recording. Page with cursor while has_more is true. Each page is 1 credit. See pagination.
One ad
GET /v1/facebook/ad-library/ad- takes
idorurl. One of them.urlisfacebook.com/ads/library/?id=.... The response is one ad: page, status, dates and the snapshot (text, images, videos, format, link, call to action). Regulated ads put transparency data inextra. get_transcript- is accepted and does not transcribe the video. The reference says a video ad's transcript is its own call,
ad/transcript, billed as AI transcription, and this flag only adds a pointer inextra.transcript_hint. Leave the flag off unless you want that pointer.
The recorded ad request uses an id. It is 1 credit on success, cacheable for 30 days like the search.
Cost
Search page: 1 credit. One ad: 1 credit. A transcript, if you add it later, follows the transcription rule in AI transcription: 1 credit up to 2 minutes, then 5 per started minute of the whole video.
That is a different price from the search. Do not assume the transcript is inside the 1 credit search.
Failures cost 0. max_age_days makes a cached repeat free. Results are kept 30 days. Signup is 100 credits, once, no card. See pricing and credits.
Limits
You get what the library returns for that query, country and filters. You do not get an advertiser's private account, their unpublished drafts, or a guaranteed spend figure.
ALL is wider and not a substitute for reading regions on each ad. Sort by impressions still returns null impression counts when Meta hides the number. The order can change without a filled impressions field.
not_found means nothing matched or the id is unknown. Stop. Packs and plans have no rate limits; free accounts have a lower one. See rate limits and errors.
Next
Search: Facebook Ad Library API, tutorial, reference. One ad: ad details API and reference. The hub is the Facebook API. LinkedIn has a separate ad library route if that is the network you meant: LinkedIn Ad Library search.
There is also a TikTok ad library under the TikTok API. It is not this endpoint.