Facebook's Ad Library (facebook.com/ads/library) lets you search ads by keyword or advertiser, but there's no official API for it — Meta's Ad Library API exists but requires an app review and only covers political/social-issue ads in most regions. If you want to pull any active ad by keyword or Page ID into a script, you end up scraping the library's internal GraphQL endpoint yourself, which breaks every few months when Meta changes its payload shape.
AxioAPI wraps that endpoint behind a stable REST route so you don't maintain the scraper.
The endpoint
GET https://axioapi.com/api/v1/social/facebook/ads Query params (validated server-side):
| param | required | notes |
|---|---|---|
q | yes, unless page_id is set | keyword, up to 100 chars |
page_id | yes, unless q is set | numeric Facebook Page ID, 5–25 digits |
search_type | no | KEYWORD_EXACT_PHRASE, KEYWORD_UNORDERED, or PAGE (default behaves like a page lookup when page_id is present) |
country | no | two-letter code or ALL, defaults to US |
status | no | ACTIVE, INACTIVE, or ALL |
limit | no | 1–50 |
cursor | no | pagination cursor from a previous response |
Example: ads currently running for a brand
const API = 'https://axioapi.com/api/v1'; const headers = { Authorization: `Bearer ${process.env.AXIOAPI_KEY}`, Accept: 'application/json' }; async function searchAds(pageId, country = 'US') { const url = new URL(`${API}/social/facebook/ads`); url.searchParams.set('page_id', pageId); url.searchParams.set('search_type', 'PAGE'); url.searchParams.set('country', country); url.searchParams.set('status', 'ACTIVE'); const res = await fetch(url, { headers }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); return (await res.json()).data; } // Nike's Page ID searchAds('15087023444').then((data) => console.log(data)); A keyword search works the same way with q instead of page_id:
url.searchParams.set('q', 'nike'); url.searchParams.set('search_type', 'KEYWORD_EXACT_PHRASE'); What you get back
Each ad in the response carries the usual Ad Library fields (creative text, CTA, link, start/end date) plus two derived fields AxioAPI computes for you so you don't have to:
-
days_active— how many days the ad has run (capped at "now" for still-active ads) -
is_winning_candidate—trueoncedays_active >= 14, a common rough signal that an ad is profitable enough for the advertiser to keep running -
cta_type— normalized CTA text (SHOP_NOW,LEARN_MORE, …) -
target_landing_page— hostname extracted from the ad's link URL
That last part matters if you're doing competitive research: instead of reading every ad's HTML, you can group an advertiser's active ads by landing page hostname and see which funnel they're pushing the most budget into right now.
Rate limits and caching
Results are cached server-side per query for about an hour, so repeated lookups of the same keyword or Page ID within that window don't cost you anything extra and don't hit the upstream twice. If you're building a dashboard that polls a handful of competitor Page IDs daily, this is cheap — check current pricing on the Social — Facebook API page before wiring it into anything high-volume.
If you just want to paste in a brand name and look, there's a free Facebook Ad Spy tool — no code, no account needed for the first few lookups.
