{
  "openapi": "3.0.1",
  "info": {
    "title": "Salesforce AppExchange Scraper - Apps & Publisher Leads",
    "description": "Scrape Salesforce AppExchange into rich B2B vendor leads: publisher name, email, website, HQ, employees, ratings, reviews, pricing, security review, editions & categories. Filter by keyword, category, rating or HQ country. Monitor mode + email enrichment.",
    "version": "0.1",
    "x-build-id": "PQxaWU6PULM3pWtzG"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapesage~salesforce-appexchange-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapesage-salesforce-appexchange-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/scrapesage~salesforce-appexchange-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapesage-salesforce-appexchange-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/scrapesage~salesforce-appexchange-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapesage-salesforce-appexchange-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": {
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Free-text terms to match against the app name, description and publisher name (case-insensitive; an app is kept if it matches ANY term). Leave empty to scan the whole marketplace. Example: <code>marketing</code>, <code>data quality</code>, <code>Docusign</code>.",
            "items": {
              "type": "string"
            }
          },
          "categories": {
            "title": "Categories",
            "type": "array",
            "description": "Only keep apps in these AppExchange categories. Use a friendly term that matches the category name (case-insensitive, partial match): <code>Sales</code>, <code>Marketing</code>, <code>Customer Service</code>, <code>Analytics</code>, <code>IT Administration</code>, <code>Productivity</code>, <code>Collaboration</code>, <code>Finance</code>, <code>Human Resources</code>, <code>ERP</code>, <code>Commerce</code>, <code>Integration</code>. Leave empty for all categories.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Start URLs / listing IDs",
            "type": "array",
            "description": "Specific AppExchange listings to scrape directly. Paste listing-detail URLs (<code>https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3u00000Qt7LiEAJ</code>) or bare listing IDs (<code>a0N3u00000Qt7LiEAJ</code>). Used in addition to the keyword/category scan.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "maxItems": {
            "title": "Max apps",
            "minimum": 1,
            "type": "integer",
            "description": "Maximum number of app records to scrape.",
            "default": 100
          },
          "includeDetails": {
            "title": "Include publisher & full details",
            "type": "boolean",
            "description": "Fetch each app's detail for the full B2B record: publisher (vendor) name, email, website, HQ location, employee count & description, pricing model, security-review status, supported editions, app type and full description. Turn off for a faster, lighter run that returns only listing-level fields (name, rating, reviews, categories, publisher name).",
            "default": true
          },
          "includeReviews": {
            "title": "Include customer reviews",
            "type": "boolean",
            "description": "Fetch customer reviews for each app (title, rating, body, author, company, date). Adds one request per app.",
            "default": false
          },
          "maxReviews": {
            "title": "Max reviews per app",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "How many reviews to keep per app when reviews are enabled.",
            "default": 10
          },
          "enrichPublisherEmails": {
            "title": "Enrich emails from the publisher website",
            "type": "boolean",
            "description": "For each app whose publisher has a website, crawl it (home + contact/about, up to 3 pages) to extract contact emails, phone numbers and social links. Boosts contactability for publishers that don't list an email on AppExchange. Requires details.",
            "default": false
          },
          "emitPublisherLeads": {
            "title": "Also output one lead per publisher",
            "type": "boolean",
            "description": "In addition to per-app rows, output one deduplicated B2B lead per unique publisher (vendor) with their app count, average rating, total reviews and contact details. Requires details.",
            "default": false
          },
          "minRating": {
            "title": "Minimum rating (0–5)",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Only keep apps with at least this average star rating. 0 = no minimum.",
            "default": 0
          },
          "freeOnly": {
            "title": "Only free apps",
            "type": "boolean",
            "description": "Keep only apps that are free to install.",
            "default": false
          },
          "paidOnly": {
            "title": "Only paid apps",
            "type": "boolean",
            "description": "Keep only paid / commercial apps (stronger vendor-spend signal).",
            "default": false
          },
          "lightningReadyOnly": {
            "title": "Only Lightning Ready apps",
            "type": "boolean",
            "description": "Keep only apps marked Lightning Ready.",
            "default": false
          },
          "securityReviewedOnly": {
            "title": "Only security-reviewed apps",
            "type": "boolean",
            "description": "Keep only apps that have passed the Salesforce Security Review. Requires details.",
            "default": false
          },
          "withPublisherEmailOnly": {
            "title": "Only apps whose publisher has an email",
            "type": "boolean",
            "description": "Skip apps where no publisher email is available (from AppExchange or website enrichment). Requires details.",
            "default": false
          },
          "withWebsiteOnly": {
            "title": "Only apps whose publisher has a website",
            "type": "boolean",
            "description": "Skip apps where the publisher has no website. Requires details.",
            "default": false
          },
          "hqCountries": {
            "title": "Publisher HQ countries",
            "type": "array",
            "description": "Only keep apps whose publisher is headquartered in one of these countries / locations (matched against country code and HQ text, e.g. <code>US</code>, <code>United Kingdom</code>, <code>India</code>). Requires details.",
            "items": {
              "type": "string"
            }
          },
          "editions": {
            "title": "Supported editions",
            "type": "array",
            "description": "Only keep apps that support at least one of these Salesforce editions. Use the codes <code>PE</code> (Professional), <code>EE</code> (Enterprise), <code>UE</code> (Unlimited), <code>DE</code> (Developer), <code>PP</code> (Performance), <code>GE</code> (Group), <code>EC</code> (Essentials).",
            "items": {
              "type": "string"
            }
          },
          "maxScan": {
            "title": "Max apps to scan",
            "minimum": 24,
            "type": "integer",
            "description": "Upper bound on how many listings to examine while applying keyword/category/edition filters. Protects you from scanning the whole 5,000+ catalog when a filter matches few apps.",
            "default": 1500
          },
          "monitorMode": {
            "title": "Monitor mode (only new apps)",
            "type": "boolean",
            "description": "Remember listing IDs returned in previous runs (in a named key-value store) and emit only NEW apps on each run. Perfect with Apify Schedules for a steady new-vendor feed — it does not conflict with scheduling: the schedule triggers the run, monitor mode deduplicates this run's records against everything earlier runs already returned.",
            "default": false
          },
          "monitorStoreName": {
            "title": "Monitor store name",
            "type": "string",
            "description": "Name of the key-value store that holds the seen-listing memory for monitor mode. Use different names to track independent searches separately (lowercase letters, digits and hyphens only).",
            "default": "salesforce-appexchange-monitor"
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 25,
            "type": "integer",
            "description": "How many API requests to run in parallel. 10 is a good default for the AppExchange API.",
            "default": 10
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Proxies to use. The AppExchange API works from plain datacenter IPs, so the default Apify Proxy (automatic) is enough and cheapest.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}