{
    "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
                        }
                    },
                    {
                        "name": "media_type",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "all",
                                "image",
                                "video"
                            ],
                            "default": "all"
                        }
                    },
                    {
                        "name": "active_only",
                        "in": "query",
                        "required": false,
                        "description": "In the query string send 1 or true (true), 0 or false (false); other values return 400.",
                        "schema": {
                            "type": "boolean",
                            "default": false
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "description": "newest = newest internal ID first; spend = highest estimated spend first.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "newest",
                                "spend"
                            ],
                            "default": "newest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AdListResponse"
                                },
                                "example": {
                                    "success": true,
                                    "ads": [
                                        {
                                            "id": 20013,
                                            "page_id": "116482854782233",
                                            "ad_id": "806878632423038",
                                            "ad_archive_id": "806878632423038",
                                            "headline": "Learn How to Scale Your Business",
                                            "body_text": "We’re hosting a workshop 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.",
                                            "media_type": "video",
                                            "thumbnail_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/ad-thumbnails/6aa66dc47c2276.33202718_1789291972.jpg",
                                            "video_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/ad-videos/6aa66dc6000295.13536020_1789291974.mp4",
                                            "landing_url": "https://www.acquisition.com/workshop-km",
                                            "is_active": 0,
                                            "estimated_spend": "1977.36",
                                            "estimated_spend_eu": "1977.36",
                                            "estimated_spend_usa": "0.00",
                                            "spend_coverage": "eu_uk",
                                            "spend_model_version": 2,
                                            "total_reach": 50760,
                                            "total_impressions": 0,
                                            "first_seen_at": "2026-09-13 09:32:44",
                                            "last_seen_at": "2026-09-19 16:48:08",
                                            "internal_ad_id": 20013,
                                            "meta_ad_id": "806878632423038"
                                        },
                                        {
                                            "id": 20012,
                                            "page_id": "116482854782233",
                                            "ad_id": "2233891893758641",
                                            "ad_archive_id": "2233891893758641",
                                            "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",
                                            "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",
                                            "landing_url": "https://www.acquisition.com/workshop-km",
                                            "is_active": 0,
                                            "estimated_spend": "3358.47",
                                            "estimated_spend_eu": "3358.47",
                                            "estimated_spend_usa": "0.00",
                                            "spend_coverage": "eu_uk",
                                            "spend_model_version": 2,
                                            "total_reach": 85647,
                                            "total_impressions": 0,
                                            "first_seen_at": "2026-09-13 09:32:30",
                                            "last_seen_at": "2026-09-19 16:48:08",
                                            "internal_ad_id": 20012,
                                            "meta_ad_id": "2233891893758641"
                                        }
                                    ],
                                    "pagination": {
                                        "next_cursor": "eyJpZCI6MjAwMTIsInNjb3BlIjoiNmFhODhiODM4MTVkNjQ0YjIzMjgxNWQyMDQ5NDJmZmI2Zjg0NGI3NGU3Y2NiMTQ0MmE5YjQ2ODIwNzQ4MjUyMCJ9",
                                        "has_more": true,
                                        "total": 32
                                    },
                                    "summary": {
                                        "estimated_spend": 114661.67,
                                        "currency": "EUR",
                                        "spend_basis": "latest_cumulative_estimate"
                                    },
                                    "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"
                    },
                    "405": {
                        "$ref": "#/components/responses/MethodNotAllowed"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "503": {
                        "$ref": "#/components/responses/Unavailable"
                    }
                }
            }
        },
        "/stats/top-ads.php": {
            "get": {
                "operationId": "get_top_ads_stats",
                "tags": [
                    "Statistics"
                ],
                "summary": "Analyze estimated ad spend",
                "description": "Analyze latest cumulative estimated spend in EUR for your tracked advertisers. page_id is an exact advertiser filter. timeframe filters when ads were last seen, NOT spend accrued during that period. Creative breakdowns sample the top 1,000 ads; response metadata states matched and sampled counts and full-match aggregate spend. Zero can mean unavailable estimates.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page_id",
                        "in": "query",
                        "required": false,
                        "description": "Meta advertiser page ID, kept as a string.",
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9]{5,25}$"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 500
                        }
                    },
                    {
                        "name": "media_type",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "all",
                                "image",
                                "video"
                            ],
                            "default": "all"
                        }
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 100
                        }
                    },
                    {
                        "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
                        }
                    },
                    {
                        "name": "timeframe",
                        "in": "query",
                        "required": false,
                        "description": "Last-seen window; never a period-spend calculation.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "all",
                                "7d",
                                "30d",
                                "90d"
                            ],
                            "default": "30d"
                        }
                    },
                    {
                        "name": "active_only",
                        "in": "query",
                        "required": false,
                        "description": "In the query string send 1 or true (true), 0 or false (false); other values return 400.",
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "boolean"
                                },
                                {
                                    "type": "string",
                                    "enum": [
                                        "0",
                                        "1",
                                        "true",
                                        "false"
                                    ]
                                }
                            ],
                            "default": false
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/TopAdsResponse"
                                },
                                "example": {
                                    "success": true,
                                    "data": {
                                        "totalSpend": 195513.69,
                                        "adCount": 708,
                                        "mediaTypeStats": [
                                            {
                                                "media_type": "video",
                                                "count": 343,
                                                "total_spend": "100320.48"
                                            },
                                            {
                                                "media_type": "image",
                                                "count": 333,
                                                "total_spend": "91693.36"
                                            }
                                        ],
                                        "durationStats": [
                                            {
                                                "duration_range": "5s",
                                                "duration": 5,
                                                "count": 1,
                                                "total_spend": 996.7
                                            },
                                            {
                                                "duration_range": "14s",
                                                "duration": 14,
                                                "count": 1,
                                                "total_spend": 0
                                            }
                                        ],
                                        "maxDurationSpend": 16237.32,
                                        "genderStats": [
                                            {
                                                "gender": "male",
                                                "ad_count": 146,
                                                "total_reach": 4527485,
                                                "total_spend": 145102.8529067771
                                            },
                                            {
                                                "gender": "female",
                                                "ad_count": 146,
                                                "total_reach": 1514603,
                                                "total_spend": 48542.00871370381
                                            }
                                        ],
                                        "ageStats": [
                                            {
                                                "age_range": "25-34",
                                                "ad_count": 146,
                                                "total_reach": 2051453,
                                                "total_spend": 65747.69058410278
                                            },
                                            {
                                                "age_range": "35-44",
                                                "ad_count": 146,
                                                "total_reach": 1233208,
                                                "total_spend": 39523.48799111665
                                            }
                                        ],
                                        "ctaStats": [
                                            {
                                                "cta_text": "Sign up",
                                                "count": 99,
                                                "total_spend": "141141.99"
                                            },
                                            {
                                                "cta_text": "Learn more",
                                                "count": 324,
                                                "total_spend": "53697.31"
                                            }
                                        ],
                                        "hooksStats": [
                                            {
                                                "hook_text": "You're doing $1M+ a year",
                                                "hook_type": "text",
                                                "ad_count": 29,
                                                "total_spend": "53945.42"
                                            },
                                            {
                                                "hook_text": "We just opened Vantage",
                                                "hook_type": "text",
                                                "ad_count": 31,
                                                "total_spend": "44510.02"
                                            }
                                        ],
                                        "headlineStats": [
                                            {
                                                "headline": "A Private Network for Verified $1M+ Founders",
                                                "count": 35,
                                                "total_spend": "76169.16"
                                            },
                                            {
                                                "headline": "Join Vantage as a Founding Member",
                                                "count": 57,
                                                "total_spend": "69019.99"
                                            }
                                        ],
                                        "matchedAdCount": 708,
                                        "matchedTotalSpend": 195513.69
                                    },
                                    "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",
                                        "sample_limit": 1000,
                                        "sampled": false,
                                        "aggregate_scope": "all_matching_public_advertiser_ads"
                                    }
                                }
                            }
                        }
                    },
                    "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"
                    }
                }
            }
        },
        "/stats/top-landingpages.php": {
            "get": {
                "operationId": "get_top_landingpages_stats",
                "tags": [
                    "Statistics"
                ],
                "summary": "Rank landing pages by estimated spend",
                "description": "Rank the landing pages of your tracked advertisers by latest cumulative estimated spend in EUR. Ads are grouped by landing URL with ad, advertiser and active-ad counts, the top-spending advertiser and, when one is stored, a screenshot as screenshot_url (site path) and screenshot_full_url (absolute URL). page_id is an exact advertiser filter; q matches part of the landing URL. timeframe filters when ads were last seen, NOT spend accrued during that period. Zero can mean unavailable estimates.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page_id",
                        "in": "query",
                        "required": false,
                        "description": "Meta advertiser page ID, kept as a string.",
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9]{5,25}$"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Substring of the landing URL.",
                        "schema": {
                            "type": "string",
                            "maxLength": 500
                        }
                    },
                    {
                        "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
                        }
                    },
                    {
                        "name": "timeframe",
                        "in": "query",
                        "required": false,
                        "description": "Last-seen window; never a period-spend calculation.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "all",
                                "7d",
                                "30d",
                                "90d"
                            ],
                            "default": "30d"
                        }
                    },
                    {
                        "name": "active_only",
                        "in": "query",
                        "required": false,
                        "description": "In the query string send 1 or true (true), 0 or false (false); other values return 400.",
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "boolean"
                                },
                                {
                                    "type": "string",
                                    "enum": [
                                        "0",
                                        "1",
                                        "true",
                                        "false"
                                    ]
                                }
                            ],
                            "default": false
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 60
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/TopLandingpagesResponse"
                                },
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "landing_url": "https://www.skool.com/acq",
                                            "total_spend": 67050.86,
                                            "ads_count": 24,
                                            "brands_count": 1,
                                            "active_ads_count": 0,
                                            "max_days_running": 22,
                                            "last_seen_at": "2026-09-19 16:48:08",
                                            "brand": {
                                                "page_id": "116482854782233",
                                                "brand_name": "Alex Hormozi",
                                                "brand_image": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg"
                                            },
                                            "screenshot_url": null,
                                            "screenshot_full_url": null
                                        },
                                        {
                                            "landing_url": "https://www.acquisition.com/workshop-km",
                                            "total_spend": 35564.45,
                                            "ads_count": 40,
                                            "brands_count": 1,
                                            "active_ads_count": 15,
                                            "max_days_running": 172,
                                            "last_seen_at": "2026-09-19 16:48:08",
                                            "brand": {
                                                "page_id": "116482854782233",
                                                "brand_name": "Alex Hormozi",
                                                "brand_image": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg"
                                            },
                                            "screenshot_url": null,
                                            "screenshot_full_url": null
                                        }
                                    ],
                                    "count": 2,
                                    "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"
                    },
                    "405": {
                        "$ref": "#/components/responses/MethodNotAllowed"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "503": {
                        "$ref": "#/components/responses/Unavailable"
                    }
                }
            }
        },
        "/lists/get.php": {
            "get": {
                "operationId": "get_ad_lists",
                "tags": [
                    "Lists"
                ],
                "summary": "Read saved ad lists",
                "description": "Read your saved lists, with ad creatives limited to advertisers you actively track. list_id selects one owned list; ad_id reports which of your lists contain that internal ad ID and takes precedence when both are supplied. Saving an ad does not bypass tracking limits.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 9007199254740991
                        }
                    },
                    {
                        "name": "ad_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 9007199254740991
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ListsResponse"
                                },
                                "example": {
                                    "success": true,
                                    "lists": [
                                        {
                                            "id": 412,
                                            "list_name": "Hormozi workshop ads",
                                            "description": "Video ads that invite founders to the Las Vegas workshop",
                                            "created_at": "2026-09-20 10:15:00",
                                            "updated_at": "2026-10-02 08:41:12",
                                            "ad_count": 2
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "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"
                    }
                }
            }
        },
        "/projects/get.php": {
            "get": {
                "operationId": "get_projects",
                "tags": [
                    "Projects"
                ],
                "summary": "Read advertiser projects",
                "description": "Read your projects. public_id selects one owned project; brand_id selects memberships for an actively tracked internal brand record and takes precedence when both are supplied.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 9007199254740991
                        }
                    },
                    {
                        "name": "public_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ProjectsResponse"
                                },
                                "example": {
                                    "success": true,
                                    "projects": [
                                        {
                                            "public_id": "k3x9q2mfa7td",
                                            "project_name": "Coaching advertisers",
                                            "description": "Info-product advertisers we follow",
                                            "color": "#1877F2",
                                            "created_at": "2026-09-20 10:12:44",
                                            "updated_at": "2026-10-02 08:40:03",
                                            "brand_count": 1
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "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"
                    }
                }
            }
        },
        "/alerts/count.php": {
            "get": {
                "operationId": "get_pending_alert_count",
                "tags": [
                    "Alerts"
                ],
                "summary": "Count pending alerts",
                "description": "Read the number of pending alerts for your account.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AlertCountResponse"
                                },
                                "example": {
                                    "success": true,
                                    "count": 3
                                }
                            }
                        }
                    },
                    "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"
                    }
                }
            }
        },
        "/ads/new.php": {
            "get": {
                "operationId": "list_new_ads",
                "tags": [
                    "Ads"
                ],
                "summary": "List new ads of tracked brands",
                "description": "List ads that newly appeared for advertisers you actively track, newest first (event ad.new). An ad counts as new when it started at most 7 days before it was first seen, so the back catalog of a freshly tracked advertiser is excluded. Without since_id or cursor the last 30 days are returned. since_id returns only items with a higher internal_ad_id. Spend is a latest cumulative estimate in EUR; null means unknown. Use page_id or project, not both.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "since_id",
                        "in": "query",
                        "required": false,
                        "description": "Return only items with a higher id (internal_ad_id for new ads, alert_id for alerts).",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 9007199254740991
                        }
                    },
                    {
                        "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": 1024
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        }
                    },
                    {
                        "name": "page_id",
                        "in": "query",
                        "required": false,
                        "description": "Meta advertiser page ID, kept as a string.",
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9]{5,25}$"
                        }
                    },
                    {
                        "name": "project",
                        "in": "query",
                        "required": false,
                        "description": "Public_id of one of your projects. Cannot be combined with page_id.",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/IntegrationItemListResponse"
                                },
                                "example": {
                                    "success": true,
                                    "items": [
                                        {
                                            "id": "ad.new:48211",
                                            "event": "ad.new",
                                            "occurred_at": "2026-10-20T09:12:40+00:00",
                                            "currency": "EUR",
                                            "spend_is_estimate": true,
                                            "brand": {
                                                "page_id": "116482854782233",
                                                "name": "Alex Hormozi",
                                                "image_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg",
                                                "url": "https://www.adspendspy.com/brand/116482854782233?utm_source=adspendspy_api&utm_medium=integration"
                                            },
                                            "ad": {
                                                "internal_ad_id": 48211,
                                                "meta_ad_id": "2233891893758641",
                                                "ad_archive_id": "2233891893758641",
                                                "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.",
                                                "cta_text": "Learn more",
                                                "landing_url": "https://www.acquisition.com/workshop-km",
                                                "media_type": "video",
                                                "thumbnail_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/ad-thumbnails/6aa66db48ef9e0.74784722_1789291956.jpg",
                                                "video_url": null,
                                                "platforms": [
                                                    "facebook",
                                                    "instagram"
                                                ],
                                                "start_date": "2026-10-19",
                                                "is_active": true,
                                                "estimated_spend_eur": null,
                                                "spend_coverage": "none",
                                                "url": "https://www.adspendspy.com/ad/48211?utm_source=adspendspy_api&utm_medium=integration"
                                            },
                                            "alert": null
                                        }
                                    ],
                                    "pagination": {
                                        "next_cursor": "eyJpZCI6NDgyMTF9",
                                        "has_more": true
                                    },
                                    "meta": {
                                        "currency": "EUR",
                                        "spend_basis": "latest_cumulative_estimate",
                                        "spend_is_estimate": true
                                    }
                                }
                            }
                        }
                    },
                    "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"
                    }
                }
            }
        },
        "/alerts/list.php": {
            "get": {
                "operationId": "list_alerts",
                "tags": [
                    "Alerts"
                ],
                "summary": "List spend alerts",
                "description": "List spend alerts for ads of advertisers you actively track, newest first (event ad.spend_alert). Each item carries the alert threshold and the estimated spend when the alert was created. Without since_id or cursor the last 30 days are returned. since_id returns only items with a higher alert_id. Spend is a latest cumulative estimate in EUR; null means unknown. Reading alerts does not mark them as sent. Use page_id or project, not both.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "since_id",
                        "in": "query",
                        "required": false,
                        "description": "Return only items with a higher id (internal_ad_id for new ads, alert_id for alerts).",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 9007199254740991
                        }
                    },
                    {
                        "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": 1024
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        }
                    },
                    {
                        "name": "page_id",
                        "in": "query",
                        "required": false,
                        "description": "Meta advertiser page ID, kept as a string.",
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9]{5,25}$"
                        }
                    },
                    {
                        "name": "project",
                        "in": "query",
                        "required": false,
                        "description": "Public_id of one of your projects. Cannot be combined with page_id.",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/IntegrationItemListResponse"
                                },
                                "example": {
                                    "success": true,
                                    "items": [
                                        {
                                            "id": "ad.spend_alert:991",
                                            "event": "ad.spend_alert",
                                            "occurred_at": "2026-10-22T07:41:12+00:00",
                                            "currency": "EUR",
                                            "spend_is_estimate": true,
                                            "brand": {
                                                "page_id": "116482854782233",
                                                "name": "Alex Hormozi",
                                                "image_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg",
                                                "url": "https://www.adspendspy.com/brand/116482854782233?utm_source=adspendspy_api&utm_medium=integration"
                                            },
                                            "ad": {
                                                "internal_ad_id": 48211,
                                                "meta_ad_id": "2233891893758641",
                                                "ad_archive_id": "2233891893758641",
                                                "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.",
                                                "cta_text": "Learn more",
                                                "landing_url": "https://www.acquisition.com/workshop-km",
                                                "media_type": "video",
                                                "thumbnail_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/ad-thumbnails/6aa66db48ef9e0.74784722_1789291956.jpg",
                                                "video_url": null,
                                                "platforms": [
                                                    "facebook",
                                                    "instagram"
                                                ],
                                                "start_date": "2026-10-19",
                                                "is_active": true,
                                                "estimated_spend_eur": 1840.5,
                                                "spend_coverage": "eu_uk",
                                                "url": "https://www.adspendspy.com/ad/48211?utm_source=adspendspy_api&utm_medium=integration"
                                            },
                                            "alert": {
                                                "alert_id": 991,
                                                "threshold_eur": 500,
                                                "spend_at_alert_eur": 812.4
                                            }
                                        }
                                    ],
                                    "pagination": {
                                        "next_cursor": null,
                                        "has_more": false
                                    },
                                    "meta": {
                                        "currency": "EUR",
                                        "spend_basis": "latest_cumulative_estimate",
                                        "spend_is_estimate": true
                                    }
                                }
                            }
                        }
                    },
                    "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"
                    }
                }
            }
        },
        "/webhooks/subscribe.php": {
            "post": {
                "operationId": "subscribe_webhook",
                "tags": [
                    "Webhooks"
                ],
                "summary": "Subscribe a webhook",
                "description": "Register an https URL that receives one signed POST per event (ad.new or ad.spend_alert, see callbacks). Deliveries start at subscription time; no backlog is sent. An older active webhook with the same event, target_url and filters is replaced. The secret for verifying signatures is returned only in this response. At most 25 active webhooks and 120 webhook-management calls per hour per account.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "event": {
                                        "type": "string",
                                        "enum": [
                                            "ad.new",
                                            "ad.spend_alert"
                                        ],
                                        "description": "Event to deliver."
                                    },
                                    "target_url": {
                                        "type": "string",
                                        "maxLength": 2048,
                                        "description": "https URL on port 443 or 8443, without user or password; every resolved address must be public."
                                    },
                                    "platform": {
                                        "type": "string",
                                        "enum": [
                                            "zapier",
                                            "make",
                                            "n8n",
                                            "custom"
                                        ],
                                        "default": "custom",
                                        "description": "Platform that receives the deliveries."
                                    },
                                    "page_id": {
                                        "type": "string",
                                        "nullable": true,
                                        "description": "Only ads of this tracked advertiser (numeric page ID string). Cannot be combined with the other filter; null or omitted = no filter."
                                    },
                                    "project": {
                                        "type": "string",
                                        "nullable": true,
                                        "description": "Only advertisers in this project (public_id). Cannot be combined with the other filter; null or omitted = no filter."
                                    }
                                },
                                "required": [
                                    "event",
                                    "target_url"
                                ]
                            },
                            "example": {
                                "event": "ad.new",
                                "target_url": "https://hooks.zapier.com/hooks/standard/123/abc",
                                "platform": "zapier",
                                "page_id": "116482854782233",
                                "project": null
                            }
                        }
                    },
                    "description": "Other keys are ignored. Browser-session callers also send csrf_token. At most 8 KB."
                },
                "callbacks": {
                    "ad.new": {
                        "{$request.body#/target_url}": {
                            "post": {
                                "operationId": "deliver_ad_new",
                                "summary": "Delivery of ad.new",
                                "description": "One POST per event, body = one IntegrationItem, User-Agent AdSpendSpy-Webhooks/1.0. Verify: hex HMAC-SHA256 with the webhook secret over \"<X-AdSpendSpy-Timestamp>.<raw body>\" must equal the value after v1= (constant-time compare); reject timestamps older than 5 minutes. Test vector: secret whsec_test, timestamp 1700000000, body {\"id\":\"ad.new:1\"} gives v1=98ab6f15d65efe0ec4dbf9f25fdeeeef42a5651d8bd1bd10f3b3609b436a6474. Redirects are not followed. Other answers are retried after 1, 5, 30, 120 and 720 minutes. No ordering guarantee: use occurred_at.",
                                "security": [],
                                "parameters": [
                                    {
                                        "name": "X-AdSpendSpy-Event",
                                        "in": "header",
                                        "required": true,
                                        "description": "Event type.",
                                        "schema": {
                                            "type": "string",
                                            "enum": [
                                                "ad.new"
                                            ]
                                        }
                                    },
                                    {
                                        "name": "X-AdSpendSpy-Webhook",
                                        "in": "header",
                                        "required": true,
                                        "description": "Webhook id (whk_…).",
                                        "schema": {
                                            "type": "string",
                                            "pattern": "^whk_[a-f0-9]{8,48}$"
                                        }
                                    },
                                    {
                                        "name": "X-AdSpendSpy-Delivery",
                                        "in": "header",
                                        "required": true,
                                        "description": "Delivery id; the same for every retry of this delivery.",
                                        "schema": {
                                            "type": "string"
                                        }
                                    },
                                    {
                                        "name": "X-AdSpendSpy-Timestamp",
                                        "in": "header",
                                        "required": true,
                                        "description": "Unix seconds when the request was signed.",
                                        "schema": {
                                            "type": "integer"
                                        }
                                    },
                                    {
                                        "name": "X-AdSpendSpy-Signature",
                                        "in": "header",
                                        "required": true,
                                        "description": "v1=<hex HMAC-SHA256(secret, \"<timestamp>.<raw body>\")>.",
                                        "schema": {
                                            "type": "string",
                                            "pattern": "^v1=[0-9a-f]{64}$"
                                        }
                                    }
                                ],
                                "requestBody": {
                                    "required": true,
                                    "content": {
                                        "application/json": {
                                            "schema": {
                                                "$ref": "#/components/schemas/IntegrationItem"
                                            },
                                            "example": {
                                                "id": "ad.new:48211",
                                                "event": "ad.new",
                                                "occurred_at": "2026-10-20T09:12:40+00:00",
                                                "currency": "EUR",
                                                "spend_is_estimate": true,
                                                "brand": {
                                                    "page_id": "116482854782233",
                                                    "name": "Alex Hormozi",
                                                    "image_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg",
                                                    "url": "https://www.adspendspy.com/brand/116482854782233?utm_source=adspendspy_api&utm_medium=integration"
                                                },
                                                "ad": {
                                                    "internal_ad_id": 48211,
                                                    "meta_ad_id": "2233891893758641",
                                                    "ad_archive_id": "2233891893758641",
                                                    "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.",
                                                    "cta_text": "Learn more",
                                                    "landing_url": "https://www.acquisition.com/workshop-km",
                                                    "media_type": "video",
                                                    "thumbnail_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/ad-thumbnails/6aa66db48ef9e0.74784722_1789291956.jpg",
                                                    "video_url": null,
                                                    "platforms": [
                                                        "facebook",
                                                        "instagram"
                                                    ],
                                                    "start_date": "2026-10-19",
                                                    "is_active": true,
                                                    "estimated_spend_eur": null,
                                                    "spend_coverage": "none",
                                                    "url": "https://www.adspendspy.com/ad/48211?utm_source=adspendspy_api&utm_medium=integration"
                                                },
                                                "alert": null
                                            }
                                        }
                                    }
                                },
                                "responses": {
                                    "200": {
                                        "description": "Any 2xx answer within 5 seconds counts as delivered."
                                    },
                                    "410": {
                                        "description": "Gone: the webhook is disabled at once."
                                    }
                                }
                            }
                        }
                    },
                    "ad.spend_alert": {
                        "{$request.body#/target_url}": {
                            "post": {
                                "operationId": "deliver_ad_spend_alert",
                                "summary": "Delivery of ad.spend_alert",
                                "description": "One POST per event, body = one IntegrationItem, User-Agent AdSpendSpy-Webhooks/1.0. Verify: hex HMAC-SHA256 with the webhook secret over \"<X-AdSpendSpy-Timestamp>.<raw body>\" must equal the value after v1= (constant-time compare); reject timestamps older than 5 minutes. Test vector: secret whsec_test, timestamp 1700000000, body {\"id\":\"ad.new:1\"} gives v1=98ab6f15d65efe0ec4dbf9f25fdeeeef42a5651d8bd1bd10f3b3609b436a6474. Redirects are not followed. Other answers are retried after 1, 5, 30, 120 and 720 minutes. No ordering guarantee: use occurred_at.",
                                "security": [],
                                "parameters": [
                                    {
                                        "name": "X-AdSpendSpy-Event",
                                        "in": "header",
                                        "required": true,
                                        "description": "Event type.",
                                        "schema": {
                                            "type": "string",
                                            "enum": [
                                                "ad.spend_alert"
                                            ]
                                        }
                                    },
                                    {
                                        "name": "X-AdSpendSpy-Webhook",
                                        "in": "header",
                                        "required": true,
                                        "description": "Webhook id (whk_…).",
                                        "schema": {
                                            "type": "string",
                                            "pattern": "^whk_[a-f0-9]{8,48}$"
                                        }
                                    },
                                    {
                                        "name": "X-AdSpendSpy-Delivery",
                                        "in": "header",
                                        "required": true,
                                        "description": "Delivery id; the same for every retry of this delivery.",
                                        "schema": {
                                            "type": "string"
                                        }
                                    },
                                    {
                                        "name": "X-AdSpendSpy-Timestamp",
                                        "in": "header",
                                        "required": true,
                                        "description": "Unix seconds when the request was signed.",
                                        "schema": {
                                            "type": "integer"
                                        }
                                    },
                                    {
                                        "name": "X-AdSpendSpy-Signature",
                                        "in": "header",
                                        "required": true,
                                        "description": "v1=<hex HMAC-SHA256(secret, \"<timestamp>.<raw body>\")>.",
                                        "schema": {
                                            "type": "string",
                                            "pattern": "^v1=[0-9a-f]{64}$"
                                        }
                                    }
                                ],
                                "requestBody": {
                                    "required": true,
                                    "content": {
                                        "application/json": {
                                            "schema": {
                                                "$ref": "#/components/schemas/IntegrationItem"
                                            },
                                            "example": {
                                                "id": "ad.spend_alert:991",
                                                "event": "ad.spend_alert",
                                                "occurred_at": "2026-10-22T07:41:12+00:00",
                                                "currency": "EUR",
                                                "spend_is_estimate": true,
                                                "brand": {
                                                    "page_id": "116482854782233",
                                                    "name": "Alex Hormozi",
                                                    "image_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/brand-images/6aa53d54cf8640.38028505_1789214036.jpg",
                                                    "url": "https://www.adspendspy.com/brand/116482854782233?utm_source=adspendspy_api&utm_medium=integration"
                                                },
                                                "ad": {
                                                    "internal_ad_id": 48211,
                                                    "meta_ad_id": "2233891893758641",
                                                    "ad_archive_id": "2233891893758641",
                                                    "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.",
                                                    "cta_text": "Learn more",
                                                    "landing_url": "https://www.acquisition.com/workshop-km",
                                                    "media_type": "video",
                                                    "thumbnail_url": "https://pub-9386975130c84779921f8ea9548c431c.r2.dev/ad-thumbnails/6aa66db48ef9e0.74784722_1789291956.jpg",
                                                    "video_url": null,
                                                    "platforms": [
                                                        "facebook",
                                                        "instagram"
                                                    ],
                                                    "start_date": "2026-10-19",
                                                    "is_active": true,
                                                    "estimated_spend_eur": 1840.5,
                                                    "spend_coverage": "eu_uk",
                                                    "url": "https://www.adspendspy.com/ad/48211?utm_source=adspendspy_api&utm_medium=integration"
                                                },
                                                "alert": {
                                                    "alert_id": 991,
                                                    "threshold_eur": 500,
                                                    "spend_at_alert_eur": 812.4
                                                }
                                            }
                                        }
                                    }
                                },
                                "responses": {
                                    "200": {
                                        "description": "Any 2xx answer within 5 seconds counts as delivered."
                                    },
                                    "410": {
                                        "description": "Gone: the webhook is disabled at once."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Webhook created. Store the secret now; it is never shown again.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WebhookCreated"
                                },
                                "example": {
                                    "success": true,
                                    "webhook": {
                                        "id": "whk_3f9a1c2d4b5e6f708192a3b4",
                                        "event": "ad.new",
                                        "target_url": "https://hooks.zapier.com/hooks/standard/123/abc",
                                        "platform": "zapier",
                                        "filters": {
                                            "page_id": "116482854782233",
                                            "project": null
                                        },
                                        "created_at": "2026-10-22T07:41:12+00:00"
                                    },
                                    "secret": "whsec_5b1e9f0a7c3d2e1f4a6b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f708192a3b"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid body. Codes: invalid_json, invalid_event, invalid_target_url, target_not_allowed, invalid_platform, filter_conflict, invalid_page_id.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "invalid_target_url",
                                    "message": "target_url must be an https URL on port 443 or 8443, without user or password."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "402": {
                        "$ref": "#/components/responses/PaymentRequired"
                    },
                    "403": {
                        "description": "The credential may not call this endpoint (mobile app tokens never can), the OAuth token lacks account.read, or a browser-session call has no valid csrf_token (code csrf_failed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "forbidden",
                                    "message": "Webhooks are not available to the mobile app."
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "The page_id or project filter is not in your account. Codes: brand_not_tracked, project_not_found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "brand_not_tracked",
                                    "message": "You do not track this brand."
                                }
                            }
                        }
                    },
                    "405": {
                        "$ref": "#/components/responses/MethodNotAllowed"
                    },
                    "409": {
                        "description": "25 active webhooks already exist (code webhook_limit_reached). Remove one first.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "webhook_limit_reached",
                                    "message": "You can have at most 25 active webhooks. Remove one first."
                                }
                            }
                        }
                    },
                    "413": {
                        "description": "The JSON body exceeds 8 KB.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "payload_too_large",
                                    "message": "The request body must be at most 8 KB."
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/WebhookTooManyRequests"
                    },
                    "503": {
                        "$ref": "#/components/responses/WebhookUnavailable"
                    }
                }
            }
        },
        "/webhooks/unsubscribe.php": {
            "post": {
                "operationId": "unsubscribe_webhook",
                "tags": [
                    "Webhooks"
                ],
                "summary": "Unsubscribe a webhook",
                "description": "Disable one of your webhooks. Idempotent: an already disabled webhook of yours also answers 200 with its original disabled_at.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "string",
                                        "pattern": "^whk_[a-f0-9]{8,48}$",
                                        "description": "Webhook id from subscribe_webhook or list_webhooks."
                                    }
                                },
                                "required": [
                                    "id"
                                ]
                            },
                            "example": {
                                "id": "whk_3f9a1c2d4b5e6f708192a3b4"
                            }
                        }
                    },
                    "description": "Other keys are ignored. Browser-session callers also send csrf_token. At most 8 KB."
                },
                "responses": {
                    "200": {
                        "description": "Webhook disabled (also when it was already disabled).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WebhookUnsubscribed"
                                },
                                "example": {
                                    "success": true,
                                    "webhook": {
                                        "id": "whk_3f9a1c2d4b5e6f708192a3b4",
                                        "disabled_at": "2026-10-22T08:00:00+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "The body is not a JSON object (code invalid_json).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "invalid_json",
                                    "message": "Send a JSON object."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "402": {
                        "$ref": "#/components/responses/PaymentRequired"
                    },
                    "403": {
                        "description": "The credential may not call this endpoint (mobile app tokens never can), the OAuth token lacks account.read, or a browser-session call has no valid csrf_token (code csrf_failed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "forbidden",
                                    "message": "Webhooks are not available to the mobile app."
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown webhook id, or it belongs to another account (code webhook_not_found).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "webhook_not_found",
                                    "message": "Webhook not found."
                                }
                            }
                        }
                    },
                    "405": {
                        "$ref": "#/components/responses/MethodNotAllowed"
                    },
                    "413": {
                        "description": "The JSON body exceeds 8 KB.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "payload_too_large",
                                    "message": "The request body must be at most 8 KB."
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/WebhookTooManyRequests"
                    },
                    "503": {
                        "$ref": "#/components/responses/WebhookUnavailable"
                    }
                }
            }
        },
        "/webhooks/list.php": {
            "get": {
                "operationId": "list_webhooks",
                "tags": [
                    "Webhooks"
                ],
                "summary": "List webhooks",
                "description": "List your active webhooks with the status of the latest delivery. The secret is never returned.",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "apiKeyHeader": []
                    },
                    {
                        "oauth2": [
                            "account.read"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WebhookListResponse"
                                },
                                "example": {
                                    "success": true,
                                    "webhooks": [
                                        {
                                            "id": "whk_3f9a1c2d4b5e6f708192a3b4",
                                            "event": "ad.new",
                                            "target_url": "https://hooks.zapier.com/hooks/standard/123/abc",
                                            "platform": "zapier",
                                            "filters": {
                                                "page_id": "116482854782233",
                                                "project": null
                                            },
                                            "created_at": "2026-10-22T07:41:12+00:00",
                                            "last_delivery_at": "2026-10-22T07:45:03+00:00",
                                            "last_success_at": "2026-10-22T07:45:03+00:00",
                                            "last_status": "sent"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "402": {
                        "$ref": "#/components/responses/PaymentRequired"
                    },
                    "403": {
                        "description": "The credential may not call this endpoint (mobile app tokens never can), the OAuth token lacks account.read, or a browser-session call has no valid csrf_token (code csrf_failed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "success": false,
                                    "code": "forbidden",
                                    "message": "Webhooks are not available to the mobile app."
                                }
                            }
                        }
                    },
                    "405": {
                        "$ref": "#/components/responses/MethodNotAllowed"
                    },
                    "429": {
                        "$ref": "#/components/responses/WebhookTooManyRequests"
                    },
                    "503": {
                        "$ref": "#/components/responses/WebhookUnavailable"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "asp_live_ API key",
                "description": "Authorization: Bearer asp_live_… with a personal API key from Account Settings."
            },
            "apiKeyHeader": {
                "type": "apiKey",
                "in": "header",
                "name": "X-API-Key",
                "description": "The same personal API key in the X-API-Key header."
            },
            "oauth2": {
                "type": "oauth2",
                "description": "For connected apps (MCP clients); scripts use an API key. Authorization code flow with PKCE S256. Clients register at https://www.adspendspy.com/oauth/register; metadata is at https://www.adspendspy.com/.well-known/oauth-authorization-server.",
                "flows": {
                    "authorizationCode": {
                        "authorizationUrl": "https://www.adspendspy.com/oauth/authorize",
                        "tokenUrl": "https://www.adspendspy.com/oauth/token",
                        "refreshUrl": "https://www.adspendspy.com/oauth/token",
                        "scopes": {
                            "account.read": "Read your tracked brands, their ads and spend estimates, your statistics, ad lists, projects and alerts.",
                            "brands.track": "Start tracking new brands in your account (uses your normal brand slots)."
                        }
                    }
                }
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "required": [
                    "success",
                    "message"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            false
                        ]
                    },
                    "message": {
                        "type": "string",
                        "description": "Human-readable reason. brands/track.php and the 402 membership answer localize it via X-App-Language."
                    },
                    "code": {
                        "type": "string",
                        "description": "Machine-readable error code of the webhooks/* endpoints, for example invalid_target_url or webhook_not_found."
                    },
                    "message_key": {
                        "type": "string",
                        "description": "Stable catalog key of the message (brands/track.php)."
                    },
                    "message_params": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "string"
                        }
                    },
                    "reason": {
                        "type": "string",
                        "description": "Machine-readable reason, for example membership_required."
                    },
                    "redirect_url": {
                        "type": "string",
                        "description": "Recovery page on the AdSpendSpy website (402)."
                    },
                    "limit_reached": {
                        "type": "boolean",
                        "description": "brands/track.php 403: the tracked-brand limit is reached."
                    },
                    "tracked_count": {
                        "type": "integer",
                        "description": "brands/track.php 403: actively tracked brands."
                    },
                    "tracked_limit": {
                        "type": "integer",
                        "description": "brands/track.php 403: the account limit."
                    },
                    "remaining_slots": {
                        "type": "integer",
                        "description": "brands/track.php 403: always 0."
                    }
                }
            },
            "SpendMeta": {
                "type": "object",
                "description": "How to read the spend figures in this response.",
                "required": [
                    "currency",
                    "spend_basis",
                    "model_version",
                    "timeframe",
                    "timeframe_basis",
                    "period_spend_available",
                    "zero_spend_means",
                    "demographics_basis"
                ],
                "properties": {
                    "currency": {
                        "type": "string",
                        "enum": [
                            "EUR"
                        ]
                    },
                    "spend_basis": {
                        "type": "string",
                        "enum": [
                            "latest_cumulative_estimate"
                        ]
                    },
                    "model_version": {
                        "type": "integer"
                    },
                    "timeframe": {
                        "type": "string",
                        "enum": [
                            "all",
                            "7d",
                            "30d",
                            "90d"
                        ],
                        "description": "Last-seen filter that was applied; never a period-spend calculation."
                    },
                    "timeframe_basis": {
                        "type": "string",
                        "enum": [
                            "last_seen_at"
                        ]
                    },
                    "period_spend_available": {
                        "type": "boolean",
                        "enum": [
                            false
                        ]
                    },
                    "zero_spend_means": {
                        "type": "string",
                        "enum": [
                            "unknown"
                        ]
                    },
                    "demographics_basis": {
                        "type": "string",
                        "enum": [
                            "latest_snapshot"
                        ]
                    },
                    "sample_limit": {
                        "type": "integer",
                        "description": "Statistics only: creative breakdowns use at most this many top ads."
                    },
                    "sampled": {
                        "type": "boolean",
                        "description": "Statistics only: true when more ads matched than the sample holds."
                    },
                    "aggregate_scope": {
                        "type": "string",
                        "description": "Statistics only: which ads the matched totals cover."
                    }
                }
            },
            "TrackedBrand": {
                "type": "object",
                "required": [
                    "id",
                    "page_id",
                    "brand_name",
                    "ad_count"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Internal brand record ID."
                    },
                    "page_id": {
                        "type": "string",
                        "pattern": "^[0-9]{5,25}$",
                        "description": "Meta advertiser page ID, kept as a string."
                    },
                    "brand_name": {
                        "type": "string"
                    },
                    "brand_image": {
                        "type": "string",
                        "nullable": true
                    },
                    "category": {
                        "type": "string",
                        "nullable": true
                    },
                    "likes": {
                        "type": "integer",
                        "nullable": true
                    },
                    "verification": {
                        "type": "string",
                        "nullable": true
                    },
                    "ig_username": {
                        "type": "string",
                        "nullable": true
                    },
                    "ig_followers": {
                        "type": "integer",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    },
                    "ad_count": {
                        "type": "integer",
                        "description": "Stored ads of this advertiser."
                    }
                }
            },
            "BrandSearchResult": {
                "type": "object",
                "required": [
                    "id",
                    "page_id",
                    "display_name",
                    "ad_count",
                    "status"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Internal brand record ID."
                    },
                    "page_id": {
                        "type": "string",
                        "pattern": "^[0-9]{5,25}$",
                        "description": "Meta advertiser page ID, kept as a string."
                    },
                    "brand_name": {
                        "type": "string"
                    },
                    "brand_image": {
                        "type": "string",
                        "nullable": true
                    },
                    "ad_brand_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "ad_brand_image": {
                        "type": "string",
                        "nullable": true
                    },
                    "ad_count": {
                        "type": "integer"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "tracked"
                        ]
                    },
                    "display_name": {
                        "type": "string"
                    },
                    "display_image": {
                        "type": "string",
                        "nullable": true
                    }
                }
            },
            "AdSummary": {
                "type": "object",
                "required": [
                    "id",
                    "internal_ad_id",
                    "page_id",
                    "ad_id",
                    "meta_ad_id",
                    "media_type",
                    "estimated_spend",
                    "spend_coverage"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Internal ad ID; same value as internal_ad_id."
                    },
                    "internal_ad_id": {
                        "type": "integer",
                        "description": "Pass this value to ads/details.php as ad_id."
                    },
                    "page_id": {
                        "type": "string",
                        "pattern": "^[0-9]{5,25}$",
                        "description": "Meta advertiser page ID, kept as a string."
                    },
                    "ad_id": {
                        "type": "string",
                        "description": "Meta ad ID; same value as meta_ad_id."
                    },
                    "meta_ad_id": {
                        "type": "string",
                        "description": "Identifies the ad on Meta. Never accepted as ad_id."
                    },
                    "ad_archive_id": {
                        "type": "string",
                        "nullable": true
                    },
                    "headline": {
                        "type": "string",
                        "nullable": true
                    },
                    "body_text": {
                        "type": "string",
                        "nullable": true
                    },
                    "media_type": {
                        "type": "string",
                        "enum": [
                            "image",
                            "video",
                            "carousel",
                            "text"
                        ],
                        "nullable": true
                    },
                    "thumbnail_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "video_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "landing_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "is_active": {
                        "type": "integer",
                        "enum": [
                            0,
                            1
                        ],
                        "nullable": true
                    },
                    "estimated_spend": {
                        "type": "string",
                        "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                        "description": "Latest cumulative estimated spend in EUR. 0 can mean the estimate is unavailable. Decimal string.",
                        "nullable": true
                    },
                    "estimated_spend_eu": {
                        "type": "string",
                        "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                        "description": "EU/UK part of the estimate in EUR. Decimal string.",
                        "nullable": true
                    },
                    "estimated_spend_usa": {
                        "type": "string",
                        "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                        "description": "Extrapolated US part of the estimate in EUR. Decimal string.",
                        "nullable": true
                    },
                    "spend_coverage": {
                        "type": "string",
                        "enum": [
                            "eu_uk",
                            "eu_uk_us",
                            "us_extrapolated",
                            "none"
                        ],
                        "description": "Basis of the estimate: eu_uk is based on reach data that Meta publishes for the EU and UK; us_extrapolated and the US part of eu_uk_us are extrapolated; none means no estimate."
                    },
                    "spend_model_version": {
                        "type": "integer"
                    },
                    "total_reach": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Reach that Meta publishes for the EU and UK."
                    },
                    "total_impressions": {
                        "type": "integer",
                        "nullable": true
                    },
                    "first_seen_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    },
                    "last_seen_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    }
                }
            },
            "AdDetail": {
                "type": "object",
                "description": "The stored ad record. Fields beyond the listed ones may appear.",
                "required": [
                    "id",
                    "internal_ad_id",
                    "page_id",
                    "ad_id",
                    "meta_ad_id",
                    "media_type",
                    "estimated_spend",
                    "spend_coverage"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Internal ad ID; same value as internal_ad_id."
                    },
                    "internal_ad_id": {
                        "type": "integer",
                        "description": "Pass this value to ads/details.php as ad_id."
                    },
                    "page_id": {
                        "type": "string",
                        "pattern": "^[0-9]{5,25}$",
                        "description": "Meta advertiser page ID, kept as a string."
                    },
                    "ad_id": {
                        "type": "string",
                        "description": "Meta ad ID; same value as meta_ad_id."
                    },
                    "meta_ad_id": {
                        "type": "string",
                        "description": "Identifies the ad on Meta. Never accepted as ad_id."
                    },
                    "ad_archive_id": {
                        "type": "string",
                        "nullable": true
                    },
                    "headline": {
                        "type": "string",
                        "nullable": true
                    },
                    "body_text": {
                        "type": "string",
                        "nullable": true
                    },
                    "media_type": {
                        "type": "string",
                        "enum": [
                            "image",
                            "video",
                            "carousel",
                            "text"
                        ],
                        "nullable": true
                    },
                    "thumbnail_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "video_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "landing_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "is_active": {
                        "type": "integer",
                        "enum": [
                            0,
                            1
                        ],
                        "nullable": true
                    },
                    "estimated_spend": {
                        "type": "string",
                        "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                        "description": "Latest cumulative estimated spend in EUR. 0 can mean the estimate is unavailable. Decimal string.",
                        "nullable": true
                    },
                    "estimated_spend_eu": {
                        "type": "string",
                        "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                        "description": "EU/UK part of the estimate in EUR. Decimal string.",
                        "nullable": true
                    },
                    "estimated_spend_usa": {
                        "type": "string",
                        "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                        "description": "Extrapolated US part of the estimate in EUR. Decimal string.",
                        "nullable": true
                    },
                    "spend_coverage": {
                        "type": "string",
                        "enum": [
                            "eu_uk",
                            "eu_uk_us",
                            "us_extrapolated",
                            "none"
                        ],
                        "description": "Basis of the estimate: eu_uk is based on reach data that Meta publishes for the EU and UK; us_extrapolated and the US part of eu_uk_us are extrapolated; none means no estimate."
                    },
                    "spend_model_version": {
                        "type": "integer"
                    },
                    "total_reach": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Reach that Meta publishes for the EU and UK."
                    },
                    "total_impressions": {
                        "type": "integer",
                        "nullable": true
                    },
                    "first_seen_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    },
                    "last_seen_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    },
                    "brand_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "brand_image": {
                        "type": "string",
                        "nullable": true
                    },
                    "start_date": {
                        "type": "string",
                        "nullable": true,
                        "description": "Date, format YYYY-MM-DD."
                    },
                    "end_date": {
                        "type": "string",
                        "nullable": true,
                        "description": "Date, format YYYY-MM-DD."
                    },
                    "days_running": {
                        "type": "integer",
                        "nullable": true
                    },
                    "on_facebook": {
                        "type": "integer",
                        "enum": [
                            0,
                            1
                        ],
                        "nullable": true
                    },
                    "on_instagram": {
                        "type": "integer",
                        "enum": [
                            0,
                            1
                        ],
                        "nullable": true
                    },
                    "on_messenger": {
                        "type": "integer",
                        "enum": [
                            0,
                            1
                        ],
                        "nullable": true
                    },
                    "on_audience_network": {
                        "type": "integer",
                        "enum": [
                            0,
                            1
                        ],
                        "nullable": true
                    },
                    "cta_text": {
                        "type": "string",
                        "nullable": true
                    },
                    "cta_type": {
                        "type": "string",
                        "nullable": true
                    },
                    "duration": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Video length in seconds."
                    },
                    "transcript": {
                        "type": "string",
                        "nullable": true
                    },
                    "estimated_reach_usa": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Estimated US audience behind estimated_spend_usa."
                    }
                }
            },
            "Demographic": {
                "type": "object",
                "required": [
                    "reach"
                ],
                "properties": {
                    "country": {
                        "type": "string",
                        "nullable": true
                    },
                    "age_range": {
                        "type": "string",
                        "nullable": true
                    },
                    "gender": {
                        "type": "string",
                        "nullable": true
                    },
                    "reach": {
                        "type": "integer",
                        "nullable": true
                    },
                    "impressions": {
                        "type": "integer",
                        "nullable": true
                    },
                    "snapshot_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    }
                }
            },
            "LandingPage": {
                "type": "object",
                "required": [
                    "landing_url",
                    "total_spend",
                    "ads_count",
                    "brands_count",
                    "active_ads_count"
                ],
                "properties": {
                    "landing_url": {
                        "type": "string"
                    },
                    "total_spend": {
                        "type": "number",
                        "description": "Summed latest cumulative estimated spend in EUR."
                    },
                    "ads_count": {
                        "type": "integer"
                    },
                    "brands_count": {
                        "type": "integer"
                    },
                    "active_ads_count": {
                        "type": "integer"
                    },
                    "max_days_running": {
                        "type": "integer",
                        "nullable": true
                    },
                    "last_seen_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    },
                    "brand": {
                        "type": "object",
                        "nullable": true,
                        "description": "Top-spending advertiser on this landing page.",
                        "properties": {
                            "page_id": {
                                "type": "string",
                                "pattern": "^[0-9]{5,25}$",
                                "description": "Meta advertiser page ID, kept as a string."
                            },
                            "brand_name": {
                                "type": "string",
                                "nullable": true
                            },
                            "brand_image": {
                                "type": "string",
                                "nullable": true
                            }
                        }
                    },
                    "screenshot_url": {
                        "type": "string",
                        "nullable": true,
                        "description": "Site path of a stored screenshot."
                    },
                    "screenshot_full_url": {
                        "type": "string",
                        "nullable": true,
                        "description": "Absolute URL of the same screenshot."
                    }
                }
            },
            "AdList": {
                "type": "object",
                "required": [
                    "id",
                    "list_name",
                    "ad_count"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "list_name": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "ad_count": {
                        "type": "integer"
                    },
                    "contains_ad": {
                        "type": "boolean",
                        "description": "Only with ad_id: whether this list holds that ad."
                    },
                    "created_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    },
                    "updated_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    }
                }
            },
            "Project": {
                "type": "object",
                "required": [
                    "public_id",
                    "project_name",
                    "brand_count"
                ],
                "properties": {
                    "public_id": {
                        "type": "string"
                    },
                    "project_name": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "color": {
                        "type": "string",
                        "nullable": true
                    },
                    "brand_count": {
                        "type": "integer"
                    },
                    "contains_brand": {
                        "type": "boolean",
                        "description": "Only with brand_id: whether this project holds that brand."
                    },
                    "created_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    },
                    "updated_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Server timestamp, format YYYY-MM-DD HH:MM:SS."
                    },
                    "brands": {
                        "type": "array",
                        "description": "Only with public_id: the actively tracked brands in this project.",
                        "items": {
                            "type": "object",
                            "required": [
                                "id",
                                "page_id",
                                "brand_name"
                            ],
                            "properties": {
                                "id": {
                                    "type": "integer",
                                    "description": "Internal brand record ID."
                                },
                                "page_id": {
                                    "type": "string",
                                    "pattern": "^[0-9]{5,25}$",
                                    "description": "Meta advertiser page ID, kept as a string."
                                },
                                "brand_name": {
                                    "type": "string"
                                },
                                "brand_image": {
                                    "type": "string",
                                    "nullable": true
                                },
                                "category": {
                                    "type": "string",
                                    "nullable": true
                                },
                                "ad_count": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            },
            "BrandListResponse": {
                "type": "object",
                "required": [
                    "success",
                    "data",
                    "count",
                    "total_count"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/TrackedBrand"
                        }
                    },
                    "count": {
                        "type": "integer",
                        "description": "Brands in data (after the project filter)."
                    },
                    "total_count": {
                        "type": "integer",
                        "description": "All actively tracked brands of the account."
                    }
                }
            },
            "BrandSearchResponse": {
                "type": "object",
                "required": [
                    "success",
                    "results",
                    "count"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "results": {
                        "type": "array",
                        "maxItems": 10,
                        "items": {
                            "$ref": "#/components/schemas/BrandSearchResult"
                        }
                    },
                    "count": {
                        "type": "integer"
                    }
                }
            },
            "CheckTrackedResponse": {
                "type": "object",
                "required": [
                    "success",
                    "tracked"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "tracked": {
                        "description": "Map of tracked page_id to internal brand ID. Untracked page IDs are absent. When none is tracked, the API currently returns an empty array ([]) instead of an empty object.",
                        "oneOf": [
                            {
                                "type": "object",
                                "additionalProperties": {
                                    "type": "integer"
                                }
                            },
                            {
                                "type": "array",
                                "maxItems": 0,
                                "items": {
                                    "type": "integer"
                                }
                            }
                        ]
                    }
                }
            },
            "TrackBrandResponse": {
                "type": "object",
                "required": [
                    "success",
                    "message",
                    "message_key",
                    "brand_id",
                    "page_id",
                    "already_tracked",
                    "reactivated",
                    "tracked_count",
                    "tracked_limit",
                    "remaining_slots",
                    "ingestion_state",
                    "ads_count"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "message": {
                        "type": "string",
                        "description": "Localized via X-App-Language."
                    },
                    "message_key": {
                        "type": "string",
                        "enum": [
                            "account_common.api.brands_track.tracked",
                            "account_common.api.brands_track.already_tracked"
                        ]
                    },
                    "message_params": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "string"
                        }
                    },
                    "brand_id": {
                        "type": "integer",
                        "description": "Internal brand record ID."
                    },
                    "page_id": {
                        "type": "string",
                        "pattern": "^[0-9]{5,25}$",
                        "description": "Meta advertiser page ID, kept as a string."
                    },
                    "already_tracked": {
                        "type": "boolean",
                        "description": "true with HTTP 200: the advertiser was already tracked; no slot was used."
                    },
                    "reactivated": {
                        "type": "boolean",
                        "description": "true when an earlier, removed tracking was restored."
                    },
                    "tracked_count": {
                        "type": "integer",
                        "description": "Actively tracked brands, counted before this request."
                    },
                    "tracked_limit": {
                        "type": "integer"
                    },
                    "remaining_slots": {
                        "type": "integer"
                    },
                    "ingestion_state": {
                        "type": "string",
                        "enum": [
                            "ready",
                            "pending",
                            "no_ads"
                        ],
                        "description": "ready: stored ads are available. pending: the first check or current processing is unfinished. no_ads: a completed check found no stored ads."
                    },
                    "ads_count": {
                        "type": "integer"
                    }
                }
            },
            "AdListResponse": {
                "type": "object",
                "required": [
                    "success",
                    "ads",
                    "pagination",
                    "summary",
                    "meta"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "ads": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/AdSummary"
                        }
                    },
                    "pagination": {
                        "type": "object",
                        "required": [
                            "next_cursor",
                            "has_more",
                            "total"
                        ],
                        "properties": {
                            "next_cursor": {
                                "type": "string",
                                "nullable": true,
                                "description": "Send as cursor with the same filters for the next page; null on the last page."
                            },
                            "has_more": {
                                "type": "boolean"
                            },
                            "total": {
                                "type": "integer",
                                "description": "All ads that match the filters."
                            }
                        }
                    },
                    "summary": {
                        "type": "object",
                        "required": [
                            "estimated_spend",
                            "currency",
                            "spend_basis"
                        ],
                        "properties": {
                            "estimated_spend": {
                                "type": "number",
                                "description": "Summed estimate in EUR over all matching ads."
                            },
                            "currency": {
                                "type": "string",
                                "enum": [
                                    "EUR"
                                ]
                            },
                            "spend_basis": {
                                "type": "string",
                                "enum": [
                                    "latest_cumulative_estimate"
                                ]
                            }
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/SpendMeta"
                    }
                }
            },
            "AdDetailResponse": {
                "type": "object",
                "required": [
                    "success",
                    "ad",
                    "demographics",
                    "meta"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "ad": {
                        "$ref": "#/components/schemas/AdDetail"
                    },
                    "demographics": {
                        "type": "array",
                        "description": "Latest demographic snapshot, highest reach first.",
                        "items": {
                            "$ref": "#/components/schemas/Demographic"
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/SpendMeta"
                    }
                }
            },
            "TopAdsResponse": {
                "type": "object",
                "required": [
                    "success",
                    "data",
                    "meta"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "data": {
                        "type": "object",
                        "required": [
                            "totalSpend",
                            "adCount",
                            "matchedAdCount",
                            "matchedTotalSpend"
                        ],
                        "properties": {
                            "totalSpend": {
                                "type": "number",
                                "description": "Estimated spend in EUR of the sampled top ads."
                            },
                            "adCount": {
                                "type": "integer",
                                "description": "Sampled ads (at most 1,000)."
                            },
                            "mediaTypeStats": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "media_type",
                                        "count",
                                        "total_spend"
                                    ],
                                    "properties": {
                                        "media_type": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "count": {
                                            "type": "integer"
                                        },
                                        "total_spend": {
                                            "type": "string",
                                            "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                                            "description": "Estimated spend in EUR. Decimal string.",
                                            "nullable": true
                                        }
                                    }
                                }
                            },
                            "durationStats": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "duration",
                                        "count",
                                        "total_spend"
                                    ],
                                    "properties": {
                                        "duration": {
                                            "type": "integer",
                                            "nullable": false
                                        },
                                        "count": {
                                            "type": "integer"
                                        },
                                        "total_spend": {
                                            "type": "number",
                                            "description": "Estimated spend in EUR."
                                        },
                                        "duration_range": {
                                            "type": "string"
                                        }
                                    }
                                }
                            },
                            "maxDurationSpend": {
                                "type": "number"
                            },
                            "genderStats": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "gender",
                                        "ad_count",
                                        "total_spend"
                                    ],
                                    "properties": {
                                        "gender": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "ad_count": {
                                            "type": "integer"
                                        },
                                        "total_spend": {
                                            "type": "number",
                                            "description": "Estimated spend in EUR."
                                        },
                                        "total_reach": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            },
                            "ageStats": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "age_range",
                                        "ad_count",
                                        "total_spend"
                                    ],
                                    "properties": {
                                        "age_range": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "ad_count": {
                                            "type": "integer"
                                        },
                                        "total_spend": {
                                            "type": "number",
                                            "description": "Estimated spend in EUR."
                                        },
                                        "total_reach": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            },
                            "ctaStats": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "cta_text",
                                        "count",
                                        "total_spend"
                                    ],
                                    "properties": {
                                        "cta_text": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "count": {
                                            "type": "integer"
                                        },
                                        "total_spend": {
                                            "type": "string",
                                            "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                                            "description": "Estimated spend in EUR. Decimal string.",
                                            "nullable": true
                                        }
                                    }
                                }
                            },
                            "hooksStats": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "hook_text",
                                        "ad_count",
                                        "total_spend"
                                    ],
                                    "properties": {
                                        "hook_text": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "ad_count": {
                                            "type": "integer"
                                        },
                                        "total_spend": {
                                            "type": "string",
                                            "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                                            "description": "Estimated spend in EUR. Decimal string.",
                                            "nullable": true
                                        },
                                        "hook_type": {
                                            "type": "string",
                                            "nullable": true
                                        }
                                    }
                                }
                            },
                            "headlineStats": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "headline",
                                        "count",
                                        "total_spend"
                                    ],
                                    "properties": {
                                        "headline": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "count": {
                                            "type": "integer"
                                        },
                                        "total_spend": {
                                            "type": "string",
                                            "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
                                            "description": "Estimated spend in EUR. Decimal string.",
                                            "nullable": true
                                        }
                                    }
                                }
                            },
                            "matchedAdCount": {
                                "type": "integer",
                                "description": "All matching ads."
                            },
                            "matchedTotalSpend": {
                                "type": "number",
                                "description": "Estimated spend in EUR of all matching ads."
                            }
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/SpendMeta"
                    }
                }
            },
            "TopLandingpagesResponse": {
                "type": "object",
                "required": [
                    "success",
                    "data",
                    "count",
                    "meta"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/LandingPage"
                        }
                    },
                    "count": {
                        "type": "integer"
                    },
                    "meta": {
                        "$ref": "#/components/schemas/SpendMeta"
                    }
                }
            },
            "ListsResponse": {
                "description": "lists without list_id (or with ad_id); list with list_id.",
                "oneOf": [
                    {
                        "type": "object",
                        "required": [
                            "success",
                            "lists"
                        ],
                        "properties": {
                            "success": {
                                "type": "boolean",
                                "enum": [
                                    true
                                ]
                            },
                            "lists": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/AdList"
                                }
                            }
                        }
                    },
                    {
                        "type": "object",
                        "required": [
                            "success",
                            "list"
                        ],
                        "properties": {
                            "success": {
                                "type": "boolean",
                                "enum": [
                                    true
                                ]
                            },
                            "list": {
                                "$ref": "#/components/schemas/AdList"
                            }
                        }
                    }
                ]
            },
            "ProjectsResponse": {
                "description": "projects without public_id (or with brand_id); project with public_id.",
                "oneOf": [
                    {
                        "type": "object",
                        "required": [
                            "success",
                            "projects"
                        ],
                        "properties": {
                            "success": {
                                "type": "boolean",
                                "enum": [
                                    true
                                ]
                            },
                            "projects": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/Project"
                                }
                            }
                        }
                    },
                    {
                        "type": "object",
                        "required": [
                            "success",
                            "project"
                        ],
                        "properties": {
                            "success": {
                                "type": "boolean",
                                "enum": [
                                    true
                                ]
                            },
                            "project": {
                                "$ref": "#/components/schemas/Project"
                            }
                        }
                    }
                ]
            },
            "AlertCountResponse": {
                "type": "object",
                "required": [
                    "success",
                    "count"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "count": {
                        "type": "integer",
                        "minimum": 0
                    }
                }
            },
            "IntegrationItem": {
                "type": "object",
                "description": "One ad.new or ad.spend_alert event; identical in polling items and webhook bodies. Media URLs are stored copies or null.",
                "required": [
                    "id",
                    "event",
                    "occurred_at",
                    "currency",
                    "spend_is_estimate",
                    "brand",
                    "ad",
                    "alert"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "pattern": "^ad\\.(new|spend_alert):[0-9]+$",
                        "description": "Stable event id (ad.new:<internal_ad_id> or ad.spend_alert:<alert_id>); use it to deduplicate."
                    },
                    "event": {
                        "type": "string",
                        "enum": [
                            "ad.new",
                            "ad.spend_alert"
                        ]
                    },
                    "occurred_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "ISO 8601 with offset: first seen (ad.new) or alert created (ad.spend_alert)."
                    },
                    "currency": {
                        "type": "string",
                        "enum": [
                            "EUR"
                        ]
                    },
                    "spend_is_estimate": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "brand": {
                        "type": "object",
                        "required": [
                            "page_id",
                            "name",
                            "image_url",
                            "url"
                        ],
                        "properties": {
                            "page_id": {
                                "type": "string",
                                "pattern": "^[0-9]{5,25}$",
                                "description": "Meta advertiser page ID, kept as a string."
                            },
                            "name": {
                                "type": "string",
                                "nullable": true
                            },
                            "image_url": {
                                "type": "string",
                                "nullable": true
                            },
                            "url": {
                                "type": "string",
                                "description": "Advertiser page on AdSpendSpy."
                            }
                        }
                    },
                    "ad": {
                        "type": "object",
                        "required": [
                            "internal_ad_id",
                            "meta_ad_id",
                            "media_type",
                            "platforms",
                            "is_active",
                            "estimated_spend_eur",
                            "spend_coverage",
                            "url"
                        ],
                        "properties": {
                            "internal_ad_id": {
                                "type": "integer",
                                "description": "Pass this value to ads/details.php as ad_id."
                            },
                            "meta_ad_id": {
                                "type": "string",
                                "nullable": true
                            },
                            "ad_archive_id": {
                                "type": "string",
                                "nullable": true
                            },
                            "headline": {
                                "type": "string",
                                "nullable": true
                            },
                            "body_text": {
                                "type": "string",
                                "nullable": true,
                                "description": "Cut at 2,000 characters.",
                                "maxLength": 2000
                            },
                            "cta_text": {
                                "type": "string",
                                "nullable": true
                            },
                            "landing_url": {
                                "type": "string",
                                "nullable": true
                            },
                            "media_type": {
                                "type": "string",
                                "nullable": true
                            },
                            "thumbnail_url": {
                                "type": "string",
                                "nullable": true
                            },
                            "video_url": {
                                "type": "string",
                                "nullable": true
                            },
                            "platforms": {
                                "type": "array",
                                "items": {
                                    "type": "string",
                                    "enum": [
                                        "facebook",
                                        "instagram",
                                        "messenger",
                                        "audience_network"
                                    ]
                                }
                            },
                            "start_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Date, format YYYY-MM-DD."
                            },
                            "is_active": {
                                "type": "boolean"
                            },
                            "estimated_spend_eur": {
                                "type": "number",
                                "nullable": true,
                                "description": "Latest cumulative estimated spend in EUR; null means unknown."
                            },
                            "spend_coverage": {
                                "type": "string",
                                "enum": [
                                    "eu_uk",
                                    "eu_uk_us",
                                    "us_extrapolated",
                                    "none"
                                ],
                                "description": "Basis of the estimate: eu_uk is based on reach data that Meta publishes for the EU and UK; us_extrapolated and the US part of eu_uk_us are extrapolated; none means no estimate.",
                                "nullable": true
                            },
                            "url": {
                                "type": "string",
                                "description": "Ad page on AdSpendSpy."
                            }
                        }
                    },
                    "alert": {
                        "type": "object",
                        "nullable": true,
                        "description": "null for ad.new.",
                        "required": [
                            "alert_id",
                            "threshold_eur",
                            "spend_at_alert_eur"
                        ],
                        "properties": {
                            "alert_id": {
                                "type": "integer"
                            },
                            "threshold_eur": {
                                "type": "number",
                                "nullable": true,
                                "description": "Alert threshold in EUR when the alert was created."
                            },
                            "spend_at_alert_eur": {
                                "type": "number",
                                "nullable": true,
                                "description": "Estimated spend in EUR when the alert was created."
                            }
                        }
                    }
                }
            },
            "IntegrationItemListResponse": {
                "type": "object",
                "required": [
                    "success",
                    "items",
                    "pagination",
                    "meta"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "items": {
                        "type": "array",
                        "description": "Newest first (by internal_ad_id or alert_id).",
                        "items": {
                            "$ref": "#/components/schemas/IntegrationItem"
                        }
                    },
                    "pagination": {
                        "type": "object",
                        "required": [
                            "next_cursor",
                            "has_more"
                        ],
                        "properties": {
                            "next_cursor": {
                                "type": "string",
                                "nullable": true,
                                "description": "Send as cursor with the same filters for the next page; null on the last page."
                            },
                            "has_more": {
                                "type": "boolean"
                            }
                        }
                    },
                    "meta": {
                        "type": "object",
                        "required": [
                            "currency",
                            "spend_basis",
                            "spend_is_estimate"
                        ],
                        "properties": {
                            "currency": {
                                "type": "string",
                                "enum": [
                                    "EUR"
                                ]
                            },
                            "spend_basis": {
                                "type": "string",
                                "enum": [
                                    "latest_cumulative_estimate"
                                ]
                            },
                            "spend_is_estimate": {
                                "type": "boolean",
                                "enum": [
                                    true
                                ]
                            }
                        }
                    }
                }
            },
            "Webhook": {
                "type": "object",
                "required": [
                    "id",
                    "event",
                    "target_url",
                    "platform",
                    "filters",
                    "created_at"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "pattern": "^whk_[a-f0-9]{8,48}$"
                    },
                    "event": {
                        "type": "string",
                        "enum": [
                            "ad.new",
                            "ad.spend_alert"
                        ]
                    },
                    "target_url": {
                        "type": "string"
                    },
                    "platform": {
                        "type": "string",
                        "enum": [
                            "zapier",
                            "make",
                            "n8n",
                            "custom"
                        ]
                    },
                    "filters": {
                        "type": "object",
                        "required": [
                            "page_id",
                            "project"
                        ],
                        "properties": {
                            "page_id": {
                                "type": "string",
                                "nullable": true
                            },
                            "project": {
                                "type": "string",
                                "nullable": true
                            }
                        }
                    },
                    "created_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "ISO 8601 with offset."
                    },
                    "last_delivery_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "list_webhooks only. ISO 8601 with offset."
                    },
                    "last_success_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "list_webhooks only. ISO 8601 with offset."
                    },
                    "last_status": {
                        "type": "string",
                        "enum": [
                            "sent",
                            "retrying",
                            "failed"
                        ],
                        "nullable": true,
                        "description": "list_webhooks only. Status of the latest delivery; null before the first one."
                    }
                }
            },
            "WebhookCreated": {
                "type": "object",
                "required": [
                    "success",
                    "webhook",
                    "secret"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "webhook": {
                        "$ref": "#/components/schemas/Webhook"
                    },
                    "secret": {
                        "type": "string",
                        "pattern": "^whsec_[a-f0-9]+$",
                        "description": "Signing secret. Shown only in this response; store it to verify X-AdSpendSpy-Signature."
                    }
                }
            },
            "WebhookListResponse": {
                "type": "object",
                "required": [
                    "success",
                    "webhooks"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "webhooks": {
                        "type": "array",
                        "maxItems": 25,
                        "items": {
                            "$ref": "#/components/schemas/Webhook"
                        }
                    }
                }
            },
            "WebhookUnsubscribed": {
                "type": "object",
                "required": [
                    "success",
                    "webhook"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "enum": [
                            true
                        ]
                    },
                    "webhook": {
                        "type": "object",
                        "required": [
                            "id",
                            "disabled_at"
                        ],
                        "properties": {
                            "id": {
                                "type": "string",
                                "pattern": "^whk_[a-f0-9]{8,48}$"
                            },
                            "disabled_at": {
                                "type": "string",
                                "nullable": true,
                                "description": "ISO 8601 with offset."
                            }
                        }
                    }
                }
            }
        },
        "responses": {
            "BadRequest": {
                "description": "Invalid parameter or body.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "page_id must be a Facebook Page ID string"
                        }
                    }
                }
            },
            "Unauthorized": {
                "description": "No credentials, or an invalid or revoked API key or access token.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "Invalid or revoked API key."
                        }
                    }
                },
                "headers": {
                    "WWW-Authenticate": {
                        "description": "Sent for OAuth access tokens only.",
                        "schema": {
                            "type": "string"
                        }
                    }
                }
            },
            "PaymentRequired": {
                "description": "The account has no active membership or eligible trial.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "An active membership is required to use this feature.",
                            "redirect_url": "/billing.php",
                            "reason": "membership_required"
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "The endpoint is not available with this credential, or the OAuth token lacks the required scope.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "This app was not granted the account.read permission."
                        }
                    }
                }
            },
            "NotFound": {
                "description": "The requested record does not exist in your account.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "Ad not found"
                        }
                    }
                }
            },
            "MethodNotAllowed": {
                "description": "Wrong HTTP method.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "Only GET requests are allowed"
                        }
                    }
                }
            },
            "PayloadTooLarge": {
                "description": "The JSON body exceeds 64 KiB.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "Request body is too large"
                        }
                    }
                }
            },
            "TooManyRequests": {
                "description": "Daily request limit reached (1,000 per API key, or per user for OAuth).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "Daily API request limit reached (1000 requests)."
                        }
                    }
                },
                "headers": {
                    "Retry-After": {
                        "description": "Seconds until the daily quota resets. Sent for OAuth access tokens only.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    }
                }
            },
            "Unavailable": {
                "description": "Data, authentication or quota accounting is temporarily unavailable. Retry later.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "message": "Data temporarily unavailable"
                        }
                    }
                }
            },
            "WebhookTooManyRequests": {
                "description": "More than 120 webhook-management calls in one hour (code rate_limited), or the daily request limit is reached.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "code": "rate_limited",
                            "message": "Too many webhook requests. Try again in an hour."
                        }
                    }
                },
                "headers": {
                    "Retry-After": {
                        "description": "Seconds until the daily quota resets. Sent for OAuth access tokens only.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    }
                }
            },
            "WebhookUnavailable": {
                "description": "Subscribe only: webhooks are paused (code integrations_paused; use the polling endpoints). Any webhook endpoint: temporarily unavailable (code unavailable).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "code": "integrations_paused",
                            "message": "Webhooks are paused right now. Use the polling endpoints or try again later."
                        }
                    }
                }
            }
        }
    }
}