{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/prismareviews/json-schema/prismareviews-location-schema.json",
  "title": "Location",
  "description": "One thing that receives reviews on one platform: a place, an app, a shop, a listing.",
  "x-generated": "2026-11-02",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/prismareviews-openapi.json#/components/schemas/Location",
  "type": "object",
  "required": [
    "id",
    "platform",
    "connection_id",
    "name",
    "address",
    "url",
    "external_id",
    "status",
    "last_synced_at",
    "next_sync_at",
    "review_link",
    "sync"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "Location ID (`loc_…`)."
    },
    "platform": {
      "$ref": "#/$defs/PlatformId"
    },
    "connection_id": {
      "type": "string",
      "description": "The connection that created it (`con_…`)."
    },
    "name": {
      "type": "string",
      "description": "Name on the platform. For listing URL platforms, the listing URL."
    },
    "address": {
      "type": [
        "string",
        "null"
      ],
      "description": "Address for places. For App Store apps, the bundle ID."
    },
    "url": {
      "type": [
        "string",
        "null"
      ],
      "description": "Public page of the location, app or listing, when known."
    },
    "external_id": {
      "type": "string",
      "description": "The platform's own ID."
    },
    "status": {
      "type": "string",
      "enum": [
        "active",
        "disconnected"
      ]
    },
    "last_synced_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "Last time Prisma checked it for reviews. `null` until the first sync finishes."
    },
    "next_sync_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When the next check is scheduled. `null` once disconnected."
    },
    "review_link": {
      "description": "The link to send customers to ask for a review (email, SMS, QR code). `type: \"write_review\"` opens the platform's review form; `listing` is the public page with its review button. `null` where only verified buyers or guests can review (Booking.com, eBay, Etsy, shop-review apps).",
      "anyOf": [
        {
          "type": "object",
          "required": [
            "url",
            "type"
          ],
          "properties": {
            "url": {
              "type": "string",
              "description": "The link."
            },
            "type": {
              "type": "string",
              "enum": [
                "write_review",
                "listing"
              ]
            }
          }
        },
        {
          "type": "null"
        }
      ]
    },
    "sync": {
      "type": "object",
      "required": [
        "consecutive_failures",
        "last_error",
        "last_error_at"
      ],
      "description": "Sync health: tells \"no new reviews\" apart from \"the check failed\". After 3 failed checks in a row Prisma sends `location.sync_failed`, and `location.sync_recovered` on the next successful one.",
      "properties": {
        "consecutive_failures": {
          "type": "integer",
          "description": "Checks in a row that failed. `0` after a successful check."
        },
        "last_error": {
          "type": [
            "string",
            "null"
          ],
          "description": "The last failed check's error (up to 300 characters, never keys or tokens). Kept after a recovery, as history."
        },
        "last_error_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "When the last check failed."
        }
      }
    }
  },
  "$defs": {
    "PlatformId": {
      "type": "string",
      "enum": [
        "google",
        "app_store",
        "google_play",
        "judge_me",
        "trustpilot",
        "google_maps",
        "yelp",
        "tripadvisor",
        "booking",
        "yotpo",
        "reviews_io",
        "g2",
        "ebay",
        "etsy",
        "steam",
        "okendo",
        "feefo",
        "trusted_shops",
        "ekomi",
        "loox",
        "proven_expert",
        "shopper_approved",
        "wordpress",
        "appexchange",
        "facebook",
        "opentable",
        "doordash",
        "angi",
        "checkatrade",
        "avvo",
        "capterra",
        "apartments",
        "gartner",
        "healthgrades",
        "vitals",
        "classpass"
      ],
      "description": "Platform ID.\n\n| ID | Platform | Connects with | Replies |\n| --- | --- | --- | --- |\n| `google` | Google Business Profile | oauth | by API |\n| `app_store` | App Store | credentials | by API |\n| `google_play` | Google Play | credentials | by API |\n| `judge_me` | Judge.me | credentials | by API |\n| `trustpilot` | Trustpilot | oauth | by API |\n| `google_maps` | Google Maps | listing_url | read only |\n| `yelp` | Yelp | listing_url | read only |\n| `tripadvisor` | Tripadvisor | listing_url | read only |\n| `booking` | Booking.com | listing_url | read only |\n| `yotpo` | Yotpo | credentials | read only |\n| `reviews_io` | REVIEWS.io | credentials | read only |\n| `g2` | G2 | credentials | read only |\n| `ebay` | eBay | oauth | by API |\n| `etsy` | Etsy | listing_url | read only |\n| `steam` | Steam | listing_url | read only |\n| `okendo` | Okendo | credentials | read only |\n| `feefo` | Feefo | credentials | read only |\n| `trusted_shops` | Trusted Shops | credentials | by API |\n| `ekomi` | eKomi | credentials | by API |\n| `loox` | Loox | credentials | read only |\n| `proven_expert` | ProvenExpert | credentials | read only |\n| `shopper_approved` | Shopper Approved | credentials | read only |\n| `wordpress` | WordPress.org | listing_url | read only |\n| `appexchange` | Salesforce AppExchange | listing_url | read only |\n| `facebook` | Facebook | listing_url | read only |\n| `opentable` | OpenTable | listing_url | read only |\n| `doordash` | DoorDash | listing_url | read only |\n| `angi` | Angi | listing_url | read only |\n| `checkatrade` | Checkatrade | listing_url | read only |\n| `avvo` | Avvo | listing_url | read only |\n| `capterra` | Capterra | listing_url | read only |\n| `apartments` | Apartments.com | listing_url | read only |\n| `gartner` | Gartner Peer Insights | listing_url | read only |\n| `healthgrades` | Healthgrades | listing_url | read only |\n| `vitals` | Vitals | listing_url | read only |\n| `classpass` | ClassPass | listing_url | read only |"
    }
  }
}