Use cases
What teams build with it. From one request.
- Monitor competitors' ad creatives and offers
- Research ad copy in a market or niche
- Track political and issue ad spending
- Find the advertisers running ads on a topic
What you get
Ads in one schema. The same on every platform.
platformstring- Library owner's platform ID (facebook for Meta's library, tiktok, google, linkedin).
idstring- Library ad ID (string).
urlstring- Public library page of the ad.
advertiserobject- The advertising page, business or account.
paid_bystring- Disclosed payer ("Paid for by").
is_activeboolean- True while the ad is running.
first_shown_atstring- First delivery, RFC 3339 UTC (often date-only: see approximate_fields).
last_shown_atstring- Last delivery, RFC 3339 UTC; null while active.
Every field, its type and when it is null: the response reference and the ad schema.
Example request
curl -G 'https://staging-fly.socialtap.dev/v1/facebook/search_ads' \
--data-urlencode 'country=US' \
--data-urlencode 'query=coffee' \
--data-urlencode 'status=all' \
-H "x-api-key: $SOCIALTAP_API_KEY"const params = new URLSearchParams({
country: "US",
query: "coffee",
status: "all",
});
const res = await fetch(`https://staging-fly.socialtap.dev/v1/facebook/search_ads?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, page, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://staging-fly.socialtap.dev/v1/facebook/search_ads",
params={"country": "US", "query": "coffee", "status": "all"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, page, meta = body["data"], body["page"], body["meta"]
print(data, meta["credits_charged"])package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("country", "US")
q.Set("query", "coffee")
q.Set("status", "all")
req, err := http.NewRequest("GET", "https://staging-fly.socialtap.dev/v1/facebook/search_ads?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Page json.RawMessage `json:"page"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}<?php
$query = http_build_query([
'country' => 'US',
'query' => 'coffee',
'status' => 'all',
]);
$ch = curl_init('https://staging-fly.socialtap.dev/v1/facebook/search_ads?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;require "json"
require "net/http"
uri = URI("https://staging-fly.socialtap.dev/v1/facebook/search_ads")
uri.query = URI.encode_www_form('country' => 'US', 'query' => 'coffee', 'status' => 'all')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]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;
public class Main {
public static void main(String[] args) throws Exception {
String query = "country=" + encode("US")
+ "&query=" + encode("coffee")
+ "&status=" + encode("all");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://staging-fly.socialtap.dev/v1/facebook/search_ads?" + query))
.header("x-api-key", System.getenv("SOCIALTAP_API_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
// An error is {"error": {"code", "message", ...}}; success is {data, meta}, meta.credits_charged its price.
if (response.statusCode() >= 400) throw new RuntimeException(response.body());
System.out.println(response.body());
}
static String encode(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8);
}
}using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("x-api-key", Environment.GetEnvironmentVariable("SOCIALTAP_API_KEY"));
var query = string.Join("&",
"country=" + Uri.EscapeDataString("US"),
"query=" + Uri.EscapeDataString("coffee"),
"status=" + Uri.EscapeDataString("all"));
var res = await http.GetAsync("https://staging-fly.socialtap.dev/v1/facebook/search_ads?" + query);
using var body = JsonDocument.Parse(await res.Content.ReadAsStringAsync());
if (!res.IsSuccessStatusCode)
{
var error = body.RootElement.GetProperty("error");
throw new Exception($"{error.GetProperty("code")}: {error.GetProperty("message")}");
}
Console.WriteLine(body.RootElement.GetProperty("data"));
Console.WriteLine(body.RootElement.GetProperty("meta").GetProperty("credits_charged"));// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }, serde_json = "1"
use std::env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let res = reqwest::blocking::Client::new()
.get("https://staging-fly.socialtap.dev/v1/facebook/search_ads")
.query(&[("country", "US"), ("query", "coffee"), ("status", "all")])
.header("x-api-key", env::var("SOCIALTAP_API_KEY")?)
.send()?;
let ok = res.status().is_success();
let body: serde_json::Value = res.json()?;
if !ok {
return Err(format!("{}: {}", body["error"]["code"], body["error"]["message"]).into());
}
println!("{} {}", body["data"], body["meta"]["credits_charged"]);
Ok(())
}{
"data": [
{
"advertiser": {
"avatar_url": "https://scontent-atl3-2.xx.fbcdn.net/v/t39.35426-6/739782028_1533198008291919_1079542453788497101_n.jpg?stp=dst-jpg_s60x60_tt6&_nc_cat=104&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-2.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBED&…",
"display_name": "American Health Support Community",
"id": "966175593248497",
"is_verified": null,
"url": "https://www.facebook.com/61588018263996",
"username": null
},
"approximate_fields": [
"first_shown_at"
],
"audience_size": null,
"country_codes": [],
"creatives": [
{
"body": "My aunt called me a creep for putting a camera in Nana’s living room.\n\nNana called me practical.\n\nThen the camera caught something worse than a fall.\n\nI need to be clear about one thing before anyone decides what kind of grandson I am.\n\nNana asked for the camera.\n\nNot me.\n\nNot my…",
"cta_text": "Learn more",
"link_description": null,
"link_url": "https://shop.pipitea.com/hbt/kd/sp-nm",
"media": [
{
"alt_text": null,
"duration_ms": null,
"expires_at": "2026-10-25T18:00:00Z",
"height": null,
"thumbnail_url": "https://scontent-atl3-1.xx.fbcdn.net/v/t39.35426-6/742001725_2100792434176297_9060645049521596104_n.jpg?stp=dst-jpg_s600x600_tt6&_nc_cat=100&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-1.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBE…",
"type": "image",
"url": "https://scontent-atl3-1.xx.fbcdn.net/v/t39.35426-6/742501415_1706621370582971_4085631001896338504_n.jpg?_nc_cat=103&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-1.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBED&oe=F2A52380",
"width": null
}
],
"title": "Natural Relief in Weeks"
}
],
"first_shown_at": "2026-07-18T07:00:00Z",
"id": "2619351891814847",
"impressions": null,
"is_active": true,
"is_political": false,
"languages": [],
"last_shown_at": null,
"paid_by": null,
"platform": "facebook",
"platform_specific": {},
"publisher_platforms": [
"facebook",
"instagram",
"audience_network"
],
"reach": null,
"spend": null,
"type": "image",
"unknown_fields": [],
"url": "https://www.facebook.com/ads/library/?id=2619351891814847"
},
{
"advertiser": {
"avatar_url": "https://scontent-atl3-1.xx.fbcdn.net/v/t39.35426-6/712623693_1599994994434095_1320701223312676781_n.jpg?stp=dst-jpg_s60x60_tt6&_nc_cat=110&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-1.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBED&…",
"display_name": "American Health Support Community",
"id": "966175593248497",
"is_verified": null,
"url": "https://www.facebook.com/61588018263996",
"username": null
},
"approximate_fields": [
"first_shown_at"
],
"audience_size": null,
"country_codes": [],
"creatives": [
{
"body": "I almost looked past the woman who saved my husband's life. She was seventy-nine, sitting alone at the booth next to ours at the Cracker Barrel off Highway 31. A glass of milk in front of her. She kept stirring it. She wasn't eating.\n\nIf I'd known, the night I leaned over and ask…",
"cta_text": "Learn more",
"link_description": "\"I've tried everything to support my kidney function naturally. Fish oil, CoQ10, cutting protein, stressing about every meal. Nothing moved the needle enough to satisfy my doctor. Hibiscus tea is the first thing that actually showed up in my numbers. It's been 3 months and my eGF…",
"link_url": "https://shop.pipitea.com/hbt/kd/sp",
"media": [
{
"alt_text": null,
"duration_ms": null,
"expires_at": "2026-10-25T18:00:00Z",
"height": null,
"thumbnail_url": "https://scontent-atl3-2.xx.fbcdn.net/v/t39.35426-6/711729685_1717035472767079_186136568392095276_n.jpg?stp=dst-jpg_s600x600_tt6&_nc_cat=104&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-2.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBED…",
"type": "image",
"url": "https://scontent-atl3-1.xx.fbcdn.net/v/t39.35426-6/713729791_868879862958547_7409366389733397444_n.jpg?_nc_cat=107&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-1.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBED&oe=F2A52380",
"width": null
}
],
"title": "Natural Relief in Weeks"
}
],
"first_shown_at": "2026-06-01T07:00:00Z",
"id": "1923645134954720",
"impressions": null,
"is_active": true,
"is_political": false,
"languages": [],
"last_shown_at": null,
"paid_by": null,
"platform": "facebook",
"platform_specific": {},
"publisher_platforms": [
"facebook",
"instagram",
"audience_network"
],
"reach": null,
"spend": null,
"type": "image",
"unknown_fields": [],
"url": "https://www.facebook.com/ads/library/?id=1923645134954720"
},
{
"advertiser": {
"avatar_url": "https://scontent-atl3-1.xx.fbcdn.net/v/t39.35426-6/712025330_1303417705276292_736671271727941526_n.jpg?stp=dst-jpg_s60x60_tt6&_nc_cat=103&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-1.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBED&o…",
"display_name": "American Health Support Community",
"id": "966175593248497",
"is_verified": null,
"url": "https://www.facebook.com/61588018263996",
"username": null
},
"approximate_fields": [
"first_shown_at"
],
"audience_size": null,
"country_codes": [],
"creatives": [
{
"body": "I almost looked past the woman who saved my husband's life. She was seventy-nine, sitting alone at the booth next to ours at the Cracker Barrel off Highway 31. A glass of milk in front of her. She kept stirring it. She wasn't eating.\n\nIf I'd known, the night I leaned over and ask…",
"cta_text": "Learn more",
"link_description": "\"I've tried everything to support my kidney function naturally. Fish oil, CoQ10, cutting protein, stressing about every meal. Nothing moved the needle enough to satisfy my doctor. Hibiscus tea is the first thing that actually showed up in my numbers. It's been 3 months and my eGF…",
"link_url": "https://shop.pipitea.com/hbt/kd/sp",
"media": [
{
"alt_text": null,
"duration_ms": null,
"expires_at": "2026-10-25T18:00:00Z",
"height": null,
"thumbnail_url": "https://scontent-atl3-1.xx.fbcdn.net/v/t39.35426-6/711737708_4485707625086258_2353150069319301753_n.jpg?stp=dst-jpg_s600x600_tt6&_nc_cat=109&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-1.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBE…",
"type": "image",
"url": "https://scontent-atl3-2.xx.fbcdn.net/v/t39.35426-6/710755472_911440771966686_1736050619245168045_n.jpg?_nc_cat=111&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=14&_nc_ht=scontent-atl3-2.xx&_nc_gid=SCRUBBED&_nc_ss=7b289&oh=SCRUBBED&oe=F2A52380",
"width": null
}
],
"title": "Natural Relief in Weeks"
}
],
"first_shown_at": "2026-06-01T07:00:00Z",
"id": "2140497416496021",
"impressions": null,
"is_active": true,
"is_political": false,
"languages": [],
"last_shown_at": null,
"paid_by": null,
"platform": "facebook",
"platform_specific": {},
"publisher_platforms": [
"facebook",
"instagram",
"audience_network"
],
"reach": null,
"spend": null,
"type": "image",
"unknown_fields": [],
"url": "https://www.facebook.com/ads/library/?id=2140497416496021"
}
],
"page": {
"has_more": true,
"next_cursor": "c1.EXAMPLE_CURSOR",
"next_cursor_expires_at": "2026-10-26T12:00:00Z",
"end_reason": null
},
"meta": {
"request_id": "req_3f9c2a7d1e8b4c6a9f0e2d4b6a8c0e1f",
"platform": "facebook",
"source": "api",
"is_cached": false,
"credits_charged": 1,
"latency_ms": 0,
"fetched_at": "2026-10-25T12:00:00Z",
"input": null,
"credits_remaining": 9999,
"client_request_id": null,
"warnings": [],
"mode": "live"
}
}Long arrays and strings are shortened for display; real responses are complete.
Pricing
Pay per page. Only when it succeeds.
| Source | Price per successful page | Per 1,000 pages |
|---|---|---|
Platform API api | 1 credit | $0.75–$1.45 |
- Failed requests are free: errors cost 0 credits.
- Cache hits are free: responses served from the cache cost 0 credits.
- Credits never expire.
- One credit balance for every endpoint and platform.
Credit packs · How this endpoint is priced · How credits work
FAQ