How do I see all ads a competitor is running on Facebook and Instagram?
Search the brand on Meta's Ad Library website, or get the same list as JSON: take the advertiser's ad_page_id from GET /facebook/pages/details (with their Page URL), then call GET /facebook/ads/search with ad_page_id, country=ALL and activeStatus=Active. Ads that run on Instagram are included, with INSTAGRAM in publisher_platform.
Meta's official option
Meta's Ad Library website shows every active ad of an advertiser for free, one brand at a time, by hand. Its API only covers political / issue ads and ads shown in the EU.
How to do it with SocialAPIs
Two ways to get the advertiser ID: /facebook/pages/details returns the Page's ad_page_id (1 credit, once per brand), or /facebook/ads/keywords with the brand name lists matching advertisers and their page_id. Then /facebook/ads/search returns their ads (1 credit per page of results; next page with end_cursor).
To hear when they launch a new ad, run the search daily and keep the ad_archive_ids you've seen: the tutorial has it in Python and n8n. One advertiser checked daily is about 30 calls a month.
Endpoints
GET /facebook/pages/details1 credit; 5 credits when exact_followers_count=true
Get Facebook page details.
Params:
link(required),exact_followers_count,page_sectionFacebook Page Details: docs and playgroundMCP:
facebook_page→detailsGET /facebook/ads/keywords1 credit
Search for ads by keyword with optional country filter.
Params:
query(required),countryMeta Ads Keywords Search: docs and playgroundMCP:
facebook_ads→keywordsGET /facebook/ads/search1 credit
Search ads in the Meta Ad Library by keyword or page ID with filters.
Params:
query,ad_page_id,country,activeStatus,after_time,before_time,sort_data,end_cursorMeta Ads Library Search: docs and playgroundMCP:
facebook_ads→search
curl -G "https://api.socialapis.io/facebook/ads/search" \
--max-time 100 \
--fail-with-body \
-H "x-api-token: $SOCIALAPIS_API_KEY" \
--data-urlencode "ad_page_id=71740214065" \
--data-urlencode "country=ALL" \
--data-urlencode "activeStatus=Active"import os
import requests
response = requests.get(
"https://api.socialapis.io/facebook/ads/search",
headers={"x-api-token": os.environ["SOCIALAPIS_API_KEY"]},
params={
"ad_page_id": "71740214065",
"country": "ALL",
"activeStatus": "Active",
},
timeout=100,
)
response.raise_for_status()
print(response.json())// Node 18+, as an ES module (e.g. main.mjs)
async function get(url, params) {
const query = new URLSearchParams(params).toString();
const response = await fetch(query ? `${url}?${query}` : url, {
headers: { "x-api-token": process.env.SOCIALAPIS_API_KEY },
signal: AbortSignal.timeout(100000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
return response.json();
}
const data = await get("https://api.socialapis.io/facebook/ads/search", {
ad_page_id: "71740214065",
country: "ALL",
activeStatus: "Active",
});
console.log(data);import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Map;
import java.util.stream.Collectors;
public class Main {
private static final HttpClient CLIENT = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
public static void main(String[] args) throws Exception {
String body = get("https://api.socialapis.io/facebook/ads/search", Map.of(
"ad_page_id", "71740214065",
"country", "ALL",
"activeStatus", "Active"));
System.out.println(body);
}
static String get(String url, Map<String, String> params) throws Exception {
String query = params.entrySet().stream()
.map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8) + "="
+ URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
HttpRequest request = HttpRequest.newBuilder(URI.create(query.isEmpty() ? url : url + "?" + query))
.header("x-api-token", System.getenv("SOCIALAPIS_API_KEY"))
.timeout(Duration.ofSeconds(100))
.GET()
.build();
HttpResponse<String> response = CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() / 100 != 2) {
throw new RuntimeException("HTTP " + response.statusCode() + ": " + response.body());
}
return response.body();
}
}package main
import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"time"
)
func main() {
body, err := get("https://api.socialapis.io/facebook/ads/search", url.Values{
"ad_page_id": {"71740214065"},
"country": {"ALL"},
"activeStatus": {"Active"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))
}
func get(endpoint string, params url.Values) ([]byte, error) {
if len(params) > 0 {
endpoint += "?" + params.Encode()
}
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
if err != nil {
return nil, err
}
req.Header.Set("x-api-token", os.Getenv("SOCIALAPIS_API_KEY"))
client := &http.Client{Timeout: 100 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode/100 != 2 {
return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, body)
}
return body, nil
}Your API key goes in the x-api-token header (here from the SOCIALAPIS_API_KEY environment variable). Get a free key.
Tutorial: Facebook Ads Library API without app reviewUse it from Claude, ChatGPT or Cursor (MCP)
Good to know
- Each ad has
page_name,start_date(Unix seconds),publisher_platformand the creative insnapshot(title,body.text,cta_text,link_url,cards). - Budgets aren't public:
spendisnullfor commercial ads. Long-running ads and many variants of one creative are the usual signals of what works. - Use it for research and monitoring; don't present a competitor's creative as your own.