{
  "openapi": "3.0.1",
  "info": {
    "title": "Facebook Ads Performance Calculator & Benchmarker",
    "description": "Benchmark a whole niche from Meta's public Ad Library: which CTAs, formats, headlines, landing domains, words and phrases dominate, and how long each choice stays on air. Longevity is the honest performance proxy - advertisers keep paying for creatives that work. Compares niches side by side.",
    "version": "0.0",
    "x-build-id": "2O9Tbz94Z1b3VyQ0t"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/fanndev~facebook-ads-benchmarker/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-fanndev-facebook-ads-benchmarker",
        "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/fanndev~facebook-ads-benchmarker/runs": {
      "post": {
        "operationId": "runs-sync-fanndev-facebook-ads-benchmarker",
        "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/fanndev~facebook-ads-benchmarker/run-sync": {
      "post": {
        "operationId": "run-sync-fanndev-facebook-ads-benchmarker",
        "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": {
          "niches": {
            "title": "Niches",
            "type": "array",
            "description": "What to benchmark. Simple form: one keyword per line, each treated as its own niche. Grouped form (paste as JSON): [{\"name\": \"skincare\", \"keywords\": [\"serum\", \"moisturiser\"], \"advertisers\": [\"123456789\"]}] so several searches feed one benchmark.",
            "items": {
              "type": "string"
            }
          },
          "countries": {
            "title": "Countries",
            "type": "array",
            "description": "ISO country codes. The Ad Library is country-scoped, so benchmarking two countries shows you how the same niche is sold in each.",
            "default": [
              "US"
            ],
            "items": {
              "type": "string"
            }
          },
          "sampleSizePerNiche": {
            "title": "Ads sampled per niche",
            "minimum": 30,
            "maximum": 2000,
            "type": "integer",
            "description": "The budget is shared across the searches that make up a niche, so a two-keyword niche does not quietly collect twice the ads of a one-keyword niche. Every benchmark row reports the sampleSize it was computed from.",
            "default": 150
          },
          "activeStatus": {
            "title": "Active status",
            "enum": [
              "active",
              "all",
              "inactive"
            ],
            "type": "string",
            "description": "Benchmarking currently-running ads tells you what the niche is doing now. Include stopped ads to see what it has tried.",
            "default": "active"
          },
          "adType": {
            "title": "Ad category",
            "enum": [
              "all",
              "political_and_issue_ads",
              "employment_ads",
              "housing_ads",
              "credit_ads",
              "financial_products_and_services_ads"
            ],
            "type": "string",
            "description": "Leave on 'All ads' for commercial benchmarking.",
            "default": "all"
          },
          "mediaType": {
            "title": "Creative type",
            "enum": [
              "all",
              "image",
              "video",
              "meme",
              "image_and_meme",
              "none"
            ],
            "type": "string",
            "description": "Restrict the sample to one creative type. Leaving this on 'Any' is what produces the image-vs-video split in the output.",
            "default": "all"
          },
          "searchType": {
            "title": "Keyword match",
            "enum": [
              "keyword_unordered",
              "keyword_exact_phrase"
            ],
            "type": "string",
            "description": "Unordered matches the words in any order; exact phrase matches the phrase as typed.",
            "default": "keyword_unordered"
          },
          "publisherPlatforms": {
            "title": "Platforms",
            "type": "array",
            "description": "Restrict the sample to ads delivered on these Meta surfaces.",
            "items": {
              "type": "string",
              "enum": [
                "FACEBOOK",
                "INSTAGRAM",
                "AUDIENCE_NETWORK",
                "MESSENGER",
                "WHATSAPP",
                "THREADS"
              ]
            },
            "default": []
          },
          "contentLanguages": {
            "title": "Ad languages",
            "type": "array",
            "description": "Two-letter language codes, e.g. en, id, es. Worth setting when benchmarking a non-English market.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "topN": {
            "title": "Rows per ranking",
            "minimum": 3,
            "maximum": 50,
            "type": "integer",
            "description": "How many entries to keep in each top-N ranking (CTAs, words, headlines, advertisers).",
            "default": 10
          },
          "minGroupSample": {
            "title": "Minimum ads behind a longevity figure",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "Groups thinner than this are dropped from the longevity rankings. A median computed from two ads is noise wearing a number's clothes.",
            "default": 3
          },
          "includeAdSample": {
            "title": "Also output the ads themselves",
            "type": "boolean",
            "description": "Append the sampled ads as AD_SAMPLE rows so you can check any benchmark against the creatives behind it.",
            "default": false
          },
          "exportFormats": {
            "title": "Extra export files",
            "type": "array",
            "description": "Also write the results to the key-value store in these formats. The dataset is always produced regardless.",
            "items": {
              "type": "string",
              "enum": [
                "json",
                "ndjson",
                "csv",
                "xlsx"
              ],
              "enumTitles": [
                "JSON",
                "NDJSON",
                "CSV",
                "Excel (XLSX)"
              ]
            },
            "default": []
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Recommended on the Apify platform if you want more than the first 30 ads of each search, which caps the sample. Facebook serves the rendered first page fine from any IP, but on Apify's datacenter IPs it answers the very first pagination request with \"Rate limit exceeded\" - measured 2026-09-20. Switching the Apify proxy on with the RESIDENTIAL group restored full pagination in the same test (60 ads over 4 pages against 30). Running from your own machine, no proxy is needed at all. The actor logs a warning naming this when it happens, so a short run is never silently mistaken for a short result set.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}