{
  "openapi": "3.0.1",
  "info": {
    "title": "TripAdvisor Reputation Event Monitor — Stateful Typed Events",
    "description": "**Stateful TripAdvisor monitor that emits TYPED EVENTS** — `new_review`, `rating_crossed`, `rank_moved`, `review_velocity_spike`, `owner_response_gap`, `review_count_milestone`. NOT a review dump. Persists per-property state in Apify KV; re-polls and emits ONLY what changed.",
    "version": "0.1",
    "x-build-id": "sXREY5D3j17QXfSVh"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/bovi~tripadvisor-reputation-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-bovi-tripadvisor-reputation-monitor",
        "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/bovi~tripadvisor-reputation-monitor/runs": {
      "post": {
        "operationId": "runs-sync-bovi-tripadvisor-reputation-monitor",
        "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/bovi~tripadvisor-reputation-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-bovi-tripadvisor-reputation-monitor",
        "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",
        "required": [
          "propertyUrls"
        ],
        "properties": {
          "propertyUrls": {
            "title": "Property URLs to monitor",
            "type": "array",
            "description": "TripAdvisor property URLs to monitor. Each URL should point to a hotel, restaurant, or attraction page. Example: ['https://www.tripadvisor.com/Hotel_Review-g60763-d93589-Reviews-The_Plaza-New_York_City_New_York.html']. The actor extracts the location ID automatically — you can also mix hotel, restaurant, and attraction URLs in one run.",
            "items": {
              "type": "string"
            }
          },
          "kvStoreName": {
            "title": "KV store name for state persistence",
            "type": "string",
            "description": "Name of the Apify Key-Value store used to persist per-property state between runs. Defaults to 'tripadvisor-reputation-state'. Use the same name across scheduled runs to enable stateful diffing — if you change this, previous state is lost and the first run will emit no events (it bootstraps the baseline instead).",
            "default": "tripadvisor-reputation-state"
          },
          "eventTypes": {
            "title": "Event types to emit",
            "type": "array",
            "description": "Filter which typed events to emit. Leave empty to emit ALL event types. Valid values: 'new_review' (any new review since last run), 'complaint' (new review with rating <= negativeThreshold), 'rating_crossed' (overall rating crossed a threshold), 'rank_moved' (destination ranking changed by >= rankMovedMinDelta), 'review_velocity_spike' (review count jumped more than velocitySpikeMinDelta), 'owner_response_gap' (negative review unanswered for >= ownerResponseGapDays), 'review_count_milestone' (total review count hit a round number). Useful for routing: e.g. send only 'complaint' to Slack, send 'rating_crossed' to a PagerDuty webhook. Allowed values: new_review, complaint, rating_crossed, rank_moved, review_velocity_spike, owner_response_gap, review_count_milestone.",
            "items": {
              "type": "string"
            }
          },
          "negativeThreshold": {
            "title": "Negative review threshold (stars)",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Reviews with rating at or below this value are flagged as a 'complaint' event (in addition to the standard 'new_review' event). Default: 2. Set to 3 to also flag 3-star reviews. Set to 0 to disable complaint detection.",
            "default": 2
          },
          "ratingCrossedThresholds": {
            "title": "Rating thresholds to watch (e.g. 4.0, 3.5)",
            "type": "array",
            "description": "Emit a 'rating_crossed' event when the overall property rating crosses any of these values (in either direction — falling below or recovering above). Example: [4.0, 3.5] emits an event when a 4.1-star property drops to 3.9, or when a 3.8 recovers to 4.1. Leave empty to disable rating-crossing detection.",
            "items": {
              "type": "number"
            }
          },
          "rankMovedMinDelta": {
            "title": "Minimum rank change to trigger rank_moved event",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Emit a 'rank_moved' event when the property's destination ranking changes by at least this many positions. Default: 3 (so a shift from #10 to #12 triggers an event, but #10 to #11 does not). Set to 1 to catch every single-position move.",
            "default": 3
          },
          "velocitySpikeMinDelta": {
            "title": "New-reviews spike threshold (count)",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Emit a 'review_velocity_spike' event when more than this many NEW reviews appear in a single run. Default: 5 — useful for spotting viral moments, review-bombing attacks, or incentivized-review bursts. For properties that normally get 1-2 reviews/day, a value of 5 catches anomalies. For busy properties (100+ reviews/day), you may want 20-50.",
            "default": 5
          },
          "ownerResponseGapDays": {
            "title": "Owner-response SLA (days)",
            "minimum": 0,
            "maximum": 90,
            "type": "integer",
            "description": "Emit an 'owner_response_gap' event for each negative review (rating <= negativeThreshold) that has had NO management response for at least this many days. Default: 3. Helps hotel GMs hit their response-time KPI. Set to 0 to disable.",
            "default": 3
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify proxy configuration. The actor REQUIRES residential proxies for reliable access to TripAdvisor — datacenter IPs are not reliable. The recommended setting is useApifyProxy: true with proxyGroups: ['RESIDENTIAL']. If you leave this empty, the actor will attempt to use Apify's default residential proxy group automatically."
          },
          "maxPropertiesPerRun": {
            "title": "Max properties to process per run",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Maximum number of properties to monitor in a single run. Default: 50. Useful if you have a large watchlist but want to split runs for speed or cost control. Properties are processed in the order they appear in propertyUrls.",
            "default": 50
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}