{
  "openapi": "3.0.1",
  "info": {
    "title": "Meta (Facebook & Instagram) Ads Library Scraper",
    "description": "Scrape all Facebook & Instagram ads of any page from the Meta Ad Library. Extract ad creatives, texts, titles, CTAs, image & HD video URLs, spend, reach and dates. Fast parallel scraping, multiple pages per run, date filters, no login or API key. Daily checks to ensure quality!",
    "version": "0.2",
    "x-build-id": "PtywYVGExki4SNYbH"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/jmlp~meta-ad-library-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-jmlp-meta-ad-library-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/jmlp~meta-ad-library-scraper/runs": {
      "post": {
        "operationId": "runs-sync-jmlp-meta-ad-library-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/jmlp~meta-ad-library-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-jmlp-meta-ad-library-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "adLibraryUrls": {
            "title": "Ad Library URLs",
            "type": "array",
            "description": "One or more full Ad Library URLs copied from the browser - each is scraped in the same run (in parallel when Max concurrency > 1). Both kinds work: a page URL (view_all_page_id=...) and a keyword search URL (q=...&search_type=keyword_unordered). Each URL brings its own target, dates, country and active status; the individual fields below fill in whatever a URL does not carry. Max ads applies globally across all of them.",
            "items": {
              "type": "string"
            }
          },
          "adLibraryUrl": {
            "title": "Ad Library URL (single)",
            "type": "string",
            "description": "Paste a single Ad Library URL - either a page URL (view_all_page_id=...) or a keyword search URL (q=...). Its target, dates, country and active status take precedence over the individual fields below. Other URL parameters (ad type, media type, sort order) are ignored - the actor pins those to the browser defaults."
          },
          "pageIDs": {
            "title": "Page IDs",
            "type": "array",
            "description": "Multiple numeric page ids to scrape in one run, all using the dates/country/active status set below. Scrape keywords instead with the Keywords field.",
            "items": {
              "type": "string"
            }
          },
          "pageID": {
            "title": "Page ID",
            "type": "string",
            "description": "Numeric Facebook page id, the view_all_page_id value from the Ad Library URL. Not needed when an Ad Library URL is pasted above, or when you are searching by keyword - clear it in that case, or the page is scraped as well."
          },
          "keyword": {
            "title": "Keyword",
            "type": "string",
            "description": "Search every advertiser's ads for this text instead of scraping one page - the same as typing it into the Ad Library search box. Keyword searches can match tens of thousands of ads, so set Max ads and narrow the country and dates. Runs in addition to any page id set above, so clear Page ID if you only want the keyword."
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Several keywords to search in one run, each using the search type, dates, country and active status set here. Max ads applies globally across all of them.",
            "items": {
              "type": "string"
            }
          },
          "searchType": {
            "title": "Keyword match type",
            "enum": [
              "keyword_unordered",
              "keyword_exact_phrase"
            ],
            "type": "string",
            "description": "How the keyword(s) are matched. 'Any order' is the Ad Library's own default and matches the words anywhere in the ad; 'exact phrase' matches the words together, in order. Only applies to keyword searches, not page ids (a pasted URL's own search_type wins).",
            "default": "keyword_unordered"
          },
          "minDate": {
            "title": "Start date from",
            "type": "string",
            "description": "YYYY-MM-DD. Returns ads that were DELIVERING during the window (measured) - a long-running ad started earlier still matches. Leave empty for the whole archive - be aware that can be tens of thousands of ads. Facebook silently ignores the filter when minDate equals maxDate, so the actor widens such a query by one day."
          },
          "maxDate": {
            "title": "Start date to",
            "type": "string",
            "description": "YYYY-MM-DD, inclusive. Same delivery-window semantics as the from-date."
          },
          "activeStatus": {
            "title": "Active status",
            "enum": [
              "all",
              "active",
              "inactive"
            ],
            "type": "string",
            "description": "Which ads to include. 'Active only' matches what the Ad Library UI shows and keeps first runs quick; 'all' covers the page's entire archive, which can be 10-100x larger.",
            "default": "all"
          },
          "country": {
            "title": "Country",
            "enum": [
              "ALL",
              "US",
              "GB",
              "DE",
              "FR",
              "ES",
              "IT",
              "BR",
              "MX",
              "CA",
              "AU",
              "IN"
            ],
            "type": "string",
            "description": "ALL covers every country the ad ran in.",
            "default": "ALL"
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Use RESIDENTIAL groups. Datacenter IPs get challenged or blocked.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 6,
            "type": "integer",
            "description": "Parallel scraping sessions. Multiple pages/keywords run in parallel and a large target's history is split into date ranges scraped simultaneously, each on its own residential proxy session - roughly linear speedup. Set to 1 only if you need results in strict impression-ranking order, or if you ever see captcha warnings in the log.",
            "default": 4
          },
          "maxAds": {
            "title": "Max ads",
            "minimum": 1,
            "type": "integer",
            "description": "Stop after this many unique ads, counted globally across all pages and keywords. The crawl terminates as soon as the cap is hit, so this caps both runtime and cost. Clear it to scrape absolutely everything with no limit."
          },
          "maxPages": {
            "title": "Max pages per shard",
            "minimum": 1,
            "type": "integer",
            "description": "Safety cap while testing, applied to each shard separately. Empty = all."
          },
          "delayMs": {
            "title": "Delay between pages (ms)",
            "minimum": 0,
            "type": "integer",
            "description": "Milliseconds to sleep between page requests. The network already adds ~700-1500 ms per page, which is the real floor. Measured: 300 ms scraped a 210-ad page in 25 s with no captcha from a bare IP. Raise it if captchas appear. Takes precedence over the legacy 'delay' (seconds) field.",
            "default": 300
          },
          "pageSize": {
            "title": "Page size",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Facebook caps pagination at 10 results regardless of this value - measured. Kept at the browser default of 30 so the request looks normal.",
            "default": 30
          },
          "raw": {
            "title": "Raw output",
            "type": "boolean",
            "description": "Push the unprojected GraphQL ad nodes instead of the fixed output schema. Field names are the same; raw skips the null-filling and key ordering.",
            "default": false
          },
          "proxyRotations": {
            "title": "Proxy rotation attempts",
            "minimum": 1,
            "maximum": 6,
            "type": "integer",
            "description": "Residential exit nodes die without warning. If the run fails before pushing anything, the actor mints a new proxy session and retries this many times.",
            "default": 3
          },
          "resume": {
            "title": "Checkpoint progress",
            "type": "boolean",
            "description": "Save progress every ~30s so a run that gets migrated or restarted by the platform picks up where it stopped, without duplicating anything. No effect on fresh runs.",
            "default": true
          },
          "continueFromLastRun": {
            "title": "Continue from last run",
            "type": "boolean",
            "description": "If your previous run with the same input was interrupted (aborted, failed, or captcha-cut), scrape only what it missed. Note the earlier ads stay in THAT run's dataset - this run's dataset will contain only the remainder. Leave off to always get a complete dataset in one place.",
            "default": false
          },
          "shardSplitThreshold": {
            "title": "Shard split threshold",
            "minimum": 100,
            "type": "integer",
            "description": "When maxConcurrency > 1, a date range reporting more ads than this is bisected into two shards instead of walked serially. ~1500 ads is about 150 pages, roughly 6 minutes of serial work per shard.",
            "default": 1500
          },
          "docId": {
            "title": "Pagination doc_id override",
            "type": "string",
            "description": "Leave empty. A stale cached id is detected and refreshed automatically."
          },
          "proxySessionId": {
            "title": "Proxy session id",
            "type": "string",
            "description": "Pin a specific exit IP, for reproducing a run while debugging. Ignored when maxConcurrency > 1 (every shard needs its own session). Nothing is persisted between runs by default."
          },
          "impersonate": {
            "title": "TLS fingerprint",
            "type": "string",
            "description": "curl_cffi target. Empty string disables impersonation.",
            "default": "chrome146"
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}