Every API here is available over the APIs.io API and to AI agents over MCP.
{
"openapi": "3.0.3",
"info": {
"title": "Meta Ad Library Spend API by AdSpendSpy",
"version": "1.0.0",
"description": "Account-scoped access to the advertisers you track in AdSpendSpy, their ads, your saved lists, projects and pending alerts, plus AdSpendSpy's estimated ad spend in EUR (cumulative).\n\nAll spend figures are estimates. For ads in the EU and UK they are based on reach data that Meta publishes; for other markets they are extrapolated.\n\nEach API key allows 1,000 requests per day, and an account can hold up to five active keys. Every endpoint requires an active membership or eligible trial; without one the API answers 402.\n\nNew ads and spend alerts are available by polling (ads/new.php, alerts/list.php) or as signed webhooks (webhooks/subscribe.php); webhook deliveries use no requests.\n\nAdSpendSpy is not affiliated with or endorsed by Meta Platforms.",
"contact": {
"name": "AdSpendSpy Support",
"email": "support@adspendspy.com",
"url": "https://www.adspendspy.com/contact"
},
"termsOfService": "https://www.adspendspy.com/terms",
"license": {
"name": "Proprietary",
"url": "https://www.adspendspy.com/terms"
},
"x-logo": {
"url": "https://www.adspendspy.com/assets/brand/signal-lens-icon.png",
"backgroundColor": "#FFFFFF"
}
},
"externalDocs": {
"description": "API documentation",
"url": "https://www.adspendspy.com/api-docs"
},
"servers": [
{
"url": "https://www.adspendspy.com/api/v1"
}
],
"tags": [
{
"name": "Brands",
"description": "Advertisers you track: list, search, check and start tracking."
},
{
"name": "Ads",
"description": "Ads of your tracked advertisers, with cumulative estimated spend in EUR."
},
{
"name": "Statistics",
"description": "Spend breakdowns and landing pages across your tracked advertisers."
},
{
"name": "Lists",
"description": "Your saved ad lists."
},
{
"name": "Projects",
"description": "Your advertiser groupings."
},
{
"name": "Alerts",
"description": "Your alerts: the pending count and spend alerts of your tracked advertisers."
},
{
"name": "Webhooks",
"description": "Signed deliveries of new ads and spend alerts to your https URL (REST hooks for Zapier, Make, n8n or your own code)."
}
],
"paths": {
"/brands/list.php": {
"get": {
"operationId": "list_tracked_brands",
"tags": [
"Brands"
],
"summary": "List tracked advertisers",
"description": "List your actively tracked advertisers and their string page_id values.",
"security": [
{
"bearerAuth": []
},
{
"apiKeyHeader": []
},
{
"oauth2": [
"account.read"
]
}
],
"parameters": [
{
"name": "project",
"in": "query",
"required": false,
"description": "all, my_brands, unassigned, or an owned project public_id. Every choice stays within your tracked brands.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 100
}
}
],
"responses": {
"200": {
"description": "Success.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BrandListResponse"
},
"example": {
"success": true,
"data": [
{
"id": 4821,
"page_id": "116482854782233",
"brand_name": "Alex Hormozi",
"brand_image": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg",
"category": "Entrepreneur",
"likes": 952142,
"verification": "BLUE_VERIFIED",
"ig_username": "hormozi",
"ig_followers": 4940960,
"created_at": "2026-09-13 09:30:12",
"ad_count": 708
}
],
"count": 1,
"total_count": 1
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"402": {
"$ref": "#/components/responses/PaymentRequired"
},
"403": {
"$ref": "#/components/responses/Forbidden"
},
"405": {
"$ref": "#/components/responses/MethodNotAllowed"
},
"429": {
"$ref": "#/components/responses/TooManyRequests"
},
"503": {
"$ref": "#/components/responses/Unavailable"
}
}
}
},
"/brands/search-tracked.php": {
"get": {
"operationId": "search_tracked_brands",
"tags": [
"Brands"
],
"summary": "Find a tracked advertiser",
"description": "Search your tracked advertisers by name, Meta page ID, or stored Facebook URL. Searches existing local data only; does not resolve vanity URLs through paid providers.",
"security": [
{
"bearerAuth": []
},
{
"apiKeyHeader": []
},
{
"oauth2": [
"account.read"
]
}
],
"parameters": [
{
"name": "q",
"in": "query",
"required": true,
"schema": {
"type": "string",
"maxLength": 500,
"minLength": 1
}
}
],
"responses": {
"200": {
"description": "Success.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BrandSearchResponse"
},
"example": {
"success": true,
"results": [
{
"id": 4821,
"page_id": "116482854782233",
"brand_name": "Alex Hormozi",
"brand_image": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg",
"ad_brand_name": "Alex Hormozi",
"ad_brand_image": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg",
"ad_count": 708,
"status": "tracked",
"display_name": "Alex Hormozi",
"display_image": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg"
}
],
"count": 1
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"402": {
"$ref": "#/components/responses/PaymentRequired"
},
"403": {
"$ref": "#/components/responses/Forbidden"
},
"405": {
"$ref": "#/components/responses/MethodNotAllowed"
},
"429": {
"$ref": "#/components/responses/TooManyRequests"
},
"503": {
"$ref": "#/components/responses/Unavailable"
}
}
}
},
"/brands/check-tracked.php": {
"post": {
"operationId": "check_brands_tracked",
"tags": [
"Brands"
],
"summary": "Check advertiser tracking",
"description": "Check whether each string Meta page ID is actively tracked by your account.",
"security": [
{
"bearerAuth": []
},
{
"apiKeyHeader": []
},
{
"oauth2": [
"account.read"
]
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"page_ids": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[0-9]{5,25}$",
"description": "Meta advertiser page ID, kept as a string."
},
"minItems": 1,
"maxItems": 100
}
},
"required": [
"page_ids"
],
"additionalProperties": false
},
"example": {
"page_ids": [
"116482854782233"
]
}
}
}
},
"responses": {
"200": {
"description": "Success.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CheckTrackedResponse"
},
"example": {
"success": true,
"tracked": {
"116482854782233": 4821
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"402": {
"$ref": "#/components/responses/PaymentRequired"
},
"403": {
"$ref": "#/components/responses/Forbidden"
},
"405": {
"$ref": "#/components/responses/MethodNotAllowed"
},
"413": {
"$ref": "#/components/responses/PayloadTooLarge"
},
"429": {
"$ref": "#/components/responses/TooManyRequests"
},
"503": {
"$ref": "#/components/responses/Unavailable"
}
}
}
},
"/brands/track.php": {
"post": {
"operationId": "track_brand",
"tags": [
"Brands"
],
"summary": "Start tracking an advertiser",
"description": "Add a known advertiser to your tracked brands before reading its ads. Changes your AdSpendSpy account: the advertiser joins your tracked brands and AdSpendSpy starts importing its ads. Requires a Meta page_id and brand_name and consumes one of your existing account tracking slots, not an extra subscription. Repeating an active tracking is idempotent, even at the limit. New imports run in the background, so ads may not be ready yet. Returns tracked_count, tracked_limit, remaining_slots and ingestion_state. There is no MCP removal tool: remove brands on the AdSpendSpy website. Does not search Meta or resolve advertiser names or URLs.",
"security": [
{
"bearerAuth": []
},
{
"apiKeyHeader": []
},
{
"oauth2": [
"brands.track"
]
}
],
"parameters": [
{
"name": "X-App-Language",
"in": "header",
"required": false,
"description": "Language of message (for example en, de, fr). Unknown values fall back to English.",
"schema": {
"type": "string",
"maxLength": 16
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"page_id": {
"type": "string",
"pattern": "^[0-9]{5,25}$",
"description": "Meta advertiser page ID, kept as a string."
},
"brand_name": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "Advertiser display name, not a URL or an instruction."
}
},
"required": [
"page_id",
"brand_name"
],
"additionalProperties": false
},
"example": {
"page_id": "116482854782233",
"brand_name": "Alex Hormozi"
}
}
}
},
"responses": {
"200": {
"description": "The advertiser was already tracked (already_tracked true). Repeating is idempotent, even at the limit.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrackBrandResponse"
},
"example": {
"success": true,
"message": "Brand already tracked",
"brand_id": 4821,
"page_id": "116482854782233",
"already_tracked": true,
"reactivated": false,
"tracked_count": 4,
"tracked_limit": 10,
"remaining_slots": 6,
"ingestion_state": "ready",
"ads_count": 708,
"message_key": "account_common.api.brands_track.already_tracked"
}
}
}
},
"201": {
"description": "Tracking started. A new import runs in the background, so ads may not be ready yet (see ingestion_state).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrackBrandResponse"
},
"example": {
"success": true,
"message": "Brand tracked successfully",
"brand_id": 4821,
"page_id": "116482854782233",
"already_tracked": false,
"reactivated": false,
"tracked_count": 3,
"tracked_limit": 10,
"remaining_slots": 7,
"ingestion_state": "ready",
"ads_count": 708,
"message_key": "account_common.api.brands_track.tracked"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"402": {
"$ref": "#/components/responses/PaymentRequired"
},
"403": {
"description": "Tracked-brand limit reached (limit_reached true, remaining_slots 0). The same status is used when the credential may not call this endpoint or the OAuth token lacks brands.track.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"success": false,
"message": "You have reached your tracked brands limit. Remove a tracked brand on the AdSpendSpy website or upgrade your plan.",
"limit_reached": true,
"tracked_count": 10,
"tracked_limit": 10,
"remaining_slots": 0,
"message_key": "account_common.api.brands_track.limit_reached"
}
}
}
},
"405": {
"$ref": "#/components/responses/MethodNotAllowed"
},
"413": {
"$ref": "#/components/responses/PayloadTooLarge"
},
"429": {
"$ref": "#/components/responses/TooManyRequests"
},
"503": {
"$ref": "#/components/responses/Unavailable"
}
}
}
},
"/ads/details.php": {
"get": {
"operationId": "get_ad_details",
"tags": [
"Ads"
],
"summary": "Inspect an ad creative",
"description": "Retrieve one ad of an advertiser you actively track by its internal AdSpendSpy ad ID (internal_ad_id), not its Meta ad ID. Saved lists and favorites do not retain MCP ad access after you remove a tracked brand on the website.",
"security": [
{
"bearerAuth": []
},
{
"apiKeyHeader": []
},
{
"oauth2": [
"account.read"
]
}
],
"parameters": [
{
"name": "ad_id",
"in": "query",
"required": true,
"description": "Internal AdSpendSpy ad ID (internal_ad_id in ad listings); never a Meta ad ID.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
}
}
],
"responses": {
"200": {
"description": "Success.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AdDetailResponse"
},
"example": {
"success": true,
"ad": {
"id": 20012,
"page_id": "116482854782233",
"brand_name": null,
"brand_image": null,
"ad_id": "2233891893758641",
"ad_archive_id": "2233891893758641",
"is_active": 0,
"start_date": "2025-09-11",
"end_date": "2026-02-24",
"days_running": 166,
"on_facebook": 1,
"on_instagram": 1,
"on_messenger": 1,
"on_audience_network": 1,
"media_type": "video",
"thumbnail_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/ad-thumbnails/6aa66db48ef9e0.74784722_1789291956.jpg",
"video_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/ad-videos/6aa66db6966021.47985771_1789291958.mp4",
"headline": "Learn How to Scale Your Business",
"body_text": "We’re hosting a private session at Acquisition.com’s Las Vegas HQ to show entrepreneurs the exact methods we use to scale businesses.\n\nWant to be in the room?\n\nClick below to see if you’re a fit.\nAdvantage+ creative text generation",
"transcript": "So, if you're a business owner over a million bucks a year, I'd like to invite you out to come to our headquarters in Vegas to see how we scale using what we call the Value Acceleration Method, which is a compilation of all the stuff that I've done across all the different industries. And if that sounds at all interesting, you can click below and book a call and we'd love to potentially meet you and see you in person.",
"cta_text": "Learn more",
"cta_type": "LEARN_MORE",
"landing_url": "https://www.acquisition.com/workshop-km",
"estimated_spend": "3358.47",
"total_reach": 85647,
"total_impressions": 0,
"first_seen_at": "2026-09-13 09:32:30",
"last_seen_at": "2026-09-19 16:48:08",
"duration": 16,
"estimated_spend_usa": "0.00",
"estimated_spend_eu": "3358.47",
"spend_coverage": "eu_uk",
"spend_model_version": 2,
"estimated_reach_usa": 0,
"internal_ad_id": 20012,
"meta_ad_id": "2233891893758641"
},
"demographics": [
{
"country": "GB",
"age_range": "25-34",
"gender": "male",
"reach": 36331,
"impressions": 0,
"snapshot_at": "2026-09-13 09:32:40"
},
{
"country": "GB",
"age_range": "35-44",
"gender": "male",
"reach": 24638,
"impressions": 0,
"snapshot_at": "2026-09-13 09:32:40"
}
],
"meta": {
"currency": "EUR",
"spend_basis": "latest_cumulative_estimate",
"model_version": 2,
"timeframe": "all",
"timeframe_basis": "last_seen_at",
"period_spend_available": false,
"zero_spend_means": "unknown",
"demographics_basis": "latest_snapshot"
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"402": {
"$ref": "#/components/responses/PaymentRequired"
},
"403": {
"$ref": "#/components/responses/Forbidden"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"405": {
"$ref": "#/components/responses/MethodNotAllowed"
},
"429": {
"$ref": "#/components/responses/TooManyRequests"
},
"503": {
"$ref": "#/components/responses/Unavailable"
}
}
}
},
"/ads/list.php": {
"get": {
"operationId": "list_brand_ads",
"tags": [
"Ads"
],
"summary": "List advertiser ads",
"description": "List creative summaries for one tracked advertiser, newest internal ID first, or with sort spend highest latest cumulative estimated spend first (use it for an advertiser's top ads). pagination.next_cursor returns the next page. Each ad carries internal_ad_id (AdSpendSpy ID) and meta_ad_id (the ad on Meta).",
"security": [
{
"bearerAuth": []
},
{
"apiKeyHeader": []
},
{
"oauth2": [
"account.read"
]
}
],
"parameters": [
{
"name": "page_id",
"in": "query",
"required": true,
"description": "Meta advertiser page ID, kept as a string.",
"schema": {
"type": "string",
"pattern": "^[0-9]{5,25}$"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 25
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination.next_cursor returned by the previous page with the same filters.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 512
# --- truncated at 32 KB (207 KB total) ---
# Full source: https://artifacts.apis.io/adspendspy/openapi/_original/adspendspy-api-openapi.json