{
  "openapi": "3.0.1",
  "info": {
    "title": "Salesforce AppExchange Scraper & Listing Monitor",
    "description": "Scrape & monitor Salesforce AppExchange apps, agents and ISVs: ratings, reviews, review insights vs competitors, pricing, versions, HQ country, market reports. $2 per 1,000 listings.",
    "version": "1.0",
    "x-build-id": "rkHI1fOpMKP00CGBY"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/signalscope-data~appexchange-tracker/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-signalscope-data-appexchange-tracker",
        "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/signalscope-data~appexchange-tracker/runs": {
      "post": {
        "operationId": "runs-sync-signalscope-data-appexchange-tracker",
        "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/signalscope-data~appexchange-tracker/run-sync": {
      "post": {
        "operationId": "run-sync-signalscope-data-appexchange-tracker",
        "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": "Search keywords",
            "type": "array",
            "description": "Keywords to search on AppExchange, e.g. \"cpq\", \"e-signature\", \"data backup\", \"ai agent\". Each keyword is a separate ranked list. Combine with categories to search inside a category.",
            "items": {
              "type": "string"
            }
          },
          "strictSearch": {
            "title": "Strict keyword match",
            "type": "boolean",
            "description": "AppExchange search is semantic and also returns loosely related apps (even for nonsense queries). Keep only listings whose name, description, publisher or categories contain every keyword. rank still shows the position on AppExchange.",
            "default": true
          },
          "categories": {
            "title": "Categories",
            "type": "array",
            "description": "AppExchange category slugs. Without keywords the whole category is listed (up to max results). Top level: sales, customerService, marketing, productivity, itAndAdministration, analytics, finance, commerce, integration, humanResources, collaboration. Sub-categories: quotesAndOrders, contractManagement, documentGeneration, dataCleansing, telephony, fieldService, salesIntelligence, accounting, projectManagement, marketingAutomation, surveys, etc.",
            "items": {
              "type": "string"
            }
          },
          "publishers": {
            "title": "Publishers (vendor filter)",
            "type": "array",
            "description": "Keep only listings whose publisher name contains one of these, e.g. \"Conga\", \"DocuSign\". Used alone, the Actor searches each publisher name and returns that vendor's listings.",
            "items": {
              "type": "string"
            }
          },
          "listingIds": {
            "title": "Specific listings (watchlist)",
            "type": "array",
            "description": "Track exact listings by AppExchange listing ID (e.g. \"a0N30000001f1q1EAA\") or full listing URL (https://appexchange.salesforce.com/appxListingDetail?listingId=...).",
            "items": {
              "type": "string"
            }
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "relevance",
              "popularity",
              "rating",
              "reviews",
              "name"
            ],
            "type": "string",
            "description": "Ranking used for each list. The rank field and rank-change tracking follow this order.",
            "default": "relevance"
          },
          "maxResultsPerQuery": {
            "title": "Max results per query",
            "minimum": 1,
            "maximum": 3000,
            "type": "integer",
            "description": "Max listings per keyword / category list. A whole category (e.g. sales, ~1,700 apps) fits in one query.",
            "default": 100
          },
          "outputLevel": {
            "title": "Output level",
            "enum": [
              "listings",
              "publishers"
            ],
            "type": "string",
            "description": "\"publishers\" outputs one row per AppExchange publisher (ISV): website and domain, headquarters, founded year, employees, number of listings, total reviews, weighted average rating, categories, industries, pricing models, latest release, last security review and a full listings[] portfolio (each publisher's other listings are added automatically). Listing details are loaded for every listing (charged as listing details). No emails or phone numbers. Monitor modes report new publishers, new listings and review growth.",
            "default": "listings"
          },
          "maxListingsPerPublisher": {
            "title": "Max listings per publisher",
            "minimum": 1,
            "maximum": 300,
            "type": "integer",
            "description": "Publisher level only: cap on listings per publisher (matched listings + the rest of its portfolio, most popular first). Each listing is charged as listing details. Rows where the cap was hit have portfolioComplete: false. Salesforce Labs alone has 270+ listings.",
            "default": 50
          },
          "includeDetails": {
            "title": "Include details (pricing, versions, security review)",
            "type": "boolean",
            "description": "Fetch each listing's detail page data: pricing plans and starting price, published date, latest package version and release date, security review date, editions, required products, industries, highlights, and publisher HQ / founded year / website. Charged as an extra event per listing.",
            "default": false
          },
          "includeReviews": {
            "title": "Include user reviews",
            "type": "boolean",
            "description": "Also output each listing's AppExchange user reviews as separate rows (recordType \"review\"): rating, title, text, date, likes, project details (edition, users, implementation) and comment thread. Reviewer names are not exported. In \"new\"/\"changed\" output mode, later runs output only reviews posted since the previous run. Charged per review.",
            "default": false
          },
          "maxReviewsPerListing": {
            "title": "Max reviews per listing",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Newest reviews first. Popular apps have 1,000+ reviews. Also the sample size for review insights.",
            "default": 20
          },
          "reviewsSince": {
            "title": "Reviews posted since",
            "type": "string",
            "description": "Optional date (YYYY-MM-DD). Only reviews posted on or after this date are output."
          },
          "maxReviewRating": {
            "title": "Max review rating",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Output only reviews with at most this many stars, e.g. 2 = critical reviews only (competitor weak spots). 5 = all reviews.",
            "default": 5
          },
          "includeReviewInsights": {
            "title": "Review insights & competitor comparison",
            "type": "boolean",
            "description": "Add one recordType \"review-insights\" row per listing, built from its newest reviews (up to \"Max reviews per listing\", respects \"Reviews since\"): rating distribution, negative/positive share, rating trend (last 12 months vs older), top complaint themes in 1-3 star reviews (bugs, setup & implementation, integration & sync, limits & performance, upgrades, support, pricing & licensing, contract & renewal, usability, documentation, data quality, permissions) with example quotes, top praise themes in 4-5 star reviews (support, ease of use, fast implementation, time saved, flexibility, reliability, native to Salesforce, value), feature requests, frequent phrases, reviews per year and reply rate. With 2+ listings (10+ reviews each) a \"review-comparison\" row benchmarks them: issue and praise matrix per 100 reviews, relative weaknesses and strengths. Rule-based (no AI), $0.01 per row. Works without \"Include reviews\" (reviews read for insights are not charged). Tip: raise \"Max reviews per listing\" to 100-200.",
            "default": false
          },
          "listingTypes": {
            "title": "Listing types",
            "type": "array",
            "description": "Optional filter by technology prefix, e.g. \"force/package\" (managed packages), \"force/copilot\" (Agentforce agents), \"force/flow\", \"force/lightning\", \"salesforce-platform/api\", \"marketing-cloud\", \"tableau\".",
            "items": {
              "type": "string"
            }
          },
          "minReviews": {
            "title": "Min reviews",
            "minimum": 0,
            "type": "integer",
            "description": "Skip listings with fewer reviews than this.",
            "default": 0
          },
          "minRating": {
            "title": "Min rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Skip listings rated below this (0 = no filter). Unrated listings are skipped when set.",
            "default": 0
          },
          "hqCountries": {
            "title": "Publisher HQ countries",
            "type": "array",
            "description": "Keep only listings whose publisher is headquartered in one of these countries, e.g. \"United States\", \"UK\", \"Germany\", \"India\". AppExchange HQ is free text (\"San Francisco, CA\", \"Munich\"), so the Actor maps it to a country (publisherCountry field) from country names, US states/abbreviations, Canadian provinces and major cities. Other values match the raw HQ text (e.g. \"Texas\"). Loads listing details (charged as listing details).",
            "items": {
              "type": "string"
            }
          },
          "pricingModels": {
            "title": "Pricing models",
            "type": "array",
            "description": "Keep only these pricing models: free, freemium, paid, free_to_install (\"free\" also includes free_to_install). Loads listing details (charged as listing details).",
            "items": {
              "type": "string"
            }
          },
          "includeMarketReport": {
            "title": "Add market report per query",
            "type": "boolean",
            "description": "Add one recordType \"market-report\" row per keyword/category: listings and publishers count, average and review-weighted rating, rating distribution, review concentration (top listing / top 10 share), listing types, categories, top publishers by listings and by reviews, Agentforce/MCP counts and top listings. With details: pricing model mix, paid / free-trial share, median price per user per month (USD), new listings in the last 90/365 days, release freshness, security review recency, publisher HQ countries and industries. Also saved to the MARKET_REPORT record.",
            "default": false
          },
          "marketReportOnly": {
            "title": "Market report only (no listing rows)",
            "type": "boolean",
            "description": "Output only the market report rows (listings are analysed but not output or charged as listings). Turn on \"Include details\" for the pricing / freshness / HQ sections; loaded details are charged as listing details. outputMode and reviews are ignored.",
            "default": false
          },
          "outputMode": {
            "title": "Output mode",
            "enum": [
              "all",
              "new",
              "changed"
            ],
            "type": "string",
            "description": "\"new\" and \"changed\" compare with the previous run of the same monitor name. The first run is the baseline and outputs everything.",
            "default": "all"
          },
          "trackChanges": {
            "title": "Add change fields in 'All' mode",
            "type": "boolean",
            "description": "Save a snapshot and add previousReviewCount, reviewsChange, previousRating, rankChange and changeTypes even when outputting all results.",
            "default": false
          },
          "minReviewsChange": {
            "title": "New reviews threshold",
            "minimum": 1,
            "type": "integer",
            "description": "A reviews-up change is reported when a listing gained at least this many reviews since the last run.",
            "default": 1
          },
          "minRankChange": {
            "title": "Rank change threshold",
            "minimum": 1,
            "type": "integer",
            "description": "A rank-up / rank-down change is reported when the position moved at least this many places.",
            "default": 5
          },
          "stateKey": {
            "title": "Monitor name",
            "type": "string",
            "description": "Snapshot name used for change tracking. Use a different name for each separate monitor/schedule.",
            "default": "default"
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}