{
 "title": "Harthliving OTA — data catalog",
 "version": 2,
 "site": "https://harthliving-ota.pages.dev",
 "built": "29/09/2026 09:28",
 "description": "Machine-readable directory of every dataset on the OTA Portal of Harth Living (7 villas/apartments in Đà Nẵng; Booking.com · Agoda · Airbnb · PriceLabs). Find a dataset here, then read its json_url or csv_url.",
 "how_to_use": [
  "Route a question with /ai-index.json (topic → datasets) or search this catalog by keywords/category/platform.",
  "Read the dataset's json_url (or csv_url). Prefer JSON/CSV over HTML pages.",
  "Each field has type + description; `filled` = non-empty values. Use /llms-full.txt only for broad context."
 ],
 "conventions": {
  "null": "not read / not available in the source",
  "false": "read and confirmed false",
  "money": "integer VND unless the field says otherwise",
  "date": "ISO YYYY-MM-DD",
  "privacy": "no guest names, door codes, Wi-Fi passwords or session tokens anywhere on this site"
 },
 "categories": [
  "competitors",
  "funnel",
  "guides",
  "issues",
  "listing_settings",
  "messaging",
  "meta",
  "payments",
  "performance",
  "pricing",
  "promotions",
  "properties",
  "reports",
  "reservations",
  "reviews",
  "search_ranking"
 ],
 "platforms": [
  "agoda",
  "airbnb",
  "all",
  "booking",
  "pricelabs"
 ],
 "documents": [
  {
   "id": "agoda_promotions_guide",
   "name": "Agoda Promotions — groups → promotions → label yes/no → conditions",
   "json_url": "https://harthliving-ota.pages.dev/api/guidebook/agoda/promotions.json",
   "markdown_url": "https://harthliving-ota.pages.dev/api/guidebook/agoda/promotions.md",
   "html_url": "https://harthliving-ota.pages.dev/guide/agoda/promotions/",
   "updated_at": "2026-09-28"
  },
  {
   "id": "guidebook_index",
   "name": "Guidebook — every guide by platform with HTML + Markdown URLs",
   "json_url": "https://harthliving-ota.pages.dev/api/guidebook/index.json",
   "html_url": "https://harthliving-ota.pages.dev/guide/"
  }
 ],
 "datasets": [
  {
   "id": "fact_metrics",
   "name": "Booking.com performance metrics",
   "description": "Long-format metric observations per property: monthly revenue, ADR and room nights back to 2023-06, plus 90-day search/booking metrics, review score and rank in city.",
   "category": "performance",
   "subcategory": null,
   "platform": "booking",
   "grain": "one metric value × property × period × crawl date",
   "keywords": [
    "booking",
    "revenue",
    "adr",
    "room nights",
    "occupancy",
    "monthly revenue",
    "doanh thu",
    "gia trung binh",
    "dem ban",
    "rank in city",
    "page score",
    "conversion"
   ],
   "derived": false,
   "rows": 1870,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 1870,
     "unique": 2,
     "example": "2026-09-23"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 1870,
     "unique": 1,
     "example": "booking"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 1870,
     "unique": 7,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 1870,
     "unique": 7,
     "example": "13311503"
    },
    {
     "name": "metric",
     "type": "string",
     "description": "Metric name (snake_case), e.g. revenue, adr, room_nights, bookings, conversion",
     "filled": 1870,
     "unique": 12,
     "example": "adr"
    },
    {
     "name": "value",
     "type": "number",
     "description": "Metric value; unit given in `unit`. -1 from Booking means 'no data', not zero",
     "filled": 1870,
     "unique": 136,
     "example": "0"
    },
    {
     "name": "unit",
     "type": "string",
     "description": "Unit of `value`: VND, nights, count, ratio, position, score_10",
     "filled": 1870,
     "unique": 6,
     "example": "VND"
    },
    {
     "name": "peer_value",
     "type": "number",
     "description": "Booking's peer-group benchmark for the same metric",
     "filled": 88,
     "unique": 33,
     "example": "0.0054"
    },
    {
     "name": "period_start",
     "type": "date",
     "description": "Start of the period the value refers to",
     "filled": 1850,
     "unique": 43,
     "example": "2015-01-01"
    },
    {
     "name": "period_end",
     "type": "date",
     "description": "End of the period the value refers to",
     "filled": 1870,
     "unique": 41,
     "example": "2023-06-30"
    },
    {
     "name": "window",
     "type": "string",
     "description": "Window of the value: 1m (one month) · 90d · 12m · alltime · lifetime",
     "filled": 1870,
     "unique": 5,
     "example": "12m"
    },
    {
     "name": "basis",
     "type": "string",
     "description": "How the value is computed: stay_date · report_window · cumulative",
     "filled": 1870,
     "unique": 3,
     "example": "cumulative"
    },
    {
     "name": "source_page",
     "type": "string",
     "description": "Booking extranet page the value was read from",
     "filled": 1870,
     "unique": 3,
     "example": "reviews.html"
    },
    {
     "name": "source_field",
     "type": "string",
     "description": "Field path inside the page payload",
     "filled": 1870,
     "unique": 14,
     "example": "competitiveSetLeaderboard.rankingInUfi"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics/fact_metrics.csv",
   "json_url": "/data/fact-metrics.json",
   "csv_url": "/data/fact-metrics.csv",
   "html_url": "/library/data/fact-metrics/",
   "key": "fact-metrics",
   "title": "fact_metrics",
   "channel": "Booking",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/fact-metrics.csv",
    "json": "/data/fact-metrics.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 1870,
     "unique": 2,
     "sample": "2026-09-23, 2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 1870,
     "unique": 1,
     "sample": "booking"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 1870,
     "unique": 7,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 1870,
     "unique": 7,
     "sample": "13311503, 14740288, 14756473"
    },
    {
     "name": "metric",
     "type": "chữ",
     "filled": 1870,
     "unique": 12,
     "sample": "adr, bookings, conversion"
    },
    {
     "name": "value",
     "type": "số",
     "filled": 1870,
     "unique": 136,
     "sample": "0, 0.0, 0.0042"
    },
    {
     "name": "unit",
     "type": "chữ",
     "filled": 1870,
     "unique": 6,
     "sample": "VND, count, nights"
    },
    {
     "name": "peer_value",
     "type": "số",
     "filled": 88,
     "unique": 33,
     "sample": "0.0054, 0.0064, 0.0102"
    },
    {
     "name": "period_start",
     "type": "ngày",
     "filled": 1850,
     "unique": 43,
     "sample": "2015-01-01, 2023-06-01, 2023-07-01"
    },
    {
     "name": "period_end",
     "type": "ngày",
     "filled": 1870,
     "unique": 41,
     "sample": "2023-06-30, 2023-07-31, 2023-08-31"
    },
    {
     "name": "window",
     "type": "chữ",
     "filled": 1870,
     "unique": 5,
     "sample": "12m, 1m, 90d"
    },
    {
     "name": "basis",
     "type": "chữ",
     "filled": 1870,
     "unique": 3,
     "sample": "cumulative, report_window, stay_date"
    },
    {
     "name": "source_page",
     "type": "chữ",
     "filled": 1870,
     "unique": 3,
     "sample": "reviews.html, showrank.html, statistics/sales_insights.html"
    },
    {
     "name": "source_field",
     "type": "chữ",
     "filled": 1870,
     "unique": 14,
     "sample": "competitiveSetLeaderboard.rankingInUfi, conversionOverviewSummary.bookings, conv"
    }
   ]
  },
  {
   "id": "fact_reservations",
   "name": "Booking.com reservations",
   "description": "Every Booking.com reservation from the group page (full history): booking date, stay dates, nights, status, price and commission. No guest names.",
   "category": "reservations",
   "subcategory": null,
   "platform": "booking",
   "grain": "one reservation (deduplicate by reservation_id, keep latest snapshot_date)",
   "keywords": [
    "booking",
    "reservation",
    "booking list",
    "don dat phong",
    "cancellation",
    "huy phong",
    "no show",
    "commission",
    "hoa hong",
    "price"
   ],
   "derived": false,
   "rows": 189,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 189,
     "unique": 1,
     "example": "2026-09-26"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 189,
     "unique": 1,
     "example": "booking"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 189,
     "unique": 7,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 189,
     "unique": 7,
     "example": "13311503"
    },
    {
     "name": "reservation_id",
     "type": "string",
     "description": "Booking.com reservation number",
     "filled": 189,
     "unique": 189,
     "example": "4301415387"
    },
    {
     "name": "booked_at",
     "type": "date",
     "description": "Date the reservation was made",
     "filled": 189,
     "unique": 152,
     "example": "2024-12-25"
    },
    {
     "name": "checkin",
     "type": "date",
     "description": "Check-in date",
     "filled": 189,
     "unique": 136,
     "example": "2025-01-09"
    },
    {
     "name": "checkout",
     "type": "date",
     "description": "Check-out date",
     "filled": 189,
     "unique": 146,
     "example": "2025-01-20"
    },
    {
     "name": "nights",
     "type": "integer",
     "description": "Number of nights",
     "filled": 189,
     "unique": 23,
     "example": "1"
    },
    {
     "name": "status",
     "type": "string",
     "description": "Reservation status: ok · cancelled_by_guest · cancelled_by_hotel · no_show · fraudulent",
     "filled": 189,
     "unique": 5,
     "example": "cancelled_by_guest"
    },
    {
     "name": "price_vnd",
     "type": "integer",
     "description": "Reservation price in VND",
     "filled": 189,
     "unique": 70,
     "example": "0"
    },
    {
     "name": "currency",
     "type": "string",
     "description": "Currency code of money columns (VND)",
     "filled": 189,
     "unique": 1,
     "example": "VND"
    },
    {
     "name": "commission_vnd",
     "type": "integer",
     "description": "Commission charged by Booking.com in VND",
     "filled": 189,
     "unique": 70,
     "example": "0"
    },
    {
     "name": "adults",
     "type": "integer",
     "description": "Number of adult guests",
     "filled": 189,
     "unique": 9,
     "example": "1"
    },
    {
     "name": "children",
     "type": "integer",
     "description": "Number of children",
     "filled": 189,
     "unique": 5,
     "example": "0"
    },
    {
     "name": "rooms",
     "type": "string",
     "description": "Room type booked × count, e.g. 'Room 305×1' (empty when not captured)",
     "filled": 165,
     "unique": 5,
     "example": "One-Bedroom Apartment×1"
    },
    {
     "name": "is_genius",
     "type": "boolean",
     "description": "1 if booked by a Genius member at Genius rate",
     "filled": 189,
     "unique": 1,
     "example": "0"
    },
    {
     "name": "is_last_minute",
     "type": "boolean",
     "description": "1 if flagged last-minute by Booking",
     "filled": 165,
     "unique": 1,
     "example": "0"
    },
    {
     "name": "window_from",
     "type": "date",
     "description": "Start of the query window used when the reservation list was read",
     "filled": 189,
     "unique": 1,
     "example": "2023-01-01"
    },
    {
     "name": "window_to",
     "type": "date",
     "description": "End of the query window used when the reservation list was read",
     "filled": 189,
     "unique": 1,
     "example": "2027-12-31"
    },
    {
     "name": "source_file",
     "type": "string",
     "description": "Raw payload file the row was extracted from (for audit)",
     "filled": 189,
     "unique": 1,
     "example": "groups/reservations · searchReservations ARRIVAL · 7 trang×30"
    }
   ],
   "updated_at": "2026-09-26",
   "source": "vault/18-ota-listings/metrics/fact_reservations.csv",
   "json_url": "/data/fact-reservations.json",
   "csv_url": "/data/fact-reservations.csv",
   "html_url": "/library/data/fact-reservations/",
   "key": "fact-reservations",
   "title": "fact_reservations",
   "channel": "Booking",
   "read_date": "2026-09-26",
   "download": {
    "csv": "/data/fact-reservations.csv",
    "json": "/data/fact-reservations.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 189,
     "unique": 1,
     "sample": "2026-09-26"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 189,
     "unique": 1,
     "sample": "booking"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 189,
     "unique": 7,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 189,
     "unique": 7,
     "sample": "13311503, 14740288, 14756473"
    },
    {
     "name": "reservation_id",
     "type": "số",
     "filled": 189,
     "unique": 189,
     "sample": "4301415387, 4360722374, 4395038389"
    },
    {
     "name": "booked_at",
     "type": "ngày",
     "filled": 189,
     "unique": 152,
     "sample": "2024-12-25, 2024-12-30, 2025-01-01"
    },
    {
     "name": "checkin",
     "type": "ngày",
     "filled": 189,
     "unique": 136,
     "sample": "2025-01-09, 2025-02-12, 2025-02-14"
    },
    {
     "name": "checkout",
     "type": "ngày",
     "filled": 189,
     "unique": 146,
     "sample": "2025-01-20, 2025-02-16, 2025-02-20"
    },
    {
     "name": "nights",
     "type": "số",
     "filled": 189,
     "unique": 23,
     "sample": "1, 10, 11"
    },
    {
     "name": "status",
     "type": "chữ",
     "filled": 189,
     "unique": 5,
     "sample": "cancelled_by_guest, cancelled_by_hotel, fraudulent"
    },
    {
     "name": "price_vnd",
     "type": "số",
     "filled": 189,
     "unique": 70,
     "sample": "0, 10018964, 10712002"
    },
    {
     "name": "currency",
     "type": "chữ",
     "filled": 189,
     "unique": 1,
     "sample": "VND"
    },
    {
     "name": "commission_vnd",
     "type": "số",
     "filled": 189,
     "unique": 70,
     "sample": "0, 1020000, 1059188"
    },
    {
     "name": "adults",
     "type": "số",
     "filled": 189,
     "unique": 9,
     "sample": "1, 10, 2"
    },
    {
     "name": "children",
     "type": "số",
     "filled": 189,
     "unique": 5,
     "sample": "0, 1, 2"
    },
    {
     "name": "rooms",
     "type": "chữ",
     "filled": 165,
     "unique": 5,
     "sample": "One-Bedroom Apartment×1, Room 305×1, Room 404×1"
    },
    {
     "name": "is_genius",
     "type": "số",
     "filled": 189,
     "unique": 1,
     "sample": "0"
    },
    {
     "name": "is_last_minute",
     "type": "số",
     "filled": 165,
     "unique": 1,
     "sample": "0"
    },
    {
     "name": "window_from",
     "type": "ngày",
     "filled": 189,
     "unique": 1,
     "sample": "2023-01-01"
    },
    {
     "name": "window_to",
     "type": "ngày",
     "filled": 189,
     "unique": 1,
     "sample": "2027-12-31"
    },
    {
     "name": "source_file",
     "type": "chữ",
     "filled": 189,
     "unique": 1,
     "sample": "groups/reservations · searchReservations ARRIVAL · 7 trang×30"
    }
   ]
  },
  {
   "id": "fact_funnel",
   "name": "Booking.com funnel",
   "description": "Search impressions → page views → bookings with peer benchmarks, per property and period (30/60/90/365 days; periods overlap).",
   "category": "funnel",
   "subcategory": null,
   "platform": "booking",
   "grain": "one property × period × crawl date",
   "keywords": [
    "booking",
    "funnel",
    "ctr",
    "conversion",
    "impressions",
    "page views",
    "pheu",
    "luot xem",
    "ty le chuyen doi"
   ],
   "derived": false,
   "rows": 35,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 35,
     "unique": 2,
     "example": "2026-09-23"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 35,
     "unique": 1,
     "example": "booking"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 35,
     "unique": 7,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 35,
     "unique": 7,
     "example": "13311503"
    },
    {
     "name": "period_days",
     "type": "integer",
     "description": "Length of the funnel period (30/60/90/365). Periods overlap — do not subtract them",
     "filled": 35,
     "unique": 4,
     "example": "30"
    },
    {
     "name": "period_label",
     "type": "string",
     "description": "Reporting period label as shown by the platform",
     "filled": 35,
     "unique": 5,
     "example": "Last 30 days"
    },
    {
     "name": "window_start",
     "type": "date",
     "description": "Start of the funnel window",
     "filled": 7,
     "unique": 1,
     "example": "2026-08-17"
    },
    {
     "name": "window_end",
     "type": "date",
     "description": "End of the funnel window",
     "filled": 7,
     "unique": 1,
     "example": "2026-09-12"
    },
    {
     "name": "window_days",
     "type": "string",
     "description": "Days in the window; a range like '27–31' when the window was back-derived",
     "filled": 35,
     "unique": 5,
     "example": "27–31"
    },
    {
     "name": "lag_days",
     "type": "integer",
     "description": "Reporting lag of the dashboard in days (~7–11) for back-derived rows",
     "filled": 7,
     "unique": 1,
     "example": "7"
    },
    {
     "name": "window_method",
     "type": "string",
     "description": "declared-by-booking · derived-exact · derived-approx · unknown",
     "filled": 35,
     "unique": 2,
     "example": "declared-by-booking"
    },
    {
     "name": "window_mismatch",
     "type": "integer",
     "description": "1 if the derived window disagrees with the declared one",
     "filled": 7,
     "unique": 1,
     "example": "0"
    },
    {
     "name": "window_ambiguity_days",
     "type": "integer",
     "description": "Uncertainty of the derived window in days",
     "filled": 7,
     "unique": 1,
     "example": "4"
    },
    {
     "name": "search_impressions",
     "type": "number",
     "description": "Times the property appeared in search results",
     "filled": 35,
     "unique": 33,
     "example": "10260"
    },
    {
     "name": "search_impressions_peer",
     "type": "number",
     "description": "Peer-group benchmark for search_impressions",
     "filled": 35,
     "unique": 35,
     "example": "103436.93622056446"
    },
    {
     "name": "page_views",
     "type": "number",
     "description": "Property page views",
     "filled": 35,
     "unique": 33,
     "example": "1171"
    },
    {
     "name": "page_views_peer",
     "type": "number",
     "description": "Peer-group benchmark for page_views",
     "filled": 35,
     "unique": 35,
     "example": "1123.7177832832172"
    },
    {
     "name": "bookings",
     "type": "number",
     "description": "Bookings in the period",
     "filled": 35,
     "unique": 17,
     "example": "0"
    },
    {
     "name": "bookings_peer",
     "type": "number",
     "description": "Peer-group benchmark for bookings",
     "filled": 35,
     "unique": 32,
     "example": "1.0"
    },
    {
     "name": "ctr",
     "type": "number",
     "description": "Click-through rate (search → property page), ratio",
     "filled": 35,
     "unique": 33,
     "example": "0.004828592061851291"
    },
    {
     "name": "ctr_peer",
     "type": "number",
     "description": "Peer-group benchmark for ctr",
     "filled": 35,
     "unique": 35,
     "example": "0.01017526739514728"
    },
    {
     "name": "conversion",
     "type": "number",
     "description": "Conversion rate (page view → booking), ratio",
     "filled": 35,
     "unique": 27,
     "example": "0"
    },
    {
     "name": "conversion_peer",
     "type": "number",
     "description": "Peer-group benchmark for conversion",
     "filled": 35,
     "unique": 35,
     "example": "0.0054"
    },
    {
     "name": "rank_in_city",
     "type": "integer",
     "description": "Booking's own rank of the property in the city",
     "filled": 7,
     "unique": 7,
     "example": "1039"
    },
    {
     "name": "rank_total",
     "type": "integer",
     "description": "Number of properties in the ranking that rank_in_city is out of",
     "filled": 7,
     "unique": 1,
     "example": "3241"
    },
    {
     "name": "property_page_score",
     "type": "number",
     "description": "Property page score (content completeness), ratio",
     "filled": 7,
     "unique": 3,
     "example": "0.7011"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics/fact_funnel.csv",
   "json_url": "/data/fact-funnel.json",
   "csv_url": "/data/fact-funnel.csv",
   "html_url": "/library/data/fact-funnel/",
   "key": "fact-funnel",
   "title": "fact_funnel",
   "channel": "Booking",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/fact-funnel.csv",
    "json": "/data/fact-funnel.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 35,
     "unique": 2,
     "sample": "2026-09-23, 2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 35,
     "unique": 1,
     "sample": "booking"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 35,
     "unique": 7,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 35,
     "unique": 7,
     "sample": "13311503, 14740288, 14756473"
    },
    {
     "name": "period_days",
     "type": "số",
     "filled": 35,
     "unique": 4,
     "sample": "30, 365, 60"
    },
    {
     "name": "period_label",
     "type": "chữ",
     "filled": 35,
     "unique": 5,
     "sample": "Last 30 days, Last 30 days (dò ngược), Last 365 days"
    },
    {
     "name": "window_start",
     "type": "ngày",
     "filled": 7,
     "unique": 1,
     "sample": "2026-08-17"
    },
    {
     "name": "window_end",
     "type": "ngày",
     "filled": 7,
     "unique": 1,
     "sample": "2026-09-12"
    },
    {
     "name": "window_days",
     "type": "chữ",
     "filled": 35,
     "unique": 5,
     "sample": "27–31, 30, 365"
    },
    {
     "name": "lag_days",
     "type": "số",
     "filled": 7,
     "unique": 1,
     "sample": "7"
    },
    {
     "name": "window_method",
     "type": "chữ",
     "filled": 35,
     "unique": 2,
     "sample": "declared-by-booking, derived-exact"
    },
    {
     "name": "window_mismatch",
     "type": "số",
     "filled": 7,
     "unique": 1,
     "sample": "0"
    },
    {
     "name": "window_ambiguity_days",
     "type": "số",
     "filled": 7,
     "unique": 1,
     "sample": "4"
    },
    {
     "name": "search_impressions",
     "type": "số",
     "filled": 35,
     "unique": 33,
     "sample": "10260, 10260.0, 10907"
    },
    {
     "name": "search_impressions_peer",
     "type": "số",
     "filled": 35,
     "unique": 35,
     "sample": "103436.93622056446, 133694.66691032506, 13803.906670503648"
    },
    {
     "name": "page_views",
     "type": "số",
     "filled": 35,
     "unique": 33,
     "sample": "1171, 138, 138.0"
    },
    {
     "name": "page_views_peer",
     "type": "số",
     "filled": 35,
     "unique": 35,
     "sample": "1123.7177832832172, 1168.2174136073852, 1456.3790318649712"
    },
    {
     "name": "bookings",
     "type": "số",
     "filled": 35,
     "unique": 17,
     "sample": "0, 0.0, 1"
    },
    {
     "name": "bookings_peer",
     "type": "số",
     "filled": 35,
     "unique": 32,
     "sample": "1.0, 1.1190932930429576, 1.120197087522092"
    },
    {
     "name": "ctr",
     "type": "số",
     "filled": 35,
     "unique": 33,
     "sample": "0.004828592061851291, 0.006555975201311195, 0.007849588719153937"
    },
    {
     "name": "ctr_peer",
     "type": "số",
     "filled": 35,
     "unique": 35,
     "sample": "0.01017526739514728, 0.0102, 0.010467976931426889"
    },
    {
     "name": "conversion",
     "type": "số",
     "filled": 35,
     "unique": 27,
     "sample": "0, 0.0, 0.0012953367875647669"
    },
    {
     "name": "conversion_peer",
     "type": "số",
     "filled": 35,
     "unique": 35,
     "sample": "0.0054, 0.005449671638907308, 0.0064"
    },
    {
     "name": "rank_in_city",
     "type": "số",
     "filled": 7,
     "unique": 7,
     "sample": "1039, 1228, 1483"
    },
    {
     "name": "rank_total",
     "type": "số",
     "filled": 7,
     "unique": 1,
     "sample": "3241"
    },
    {
     "name": "property_page_score",
     "type": "số",
     "filled": 7,
     "unique": 3,
     "sample": "0.7011, 0.7215, 1.0"
    }
   ]
  },
  {
   "id": "fact_reviews",
   "name": "Booking.com reviews",
   "description": "Booking.com guest reviews with overall score and six sub-scores, review text, country and language. No reviewer names.",
   "category": "reviews",
   "subcategory": null,
   "platform": "booking",
   "grain": "one review",
   "keywords": [
    "booking",
    "review",
    "reviews",
    "score",
    "danh gia",
    "diem review",
    "guest feedback"
   ],
   "derived": false,
   "rows": 16,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 16,
     "unique": 1,
     "example": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 16,
     "unique": 1,
     "example": "booking"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 16,
     "unique": 3,
     "example": "41lehycat"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 16,
     "unique": 3,
     "example": "13311503"
    },
    {
     "name": "review_id",
     "type": "string",
     "description": "Review ID on the platform",
     "filled": 16,
     "unique": 16,
     "example": "5124377906"
    },
    {
     "name": "completed_at",
     "type": "string",
     "description": "Date the review was submitted",
     "filled": 16,
     "unique": 16,
     "example": "2025-01-26 03:21:16"
    },
    {
     "name": "stay_status",
     "type": "string",
     "description": "Stay status of the reviewer (stayed)",
     "filled": 16,
     "unique": 1,
     "example": "stayed"
    },
    {
     "name": "country",
     "type": "string",
     "description": "Guest country",
     "filled": 16,
     "unique": 9,
     "example": "au"
    },
    {
     "name": "language",
     "type": "string",
     "description": "Language code of the review",
     "filled": 16,
     "unique": 5,
     "example": "en"
    },
    {
     "name": "score",
     "type": "number",
     "description": "Overall review score given by the guest",
     "filled": 16,
     "unique": 4,
     "example": "10.0"
    },
    {
     "name": "clean",
     "type": "number",
     "description": "Cleanliness sub-score",
     "filled": 16,
     "unique": 2,
     "example": "10.0"
    },
    {
     "name": "comfort",
     "type": "number",
     "description": "Comfort sub-score",
     "filled": 16,
     "unique": 3,
     "example": "10.0"
    },
    {
     "name": "location",
     "type": "number",
     "description": "Location sub-score",
     "filled": 16,
     "unique": 2,
     "example": "10.0"
    },
    {
     "name": "services",
     "type": "number",
     "description": "Facilities/services sub-score",
     "filled": 16,
     "unique": 2,
     "example": "10.0"
    },
    {
     "name": "staff",
     "type": "number",
     "description": "Staff sub-score",
     "filled": 16,
     "unique": 3,
     "example": "0.0"
    },
    {
     "name": "value",
     "type": "number",
     "description": "Value-for-money sub-score",
     "filled": 16,
     "unique": 2,
     "example": "10.0"
    },
    {
     "name": "title",
     "type": "string",
     "description": "Review title",
     "filled": 6,
     "unique": 6,
     "example": "Despite of those small detailed obstacles we still think the apparentment and it"
    },
    {
     "name": "positive",
     "type": "string",
     "description": "Positive review text",
     "filled": 11,
     "unique": 11,
     "example": "Great host"
    },
    {
     "name": "negative",
     "type": "string",
     "description": "Negative review text",
     "filled": 7,
     "unique": 7,
     "example": "Dirty mirrows and dust in the corners of the doors and A/C holes"
    },
    {
     "name": "has_reply",
     "type": "boolean",
     "description": "1 if the host replied",
     "filled": 16,
     "unique": 1,
     "example": "0"
    },
    {
     "name": "anonymous",
     "type": "boolean",
     "description": "1 if the reviewer is anonymous",
     "filled": 16,
     "unique": 1,
     "example": "0"
    },
    {
     "name": "source_file",
     "type": "string",
     "description": "Raw payload file the row was extracted from (for audit)",
     "filled": 16,
     "unique": 4,
     "example": "01-admin.booking.com_hotel_hoteladmin_extranet__006-review_fetch_reviews.json.gz"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics/fact_reviews.csv",
   "json_url": "/data/fact-reviews.json",
   "csv_url": "/data/fact-reviews.csv",
   "html_url": "/library/data/fact-reviews/",
   "key": "fact-reviews",
   "title": "fact_reviews",
   "channel": "Booking",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/fact-reviews.csv",
    "json": "/data/fact-reviews.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 16,
     "unique": 1,
     "sample": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 16,
     "unique": 1,
     "sample": "booking"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 16,
     "unique": 3,
     "sample": "41lehycat, alacarte305, alacarte502"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 16,
     "unique": 3,
     "sample": "13311503, 14756473, 15668481"
    },
    {
     "name": "review_id",
     "type": "số",
     "filled": 16,
     "unique": 16,
     "sample": "5124377906, 5131576150, 5145227309"
    },
    {
     "name": "completed_at",
     "type": "ngày",
     "filled": 16,
     "unique": 16,
     "sample": "2025-01-26 03:21:16, 2025-02-19 13:48:26, 2025-04-09 04:43:27"
    },
    {
     "name": "stay_status",
     "type": "chữ",
     "filled": 16,
     "unique": 1,
     "sample": "stayed"
    },
    {
     "name": "country",
     "type": "chữ",
     "filled": 16,
     "unique": 9,
     "sample": "au, ca, de"
    },
    {
     "name": "language",
     "type": "chữ",
     "filled": 16,
     "unique": 5,
     "sample": "en, ja, ru"
    },
    {
     "name": "score",
     "type": "số",
     "filled": 16,
     "unique": 4,
     "sample": "10.0, 7.0, 8.0"
    },
    {
     "name": "clean",
     "type": "số",
     "filled": 16,
     "unique": 2,
     "sample": "10.0, 7.5"
    },
    {
     "name": "comfort",
     "type": "số",
     "filled": 16,
     "unique": 3,
     "sample": "10.0, 5.0, 7.5"
    },
    {
     "name": "location",
     "type": "số",
     "filled": 16,
     "unique": 2,
     "sample": "10.0, 7.5"
    },
    {
     "name": "services",
     "type": "số",
     "filled": 16,
     "unique": 2,
     "sample": "10.0, 7.5"
    },
    {
     "name": "staff",
     "type": "số",
     "filled": 16,
     "unique": 3,
     "sample": "0.0, 10.0, 7.5"
    },
    {
     "name": "value",
     "type": "số",
     "filled": 16,
     "unique": 2,
     "sample": "10.0, 7.5"
    },
    {
     "name": "title",
     "type": "chữ",
     "filled": 6,
     "unique": 6,
     "sample": "Despite of those small detailed obstacles we still think the apparentment and it"
    },
    {
     "name": "positive",
     "type": "chữ",
     "filled": 11,
     "unique": 11,
     "sample": "Great host, near the beach and restaurants, I appreciate the host's responsivene"
    },
    {
     "name": "negative",
     "type": "chữ",
     "filled": 7,
     "unique": 7,
     "sample": "Dirty mirrows and dust in the corners of the doors and A/C holes, broken baseboa"
    },
    {
     "name": "has_reply",
     "type": "số",
     "filled": 16,
     "unique": 1,
     "sample": "0"
    },
    {
     "name": "anonymous",
     "type": "số",
     "filled": 16,
     "unique": 1,
     "sample": "0"
    },
    {
     "name": "source_file",
     "type": "chữ",
     "filled": 16,
     "unique": 4,
     "sample": "01-admin.booking.com_hotel_hoteladmin_extranet__006-review_fetch_reviews.json.gz"
    }
   ]
  },
  {
   "id": "booking_ranking",
   "name": "Booking.com public search rank",
   "description": "Where each property ranks in Booking.com public search results (clean context, Đà Nẵng), per search set and pass.",
   "category": "search_ranking",
   "subcategory": null,
   "platform": "booking",
   "grain": "one property × search × pass",
   "keywords": [
    "booking",
    "search rank",
    "ranking",
    "thu hang",
    "vi tri tim kiem",
    "visibility",
    "top"
   ],
   "derived": false,
   "rows": 72,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 72,
     "unique": 1,
     "example": "2026-09-26"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 72,
     "unique": 1,
     "example": "booking"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 72,
     "unique": 7,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 72,
     "unique": 7,
     "example": "13311503"
    },
    {
     "name": "search_id",
     "type": "string",
     "description": "Search set ID within one measurement run (A–D)",
     "filled": 72,
     "unique": 6,
     "example": "A"
    },
    {
     "name": "pass_no",
     "type": "integer",
     "description": "Measurement pass (1 or 2) — results reshuffle between passes, so ≥2 passes are taken",
     "filled": 72,
     "unique": 2,
     "example": "1"
    },
    {
     "name": "dest_id",
     "type": "string",
     "description": "Booking destination ID of the search (Đà Nẵng = -3712125)",
     "filled": 72,
     "unique": 1,
     "example": "-3712125"
    },
    {
     "name": "checkin",
     "type": "date",
     "description": "Check-in date",
     "filled": 72,
     "unique": 3,
     "example": "2026-10-01"
    },
    {
     "name": "checkout",
     "type": "date",
     "description": "Check-out date",
     "filled": 72,
     "unique": 4,
     "example": "2026-10-03"
    },
    {
     "name": "nights",
     "type": "integer",
     "description": "Number of nights",
     "filled": 72,
     "unique": 2,
     "example": "2"
    },
    {
     "name": "adults",
     "type": "integer",
     "description": "Number of adult guests",
     "filled": 72,
     "unique": 4,
     "example": "10"
    },
    {
     "name": "rooms",
     "type": "integer",
     "description": "Number of rooms",
     "filled": 72,
     "unique": 1,
     "example": "1"
    },
    {
     "name": "sort",
     "type": "string",
     "description": "Sort order used for the public search (platform default)",
     "filled": 72,
     "unique": 1,
     "example": "default_top_picks"
    },
    {
     "name": "personalization",
     "type": "string",
     "description": "Search context: clean_context / anon = no logged-in personalisation",
     "filled": 72,
     "unique": 1,
     "example": "clean_context"
    },
    {
     "name": "total_reported",
     "type": "integer",
     "description": "Total results Booking reports for the search",
     "filled": 72,
     "unique": 6,
     "example": "1090"
    },
    {
     "name": "rows_scanned",
     "type": "integer",
     "description": "Result rows read during the search",
     "filled": 72,
     "unique": 7,
     "example": "1060"
    },
    {
     "name": "unique_ids",
     "type": "integer",
     "description": "Distinct properties seen in the search results",
     "filled": 72,
     "unique": 12,
     "example": "359"
    },
    {
     "name": "rank",
     "type": "integer",
     "description": "Position of the property in public search results (first occurrence); empty when not ranked",
     "filled": 22,
     "unique": 18,
     "example": "102"
    },
    {
     "name": "page_approx",
     "type": "integer",
     "description": "Approximate results page of `rank`",
     "filled": 22,
     "unique": 8,
     "example": "19"
    },
    {
     "name": "pct_from_top",
     "type": "number",
     "description": "Rank as % of total results from the top (can exceed 100 % because of duplicate rows)",
     "filled": 22,
     "unique": 17,
     "example": "10.0"
    },
    {
     "name": "status",
     "type": "string",
     "description": "ranked · sold_out (not available / filtered out) · beyond_cap (available but beyond the ~1,000 visible rows) · not_found",
     "filled": 72,
     "unique": 3,
     "example": "beyond_cap"
    },
    {
     "name": "price_per_stay_vnd",
     "type": "integer",
     "description": "Price shown for the whole stay in VND",
     "filled": 26,
     "unique": 9,
     "example": "12378600"
    },
    {
     "name": "note",
     "type": "string",
     "description": "Free-text note from the measurement",
     "filled": 16,
     "unique": 5,
     "example": "villa"
    }
   ],
   "updated_at": "2026-09-26",
   "source": "vault/18-ota-listings/metrics/booking_ranking.csv",
   "json_url": "/data/booking-ranking.json",
   "csv_url": "/data/booking-ranking.csv",
   "html_url": "/library/data/booking-ranking/",
   "key": "booking-ranking",
   "title": "booking_ranking",
   "channel": "Booking",
   "read_date": "2026-09-26",
   "download": {
    "csv": "/data/booking-ranking.csv",
    "json": "/data/booking-ranking.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 72,
     "unique": 1,
     "sample": "2026-09-26"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 72,
     "unique": 1,
     "sample": "booking"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 72,
     "unique": 7,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 72,
     "unique": 7,
     "sample": "13311503, 14740288, 14756473"
    },
    {
     "name": "search_id",
     "type": "chữ",
     "filled": 72,
     "unique": 6,
     "sample": "A, B, C"
    },
    {
     "name": "pass_no",
     "type": "số",
     "filled": 72,
     "unique": 2,
     "sample": "1, 2"
    },
    {
     "name": "dest_id",
     "type": "số",
     "filled": 72,
     "unique": 1,
     "sample": "-3712125"
    },
    {
     "name": "checkin",
     "type": "ngày",
     "filled": 72,
     "unique": 3,
     "sample": "2026-10-01, 2026-10-11, 2026-10-22"
    },
    {
     "name": "checkout",
     "type": "ngày",
     "filled": 72,
     "unique": 4,
     "sample": "2026-10-03, 2026-10-13, 2026-10-14"
    },
    {
     "name": "nights",
     "type": "số",
     "filled": 72,
     "unique": 2,
     "sample": "2, 3"
    },
    {
     "name": "adults",
     "type": "số",
     "filled": 72,
     "unique": 4,
     "sample": "10, 2, 4"
    },
    {
     "name": "rooms",
     "type": "số",
     "filled": 72,
     "unique": 1,
     "sample": "1"
    },
    {
     "name": "sort",
     "type": "chữ",
     "filled": 72,
     "unique": 1,
     "sample": "default_top_picks"
    },
    {
     "name": "personalization",
     "type": "chữ",
     "filled": 72,
     "unique": 1,
     "sample": "clean_context"
    },
    {
     "name": "total_reported",
     "type": "số",
     "filled": 72,
     "unique": 6,
     "sample": "1090, 1096, 1245"
    },
    {
     "name": "rows_scanned",
     "type": "số",
     "filled": 72,
     "unique": 7,
     "sample": "1060, 1080, 1100"
    },
    {
     "name": "unique_ids",
     "type": "số",
     "filled": 72,
     "unique": 12,
     "sample": "359, 532, 788"
    },
    {
     "name": "rank",
     "type": "số",
     "filled": 22,
     "unique": 18,
     "sample": "102, 105, 111"
    },
    {
     "name": "page_approx",
     "type": "số",
     "filled": 22,
     "unique": 8,
     "sample": "19, 25, 32"
    },
    {
     "name": "pct_from_top",
     "type": "số",
     "filled": 22,
     "unique": 17,
     "sample": "10.0, 10.1, 10.2"
    },
    {
     "name": "status",
     "type": "chữ",
     "filled": 72,
     "unique": 3,
     "sample": "beyond_cap, ranked, sold_out"
    },
    {
     "name": "price_per_stay_vnd",
     "type": "số",
     "filled": 26,
     "unique": 9,
     "sample": "12378600, 4243200, 5376091"
    },
    {
     "name": "note",
     "type": "chữ",
     "filled": 16,
     "unique": 5,
     "sample": "villa, villa · UI thẻ thứ 101, villa · UI thẻ thứ 102"
    }
   ]
  },
  {
   "id": "booking_dim_property",
   "name": "Booking.com property list",
   "description": "The 7 properties on Booking.com: hotel_id, name, type, city, first observed selling date.",
   "category": "properties",
   "subcategory": null,
   "platform": "booking",
   "grain": "one property",
   "keywords": [
    "booking",
    "hotel id",
    "property list",
    "danh sach can",
    "active from"
   ],
   "derived": false,
   "rows": 7,
   "fields": [
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 7,
     "unique": 7,
     "example": "15nuocman5"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 7,
     "unique": 1,
     "example": "booking"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 7,
     "unique": 7,
     "example": "13311503"
    },
    {
     "name": "name",
     "type": "string",
     "description": "Property name as listed on the platform",
     "filled": 7,
     "unique": 7,
     "example": "1BR Studio A La Carte Hotel"
    },
    {
     "name": "property_type",
     "type": "string",
     "description": "villa or apartment",
     "filled": 7,
     "unique": 2,
     "example": "apartment"
    },
    {
     "name": "city",
     "type": "string",
     "description": "City of the property",
     "filled": 7,
     "unique": 1,
     "example": "Đà Nẵng"
    },
    {
     "name": "active_from",
     "type": "date",
     "description": "Earliest date the listing is known to be selling (upper bound observed from first booking/stay, or declared)",
     "filled": 7,
     "unique": 7,
     "example": "2025-01-01"
    },
    {
     "name": "active_from_basis",
     "type": "string",
     "description": "How active_from was determined (observed first booking / first stay night, or declared by platform email)",
     "filled": 7,
     "unique": 2,
     "example": "observed · đêm ở đầu tiên"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics/dim_property.csv",
   "json_url": "/data/booking-dim-property.json",
   "csv_url": "/data/booking-dim-property.csv",
   "html_url": "/library/data/booking-dim-property/",
   "key": "booking-dim-property",
   "title": "dim_property",
   "channel": "Booking",
   "read_date": "",
   "download": {
    "csv": "/data/booking-dim-property.csv",
    "json": "/data/booking-dim-property.json"
   },
   "columns": [
    {
     "name": "slug",
     "type": "chữ",
     "filled": 7,
     "unique": 7,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 7,
     "unique": 1,
     "sample": "booking"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 7,
     "unique": 7,
     "sample": "13311503, 14740288, 14756473"
    },
    {
     "name": "name",
     "type": "chữ",
     "filled": 7,
     "unique": 7,
     "sample": "1BR Studio A La Carte Hotel, 4BR Villa in An Thuong 500m to My Khe Beach, A La C"
    },
    {
     "name": "property_type",
     "type": "chữ",
     "filled": 7,
     "unique": 2,
     "sample": "apartment, villa"
    },
    {
     "name": "city",
     "type": "chữ",
     "filled": 7,
     "unique": 1,
     "sample": "Đà Nẵng"
    },
    {
     "name": "active_from",
     "type": "ngày",
     "filled": 7,
     "unique": 7,
     "sample": "2025-01-01, 2025-09-01, 2025-10-16"
    },
    {
     "name": "active_from_basis",
     "type": "chữ",
     "filled": 7,
     "unique": 2,
     "sample": "observed · đêm ở đầu tiên, observed · đơn đặt sớm nhất"
    }
   ]
  },
  {
   "id": "crawl_log",
   "name": "Booking.com crawl log",
   "description": "Log of each Booking.com metrics crawl run: date, rows written, pages read, tool.",
   "category": "meta",
   "subcategory": null,
   "platform": "booking",
   "grain": "one crawl run",
   "keywords": [
    "crawl log",
    "data freshness",
    "lan cao",
    "nhat ky cao"
   ],
   "derived": false,
   "rows": 6,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 6,
     "unique": 2,
     "example": "2026-09-23"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 6,
     "unique": 1,
     "example": "booking"
    },
    {
     "name": "properties",
     "type": "integer",
     "description": "Properties covered by the crawl run",
     "filled": 6,
     "unique": 2,
     "example": "0"
    },
    {
     "name": "rows",
     "type": "integer",
     "description": "Rows written by the crawl run",
     "filled": 6,
     "unique": 3,
     "example": "0"
    },
    {
     "name": "metrics",
     "type": "integer",
     "description": "Metrics captured per property",
     "filled": 6,
     "unique": 3,
     "example": "0"
    },
    {
     "name": "source_pages",
     "type": "string",
     "description": "Extranet pages read",
     "filled": 6,
     "unique": 3,
     "example": "reviews.html; statistics/sales_insights.html; showrank.html"
    },
    {
     "name": "tool",
     "type": "string",
     "description": "Script used for the crawl",
     "filled": 6,
     "unique": 2,
     "example": "scripts/chrome-grab.mjs"
    },
    {
     "name": "raw_dir",
     "type": "string",
     "description": "Folder of the raw payloads",
     "filled": 5,
     "unique": 4,
     "example": "_raw/2026-09-23-booking"
    },
    {
     "name": "note",
     "type": "string",
     "description": "Free-text note from the measurement",
     "filled": 6,
     "unique": 6,
     "example": "7/7 căn có số; thiếu nhóm: alacarte404=12m"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics/crawl_log.csv",
   "json_url": "/data/crawl-log.json",
   "csv_url": "/data/crawl-log.csv",
   "html_url": "/library/data/crawl-log/",
   "key": "crawl-log",
   "title": "crawl_log",
   "channel": "Booking",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/crawl-log.csv",
    "json": "/data/crawl-log.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 6,
     "unique": 2,
     "sample": "2026-09-23, 2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 6,
     "unique": 1,
     "sample": "booking"
    },
    {
     "name": "properties",
     "type": "số",
     "filled": 6,
     "unique": 2,
     "sample": "0, 7"
    },
    {
     "name": "rows",
     "type": "số",
     "filled": 6,
     "unique": 3,
     "sample": "0, 77, 858"
    },
    {
     "name": "metrics",
     "type": "số",
     "filled": 6,
     "unique": 3,
     "sample": "0, 12, 3"
    },
    {
     "name": "source_pages",
     "type": "chữ",
     "filled": 6,
     "unique": 3,
     "sample": "reviews.html; statistics/sales_insights.html; showrank.html, statistics/sales_in"
    },
    {
     "name": "tool",
     "type": "chữ",
     "filled": 6,
     "unique": 2,
     "sample": "scripts/chrome-grab.mjs, scripts/ota-metrics-crawl.py"
    },
    {
     "name": "raw_dir",
     "type": "chữ",
     "filled": 5,
     "unique": 4,
     "sample": "_raw/2026-09-23-booking, _raw/2026-09-23-booking-history, _raw/2026-09-24-bookin"
    },
    {
     "name": "note",
     "type": "chữ",
     "filled": 6,
     "unique": 6,
     "sample": "7/7 căn có số; thiếu nhóm: alacarte404=12m, CÀO BÙ alacarte404 (khối 12m) — THẤT"
    }
   ]
  },
  {
   "id": "fact_agoda_summary",
   "name": "Agoda sales summary",
   "description": "Agoda bookings, revenue and room nights per property and period code. period_type is only partly decoded — do not treat as a known window.",
   "category": "performance",
   "subcategory": null,
   "platform": "agoda",
   "grain": "one metric × property × period_type × crawl date",
   "keywords": [
    "agoda",
    "revenue",
    "bookings",
    "room nights",
    "doanh thu agoda",
    "summary"
   ],
   "derived": false,
   "rows": 84,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 84,
     "unique": 1,
     "example": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 84,
     "unique": 1,
     "example": "agoda"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 84,
     "unique": 7,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 84,
     "unique": 7,
     "example": "63382515"
    },
    {
     "name": "metric",
     "type": "string",
     "description": "Metric name (snake_case), e.g. revenue, adr, room_nights, bookings, conversion",
     "filled": 84,
     "unique": 3,
     "example": "bookings"
    },
    {
     "name": "unit",
     "type": "string",
     "description": "Unit of `value`: VND, nights, count, ratio, position, score_10",
     "filled": 84,
     "unique": 3,
     "example": "VND"
    },
    {
     "name": "period_type",
     "type": "string",
     "description": "Agoda period code 0–3. Only partly decoded — do NOT treat as a known window and do NOT add to Booking tables",
     "filled": 84,
     "unique": 4,
     "example": "0"
    },
    {
     "name": "period_label",
     "type": "string",
     "description": "Reporting period label as shown by the platform",
     "filled": 21,
     "unique": 1,
     "example": "booked so far this month"
    },
    {
     "name": "value",
     "type": "number",
     "description": "Metric value; unit given in `unit`. -1 from Booking means 'no data', not zero",
     "filled": 84,
     "unique": 18,
     "example": "0"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics-agoda/fact_agoda_summary.csv",
   "json_url": "/data/fact-agoda-summary.json",
   "csv_url": "/data/fact-agoda-summary.csv",
   "html_url": "/library/data/fact-agoda-summary/",
   "key": "fact-agoda-summary",
   "title": "fact_agoda_summary",
   "channel": "Agoda",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/fact-agoda-summary.csv",
    "json": "/data/fact-agoda-summary.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 84,
     "unique": 1,
     "sample": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 84,
     "unique": 1,
     "sample": "agoda"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 84,
     "unique": 7,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 84,
     "unique": 7,
     "sample": "63382515, 84463560, 84463562"
    },
    {
     "name": "metric",
     "type": "chữ",
     "filled": 84,
     "unique": 3,
     "sample": "bookings, revenue, room_nights"
    },
    {
     "name": "unit",
     "type": "chữ",
     "filled": 84,
     "unique": 3,
     "sample": "VND, count, nights"
    },
    {
     "name": "period_type",
     "type": "số",
     "filled": 84,
     "unique": 4,
     "sample": "0, 1, 2"
    },
    {
     "name": "period_label",
     "type": "chữ",
     "filled": 21,
     "unique": 1,
     "sample": "booked so far this month"
    },
    {
     "name": "value",
     "type": "số",
     "filled": 84,
     "unique": 18,
     "sample": "0, 1, 10"
    }
   ]
  },
  {
   "id": "fact_agoda_daily",
   "name": "Agoda daily bookings",
   "description": "Agoda bookings gained/lost per day (last 30 days only), by booking date or stay date.",
   "category": "performance",
   "subcategory": null,
   "platform": "agoda",
   "grain": "one property × day × basis",
   "keywords": [
    "agoda",
    "daily",
    "bookings gained",
    "bookings lost",
    "theo ngay"
   ],
   "derived": false,
   "rows": 178,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 178,
     "unique": 1,
     "example": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 178,
     "unique": 1,
     "example": "agoda"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 178,
     "unique": 3,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 178,
     "unique": 3,
     "example": "84463562"
    },
    {
     "name": "date",
     "type": "date",
     "description": "Day the counts refer to (only the last 30 days are available on Agoda)",
     "filled": 178,
     "unique": 32,
     "example": "2026-08-24"
    },
    {
     "name": "basis",
     "type": "string",
     "description": "book = by booking date · stay = by stay date",
     "filled": 178,
     "unique": 2,
     "example": "book"
    },
    {
     "name": "bookings_gained",
     "type": "integer",
     "description": "New bookings on that day",
     "filled": 178,
     "unique": 2,
     "example": "0"
    },
    {
     "name": "bookings_lost",
     "type": "integer",
     "description": "Cancelled bookings on that day",
     "filled": 178,
     "unique": 3,
     "example": "0"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics-agoda/fact_agoda_daily.csv",
   "json_url": "/data/fact-agoda-daily.json",
   "csv_url": "/data/fact-agoda-daily.csv",
   "html_url": "/library/data/fact-agoda-daily/",
   "key": "fact-agoda-daily",
   "title": "fact_agoda_daily",
   "channel": "Agoda",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/fact-agoda-daily.csv",
    "json": "/data/fact-agoda-daily.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 178,
     "unique": 1,
     "sample": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 178,
     "unique": 1,
     "sample": "agoda"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 178,
     "unique": 3,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 178,
     "unique": 3,
     "sample": "84463562, 84463574, 96450982"
    },
    {
     "name": "date",
     "type": "ngày",
     "filled": 178,
     "unique": 32,
     "sample": "2026-08-24, 2026-08-25, 2026-08-26"
    },
    {
     "name": "basis",
     "type": "chữ",
     "filled": 178,
     "unique": 2,
     "sample": "book, stay"
    },
    {
     "name": "bookings_gained",
     "type": "số",
     "filled": 178,
     "unique": 2,
     "sample": "0, 1"
    },
    {
     "name": "bookings_lost",
     "type": "số",
     "filled": 178,
     "unique": 3,
     "sample": "0, 1, 2"
    }
   ]
  },
  {
   "id": "fact_agoda_reservations",
   "name": "Agoda reservations",
   "description": "Agoda reservation list (no amounts — join booking_id to fact_agoda_transactions.reference_number for money).",
   "category": "reservations",
   "subcategory": null,
   "platform": "agoda",
   "grain": "one reservation",
   "keywords": [
    "agoda",
    "reservation",
    "don dat phong agoda",
    "booking id"
   ],
   "derived": false,
   "rows": 14,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 14,
     "unique": 1,
     "example": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 14,
     "unique": 1,
     "example": "agoda"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 14,
     "unique": 3,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 14,
     "unique": 3,
     "example": "84463562"
    },
    {
     "name": "booking_id",
     "type": "string",
     "description": "Agoda booking ID. Join to fact_agoda_transactions.reference_number for money (the list itself has no amounts)",
     "filled": 14,
     "unique": 14,
     "example": "1700138196"
    },
    {
     "name": "checkin",
     "type": "date",
     "description": "Check-in date",
     "filled": 14,
     "unique": 13,
     "example": "2026-02-19"
    },
    {
     "name": "checkout",
     "type": "date",
     "description": "Check-out date",
     "filled": 14,
     "unique": 14,
     "example": "2026-02-20"
    },
    {
     "name": "nights",
     "type": "integer",
     "description": "Number of nights",
     "filled": 14,
     "unique": 6,
     "example": "1"
    },
    {
     "name": "ack_type",
     "type": "string",
     "description": "Agoda acknowledgement type code (raw)",
     "filled": 14,
     "unique": 2,
     "example": "1"
    },
    {
     "name": "stay_type",
     "type": "string",
     "description": "Agoda stay type code (raw, often empty)",
     "filled": 0,
     "unique": 0,
     "example": null
    },
    {
     "name": "payment_model",
     "type": "string",
     "description": "Agoda payment model code (raw)",
     "filled": 14,
     "unique": 1,
     "example": "1"
    },
    {
     "name": "room",
     "type": "string",
     "description": "Room type name and ID",
     "filled": 14,
     "unique": 3,
     "example": "1BR Studio A La Carte Hotel [Free Airport Pickup From 3 Nights] (1323423599)"
    },
    {
     "name": "rooms",
     "type": "integer",
     "description": "Number of rooms",
     "filled": 14,
     "unique": 1,
     "example": "1"
    },
    {
     "name": "adults",
     "type": "integer",
     "description": "Number of adult guests",
     "filled": 14,
     "unique": 5,
     "example": "2"
    },
    {
     "name": "children",
     "type": "integer",
     "description": "Number of children",
     "filled": 14,
     "unique": 2,
     "example": "0"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics-agoda/fact_agoda_reservations.csv",
   "json_url": "/data/fact-agoda-reservations.json",
   "csv_url": "/data/fact-agoda-reservations.csv",
   "html_url": "/library/data/fact-agoda-reservations/",
   "key": "fact-agoda-reservations",
   "title": "fact_agoda_reservations",
   "channel": "Agoda",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/fact-agoda-reservations.csv",
    "json": "/data/fact-agoda-reservations.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 14,
     "unique": 1,
     "sample": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 14,
     "unique": 1,
     "sample": "agoda"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 14,
     "unique": 3,
     "sample": "15nuocman5, 181tohienthanh, alacarte502"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 14,
     "unique": 3,
     "sample": "84463562, 84463574, 84463577"
    },
    {
     "name": "booking_id",
     "type": "số",
     "filled": 14,
     "unique": 14,
     "sample": "1700138196, 1700156672, 1731187602"
    },
    {
     "name": "checkin",
     "type": "ngày",
     "filled": 14,
     "unique": 13,
     "sample": "2026-02-19, 2026-03-06, 2026-04-15"
    },
    {
     "name": "checkout",
     "type": "ngày",
     "filled": 14,
     "unique": 14,
     "sample": "2026-02-20, 2026-03-13, 2026-04-18"
    },
    {
     "name": "nights",
     "type": "số",
     "filled": 14,
     "unique": 6,
     "sample": "1, 2, 3"
    },
    {
     "name": "ack_type",
     "type": "số",
     "filled": 14,
     "unique": 2,
     "sample": "1, 3"
    },
    {
     "name": "stay_type",
     "type": "chữ",
     "filled": 0,
     "unique": 0,
     "sample": ""
    },
    {
     "name": "payment_model",
     "type": "số",
     "filled": 14,
     "unique": 1,
     "sample": "1"
    },
    {
     "name": "room",
     "type": "chữ",
     "filled": 14,
     "unique": 3,
     "sample": "1BR Studio A La Carte Hotel [Free Airport Pickup From 3 Nights] (1323423599), Pr"
    },
    {
     "name": "rooms",
     "type": "số",
     "filled": 14,
     "unique": 1,
     "sample": "1"
    },
    {
     "name": "adults",
     "type": "số",
     "filled": 14,
     "unique": 5,
     "sample": "2, 3, 4"
    },
    {
     "name": "children",
     "type": "số",
     "filled": 14,
     "unique": 2,
     "sample": "0, 1"
    }
   ]
  },
  {
   "id": "fact_agoda_transactions",
   "name": "Agoda transactions",
   "description": "Agoda money transactions per booking (booking value, collection amount, adjustments). booking_value = 0 means cancelled.",
   "category": "payments",
   "subcategory": null,
   "platform": "agoda",
   "grain": "one transaction",
   "keywords": [
    "agoda",
    "transaction",
    "payout",
    "payment",
    "tien",
    "thanh toan",
    "booking value",
    "collection"
   ],
   "derived": false,
   "rows": 28,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 28,
     "unique": 1,
     "example": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 28,
     "unique": 1,
     "example": "agoda"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 28,
     "unique": 4,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 28,
     "unique": 4,
     "example": "63382515"
    },
    {
     "name": "transaction_id",
     "type": "string",
     "description": "Agoda transaction ID",
     "filled": 28,
     "unique": 28,
     "example": "10330703988"
    },
    {
     "name": "reference_number",
     "type": "string",
     "description": "Booking ID the transaction belongs to (= fact_agoda_reservations.booking_id)",
     "filled": 28,
     "unique": 25,
     "example": "1558664156"
    },
    {
     "name": "transaction_type",
     "type": "string",
     "description": "Reservation or Adjustment",
     "filled": 28,
     "unique": 2,
     "example": "Adjustment"
    },
    {
     "name": "is_adjustment",
     "type": "boolean",
     "description": "1 if the transaction is an adjustment",
     "filled": 28,
     "unique": 2,
     "example": "0"
    },
    {
     "name": "created_date",
     "type": "date",
     "description": "Date the transaction was created",
     "filled": 28,
     "unique": 23,
     "example": "2025-03-06"
    },
    {
     "name": "checkin",
     "type": "date",
     "description": "Check-in date",
     "filled": 28,
     "unique": 22,
     "example": "2025-03-18"
    },
    {
     "name": "checkout",
     "type": "date",
     "description": "Check-out date",
     "filled": 28,
     "unique": 23,
     "example": "2025-03-20"
    },
    {
     "name": "booking_value",
     "type": "number",
     "description": "Booking value in VND. 0 means the booking was cancelled",
     "filled": 28,
     "unique": 17,
     "example": "-4438157.9"
    },
    {
     "name": "collection_amount",
     "type": "number",
     "description": "Amount collected/paid out in VND (negative = deduction)",
     "filled": 28,
     "unique": 17,
     "example": "-4438157.9"
    },
    {
     "name": "currency",
     "type": "string",
     "description": "Currency code of money columns (VND)",
     "filled": 28,
     "unique": 1,
     "example": "VND"
    },
    {
     "name": "payment_method",
     "type": "string",
     "description": "Payout method (Telex Transfer)",
     "filled": 28,
     "unique": 1,
     "example": "Telex Transfer"
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics-agoda/fact_agoda_transactions.csv",
   "json_url": "/data/fact-agoda-transactions.json",
   "csv_url": "/data/fact-agoda-transactions.csv",
   "html_url": "/library/data/fact-agoda-transactions/",
   "key": "fact-agoda-transactions",
   "title": "fact_agoda_transactions",
   "channel": "Agoda",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/fact-agoda-transactions.csv",
    "json": "/data/fact-agoda-transactions.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 28,
     "unique": 1,
     "sample": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 28,
     "unique": 1,
     "sample": "agoda"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 28,
     "unique": 4,
     "sample": "15nuocman5, 181tohienthanh, alacarte305"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 28,
     "unique": 4,
     "sample": "63382515, 84463562, 84463574"
    },
    {
     "name": "transaction_id",
     "type": "số",
     "filled": 28,
     "unique": 28,
     "sample": "10330703988, 10496353526, 10530884449"
    },
    {
     "name": "reference_number",
     "type": "chữ",
     "filled": 28,
     "unique": 25,
     "sample": "1558664156, 1609038648, 1647763853"
    },
    {
     "name": "transaction_type",
     "type": "chữ",
     "filled": 28,
     "unique": 2,
     "sample": "Adjustment, Reservation"
    },
    {
     "name": "is_adjustment",
     "type": "số",
     "filled": 28,
     "unique": 2,
     "sample": "0, 1"
    },
    {
     "name": "created_date",
     "type": "ngày",
     "filled": 28,
     "unique": 23,
     "sample": "2025-03-06, 2025-05-08, 2025-09-07"
    },
    {
     "name": "checkin",
     "type": "ngày",
     "filled": 28,
     "unique": 22,
     "sample": "2025-03-18, 2025-05-26, 2025-10-31"
    },
    {
     "name": "checkout",
     "type": "ngày",
     "filled": 28,
     "unique": 23,
     "sample": "2025-03-20, 2025-05-28, 2025-11-20"
    },
    {
     "name": "booking_value",
     "type": "số",
     "filled": 28,
     "unique": 17,
     "sample": "-4438157.9, -532000.0, 0.0"
    },
    {
     "name": "collection_amount",
     "type": "số",
     "filled": 28,
     "unique": 17,
     "sample": "-4438157.9, -532000.0, 0.0"
    },
    {
     "name": "currency",
     "type": "chữ",
     "filled": 28,
     "unique": 1,
     "sample": "VND"
    },
    {
     "name": "payment_method",
     "type": "chữ",
     "filled": 28,
     "unique": 1,
     "sample": "Telex Transfer"
    }
   ]
  },
  {
   "id": "fact_agoda_reviews",
   "name": "Agoda reviews",
   "description": "Agoda guest reviews with score, country, traveller type, length of stay and text.",
   "category": "reviews",
   "subcategory": null,
   "platform": "agoda",
   "grain": "one review",
   "keywords": [
    "agoda",
    "review",
    "reviews",
    "danh gia agoda",
    "score"
   ],
   "derived": false,
   "rows": 8,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 8,
     "unique": 1,
     "example": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 8,
     "unique": 1,
     "example": "agoda"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 8,
     "unique": 3,
     "example": "181tohienthanh"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 8,
     "unique": 3,
     "example": "63382515"
    },
    {
     "name": "review_id",
     "type": "string",
     "description": "Review ID on the platform",
     "filled": 8,
     "unique": 8,
     "example": "127190515"
    },
    {
     "name": "booking_id",
     "type": "string",
     "description": "Agoda booking ID of the reviewed stay",
     "filled": 8,
     "unique": 8,
     "example": "1679598750"
    },
    {
     "name": "review_date",
     "type": "date",
     "description": "Date of the review",
     "filled": 8,
     "unique": 8,
     "example": "2025-09-04"
    },
    {
     "name": "checkin",
     "type": "date",
     "description": "Check-in date",
     "filled": 8,
     "unique": 8,
     "example": "2025-08-12"
    },
    {
     "name": "checkout",
     "type": "date",
     "description": "Check-out date",
     "filled": 8,
     "unique": 8,
     "example": "2025-08-20"
    },
    {
     "name": "score",
     "type": "number",
     "description": "Overall review score given by the guest",
     "filled": 8,
     "unique": 3,
     "example": "10.0"
    },
    {
     "name": "country",
     "type": "string",
     "description": "Guest country",
     "filled": 8,
     "unique": 6,
     "example": "AU"
    },
    {
     "name": "demographic",
     "type": "string",
     "description": "Traveller type (Couples, Families with young children, Groups…)",
     "filled": 8,
     "unique": 4,
     "example": "Couples"
    },
    {
     "name": "los",
     "type": "string",
     "description": "Length of stay text (e.g. 'Stayed 7 nights in March 2026')",
     "filled": 8,
     "unique": 8,
     "example": "Stayed 3 nights in April 2026"
    },
    {
     "name": "title",
     "type": "string",
     "description": "Review title",
     "filled": 7,
     "unique": 7,
     "example": "Excellent Villa."
    },
    {
     "name": "comment",
     "type": "string",
     "description": "Review text",
     "filled": 8,
     "unique": 8,
     "example": "Gia đình tôi đã có 1 kỳ nghỉ  \"đáng tiền\" tại đây."
    },
    {
     "name": "positive",
     "type": "string",
     "description": "Positive review text",
     "filled": 0,
     "unique": 0,
     "example": null
    },
    {
     "name": "negative",
     "type": "string",
     "description": "Negative review text",
     "filled": 0,
     "unique": 0,
     "example": null
    }
   ],
   "updated_at": "2026-09-24",
   "source": "vault/18-ota-listings/metrics-agoda/fact_agoda_reviews.csv",
   "json_url": "/data/fact-agoda-reviews.json",
   "csv_url": "/data/fact-agoda-reviews.csv",
   "html_url": "/library/data/fact-agoda-reviews/",
   "key": "fact-agoda-reviews",
   "title": "fact_agoda_reviews",
   "channel": "Agoda",
   "read_date": "2026-09-24",
   "download": {
    "csv": "/data/fact-agoda-reviews.csv",
    "json": "/data/fact-agoda-reviews.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 8,
     "unique": 1,
     "sample": "2026-09-24"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 8,
     "unique": 1,
     "sample": "agoda"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 8,
     "unique": 3,
     "sample": "181tohienthanh, alacarte305, alacarte502"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 8,
     "unique": 3,
     "sample": "63382515, 84463574, 84463577"
    },
    {
     "name": "review_id",
     "type": "số",
     "filled": 8,
     "unique": 8,
     "sample": "127190515, 139256867, 140608258"
    },
    {
     "name": "booking_id",
     "type": "số",
     "filled": 8,
     "unique": 8,
     "sample": "1679598750, 1700156672, 1731187602"
    },
    {
     "name": "review_date",
     "type": "ngày",
     "filled": 8,
     "unique": 8,
     "sample": "2025-09-04, 2026-02-23, 2026-03-14"
    },
    {
     "name": "checkin",
     "type": "ngày",
     "filled": 8,
     "unique": 8,
     "sample": "2025-08-12, 2026-02-14, 2026-03-06"
    },
    {
     "name": "checkout",
     "type": "ngày",
     "filled": 8,
     "unique": 8,
     "sample": "2025-08-20, 2026-02-19, 2026-03-13"
    },
    {
     "name": "score",
     "type": "số",
     "filled": 8,
     "unique": 3,
     "sample": "10.0, 7.6, 8.8"
    },
    {
     "name": "country",
     "type": "chữ",
     "filled": 8,
     "unique": 6,
     "sample": "AU, CA, GB"
    },
    {
     "name": "demographic",
     "type": "chữ",
     "filled": 8,
     "unique": 4,
     "sample": "Couples, Families with teens, Families with young children"
    },
    {
     "name": "los",
     "type": "chữ",
     "filled": 8,
     "unique": 8,
     "sample": "Stayed 3 nights in April 2026, Stayed 3 nights in May 2026, Stayed 4 nights in J"
    },
    {
     "name": "title",
     "type": "chữ",
     "filled": 7,
     "unique": 7,
     "sample": "Excellent Villa., Kỳ nghỉ tuyệt vời, Nice but expensive "
    },
    {
     "name": "comment",
     "type": "chữ",
     "filled": 8,
     "unique": 8,
     "sample": "Gia đình tôi đã có 1 kỳ nghỉ  \"đáng tiền\" tại đây., Great Location - Clean Room "
    },
    {
     "name": "positive",
     "type": "chữ",
     "filled": 0,
     "unique": 0,
     "sample": ""
    },
    {
     "name": "negative",
     "type": "chữ",
     "filled": 0,
     "unique": 0,
     "sample": ""
    }
   ]
  },
  {
   "id": "agoda_ranking",
   "name": "Agoda public search rank",
   "description": "Where each property ranks in Agoda public search results (Đà Nẵng), per search set and pass, with status when not ranked.",
   "category": "search_ranking",
   "subcategory": null,
   "platform": "agoda",
   "grain": "one property × search × pass",
   "keywords": [
    "agoda",
    "search rank",
    "ranking",
    "thu hang agoda",
    "not open",
    "over capacity"
   ],
   "derived": false,
   "rows": 72,
   "fields": [
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was crawled from the platform (NOT the date the numbers refer to)",
     "filled": 72,
     "unique": 1,
     "example": "2026-09-26"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 72,
     "unique": 1,
     "example": "agoda"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 72,
     "unique": 7,
     "example": "15nuocman5"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 72,
     "unique": 7,
     "example": "63382515"
    },
    {
     "name": "search_id",
     "type": "string",
     "description": "Search set ID within one measurement run (A–D)",
     "filled": 72,
     "unique": 6,
     "example": "A"
    },
    {
     "name": "pass_no",
     "type": "integer",
     "description": "Measurement pass (1 or 2) — results reshuffle between passes, so ≥2 passes are taken",
     "filled": 72,
     "unique": 2,
     "example": "1"
    },
    {
     "name": "city_id",
     "type": "string",
     "description": "Agoda city ID of the search (Đà Nẵng = 16440)",
     "filled": 72,
     "unique": 1,
     "example": "16440"
    },
    {
     "name": "checkin",
     "type": "date",
     "description": "Check-in date",
     "filled": 72,
     "unique": 3,
     "example": "2026-10-01"
    },
    {
     "name": "checkout",
     "type": "date",
     "description": "Check-out date",
     "filled": 72,
     "unique": 4,
     "example": "2026-10-03"
    },
    {
     "name": "nights",
     "type": "integer",
     "description": "Number of nights",
     "filled": 72,
     "unique": 2,
     "example": "2"
    },
    {
     "name": "adults",
     "type": "integer",
     "description": "Number of adult guests",
     "filled": 72,
     "unique": 4,
     "example": "10"
    },
    {
     "name": "rooms",
     "type": "integer",
     "description": "Number of rooms",
     "filled": 72,
     "unique": 1,
     "example": "1"
    },
    {
     "name": "sort",
     "type": "string",
     "description": "Sort order used for the public search (platform default)",
     "filled": 72,
     "unique": 1,
     "example": "best_match"
    },
    {
     "name": "personalization",
     "type": "string",
     "description": "Search context: clean_context / anon = no logged-in personalisation",
     "filled": 72,
     "unique": 2,
     "example": "anon"
    },
    {
     "name": "total_filtered",
     "type": "integer",
     "description": "Total results after filters (totalFilteredHotels)",
     "filled": 72,
     "unique": 8,
     "example": "1088"
    },
    {
     "name": "rows_scanned",
     "type": "integer",
     "description": "Result rows read during the search",
     "filled": 72,
     "unique": 9,
     "example": "1167"
    },
    {
     "name": "unique_ids",
     "type": "integer",
     "description": "Distinct properties seen in the search results",
     "filled": 72,
     "unique": 11,
     "example": "1012"
    },
    {
     "name": "rank",
     "type": "integer",
     "description": "Position of the property in public search results (first occurrence); empty when not ranked",
     "filled": 31,
     "unique": 21,
     "example": "1003"
    },
    {
     "name": "page_approx",
     "type": "integer",
     "description": "Approximate results page of `rank`",
     "filled": 31,
     "unique": 12,
     "example": "1"
    },
    {
     "name": "pct_from_top",
     "type": "number",
     "description": "Rank as % of total results from the top (can exceed 100 % because of duplicate rows)",
     "filled": 31,
     "unique": 21,
     "example": "100.4"
    },
    {
     "name": "status",
     "type": "string",
     "description": "ranked · not_open (calendar not open) · over_capacity (guests > capacity) · not_found · grouped_under_<id> (shown inside a grouped listing)",
     "filled": 72,
     "unique": 5,
     "example": "grouped_under_84463577"
    },
    {
     "name": "agoda_bookings_confirmed",
     "type": "integer",
     "description": "Confirmed Agoda bookings of the property at measurement time",
     "filled": 56,
     "unique": 4,
     "example": "0"
    },
    {
     "name": "note",
     "type": "string",
     "description": "Free-text note from the measurement",
     "filled": 30,
     "unique": 15,
     "example": "0/61 đêm mở 01/10–30/11 — kín phòng ở Airbnb/Booking (iCal OK)"
    }
   ],
   "updated_at": "2026-09-26",
   "source": "vault/18-ota-listings/metrics-agoda/agoda_ranking.csv",
   "json_url": "/data/agoda-ranking.json",
   "csv_url": "/data/agoda-ranking.csv",
   "html_url": "/library/data/agoda-ranking/",
   "key": "agoda-ranking",
   "title": "agoda_ranking",
   "channel": "Agoda",
   "read_date": "2026-09-26",
   "download": {
    "csv": "/data/agoda-ranking.csv",
    "json": "/data/agoda-ranking.json"
   },
   "columns": [
    {
     "name": "snapshot_date",
     "type": "ngày",
     "filled": 72,
     "unique": 1,
     "sample": "2026-09-26"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 72,
     "unique": 1,
     "sample": "agoda"
    },
    {
     "name": "slug",
     "type": "chữ",
     "filled": 72,
     "unique": 7,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 72,
     "unique": 7,
     "sample": "63382515, 84463560, 84463562"
    },
    {
     "name": "search_id",
     "type": "chữ",
     "filled": 72,
     "unique": 6,
     "sample": "A, B, C"
    },
    {
     "name": "pass_no",
     "type": "số",
     "filled": 72,
     "unique": 2,
     "sample": "1, 2"
    },
    {
     "name": "city_id",
     "type": "số",
     "filled": 72,
     "unique": 1,
     "sample": "16440"
    },
    {
     "name": "checkin",
     "type": "ngày",
     "filled": 72,
     "unique": 3,
     "sample": "2026-10-01, 2026-10-11, 2026-10-22"
    },
    {
     "name": "checkout",
     "type": "ngày",
     "filled": 72,
     "unique": 4,
     "sample": "2026-10-03, 2026-10-13, 2026-10-14"
    },
    {
     "name": "nights",
     "type": "số",
     "filled": 72,
     "unique": 2,
     "sample": "2, 3"
    },
    {
     "name": "adults",
     "type": "số",
     "filled": 72,
     "unique": 4,
     "sample": "10, 2, 4"
    },
    {
     "name": "rooms",
     "type": "số",
     "filled": 72,
     "unique": 1,
     "sample": "1"
    },
    {
     "name": "sort",
     "type": "chữ",
     "filled": 72,
     "unique": 1,
     "sample": "best_match"
    },
    {
     "name": "personalization",
     "type": "chữ",
     "filled": 72,
     "unique": 2,
     "sample": "anon, clean_context"
    },
    {
     "name": "total_filtered",
     "type": "số",
     "filled": 72,
     "unique": 8,
     "sample": "1088, 1092, 2396"
    },
    {
     "name": "rows_scanned",
     "type": "số",
     "filled": 72,
     "unique": 9,
     "sample": "1167, 1169, 1175"
    },
    {
     "name": "unique_ids",
     "type": "số",
     "filled": 72,
     "unique": 11,
     "sample": "1012, 1017, 2428"
    },
    {
     "name": "rank",
     "type": "số",
     "filled": 31,
     "unique": 21,
     "sample": "1003, 1005, 1115"
    },
    {
     "name": "page_approx",
     "type": "số",
     "filled": 31,
     "unique": 12,
     "sample": "1, 12, 15"
    },
    {
     "name": "pct_from_top",
     "type": "số",
     "filled": 31,
     "unique": 21,
     "sample": "100.4, 102.4, 102.5"
    },
    {
     "name": "status",
     "type": "chữ",
     "filled": 72,
     "unique": 5,
     "sample": "grouped_under_84463577, not_found, not_open"
    },
    {
     "name": "agoda_bookings_confirmed",
     "type": "số",
     "filled": 56,
     "unique": 4,
     "sample": "0, 1, 10"
    },
    {
     "name": "note",
     "type": "chữ",
     "filled": 30,
     "unique": 15,
     "sample": "0/61 đêm mở 01/10–30/11 — kín phòng ở Airbnb/Booking (iCal OK), 02/10 không mở, "
    }
   ]
  },
  {
   "id": "agoda_dim_property",
   "name": "Agoda property list",
   "description": "The 7 properties on Agoda: property ID, name, type, first observed selling date, contract date.",
   "category": "properties",
   "subcategory": null,
   "platform": "agoda",
   "grain": "one property",
   "keywords": [
    "agoda",
    "property id",
    "danh sach can agoda",
    "contract"
   ],
   "derived": false,
   "rows": 7,
   "fields": [
    {
     "name": "slug",
     "type": "string",
     "description": "Internal property key (e.g. 25anthuong11, alacarte305). Join key across all datasets",
     "filled": 7,
     "unique": 7,
     "example": "15nuocman5"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Sales channel / platform key: booking | agoda | airbnb | pricelabs",
     "filled": 7,
     "unique": 1,
     "example": "agoda"
    },
    {
     "name": "external_id",
     "type": "string",
     "description": "Property/listing ID on the platform (Booking hotel_id, Agoda property ID, Airbnb listing ID)",
     "filled": 7,
     "unique": 7,
     "example": "63382515"
    },
    {
     "name": "name",
     "type": "string",
     "description": "Property name as listed on the platform",
     "filled": 7,
     "unique": 7,
     "example": "1BR Studio A La Carte Hotel [Free Airport Pickup From 3 Nights]"
    },
    {
     "name": "property_type",
     "type": "string",
     "description": "villa or apartment",
     "filled": 7,
     "unique": 2,
     "example": "apartment"
    },
    {
     "name": "city",
     "type": "string",
     "description": "City of the property",
     "filled": 7,
     "unique": 1,
     "example": "Đà Nẵng"
    },
    {
     "name": "active_from",
     "type": "date",
     "description": "Earliest date the listing is known to be selling (upper bound observed from first booking/stay, or declared)",
     "filled": 5,
     "unique": 5,
     "example": "2025-03-06"
    },
    {
     "name": "active_from_basis",
     "type": "string",
     "description": "How active_from was determined (observed first booking / first stay night, or declared by platform email)",
     "filled": 7,
     "unique": 4,
     "example": "chưa suy ra được · chưa có đơn/review nào"
    },
    {
     "name": "contract_from",
     "type": "date",
     "description": "Earliest acceptance of Agoda terms for the property (contract signed; may be before selling started)",
     "filled": 7,
     "unique": 4,
     "example": "2024-12-25"
    }
   ],
   "updated_at": "2026-09-25",
   "source": "vault/18-ota-listings/metrics-agoda/dim_property.csv",
   "json_url": "/data/agoda-dim-property.json",
   "csv_url": "/data/agoda-dim-property.csv",
   "html_url": "/library/data/agoda-dim-property/",
   "key": "agoda-dim-property",
   "title": "dim_property",
   "channel": "Agoda",
   "read_date": "",
   "download": {
    "csv": "/data/agoda-dim-property.csv",
    "json": "/data/agoda-dim-property.json"
   },
   "columns": [
    {
     "name": "slug",
     "type": "chữ",
     "filled": 7,
     "unique": 7,
     "sample": "15nuocman5, 181tohienthanh, 25anthuong11"
    },
    {
     "name": "channel",
     "type": "chữ",
     "filled": 7,
     "unique": 1,
     "sample": "agoda"
    },
    {
     "name": "external_id",
     "type": "số",
     "filled": 7,
     "unique": 7,
     "sample": "63382515, 84463560, 84463562"
    },
    {
     "name": "name",
     "type": "chữ",
     "filled": 7,
     "unique": 7,
     "sample": "1BR Studio A La Carte Hotel [Free Airport Pickup From 3 Nights], 4BR Villa in An"
    },
    {
     "name": "property_type",
     "type": "chữ",
     "filled": 7,
     "unique": 2,
     "sample": "apartment, villa"
    },
    {
     "name": "city",
     "type": "chữ",
     "filled": 7,
     "unique": 1,
     "sample": "Đà Nẵng"
    },
    {
     "name": "active_from",
     "type": "ngày",
     "filled": 5,
     "unique": 5,
     "sample": "2025-03-06, 2026-01-23, 2026-06-19"
    },
    {
     "name": "active_from_basis",
     "type": "chữ",
     "filled": 7,
     "unique": 4,
     "sample": "chưa suy ra được · chưa có đơn/review nào, declared · email Agoda “Your property"
    },
    {
     "name": "contract_from",
     "type": "ngày",
     "filled": 7,
     "unique": 4,
     "sample": "2024-12-25, 2026-01-19, 2026-02-02"
    }
   ]
  },
  {
   "id": "agoda_promotions",
   "name": "Agoda promotions and customer-facing badges",
   "description": "Every promotion type on Agoda's 'Choose new promotion' page, grouped Mega Sale · Seasonal · Essential · Targeted, with whether a badge shows on the search card, the exact badge text, the detail-page text and who sees it. Measured on agoda.com 28/09/2026.",
   "category": "promotions",
   "subcategory": "badges",
   "platform": "agoda",
   "grain": "one promotion type",
   "keywords": [
    "agoda",
    "promotion",
    "promotions",
    "khuyen mai",
    "badge",
    "label",
    "nhan",
    "mega sale",
    "seasonal",
    "essential",
    "targeted",
    "eco deals",
    "domestic",
    "private sale",
    "payday",
    "customized",
    "early bird",
    "last minute",
    "long stay",
    "customer facing",
    "hien cho khach"
   ],
   "derived": true,
   "rows": 39,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "Always 'agoda'",
     "filled": 39,
     "example": "agoda"
    },
    {
     "name": "category",
     "type": "string",
     "description": "Always 'promotions'",
     "filled": 39,
     "example": "promotions"
    },
    {
     "name": "promotion_group",
     "type": "string",
     "description": "High-level group: Mega Sale · Seasonal · Essential · Targeted",
     "filled": 39,
     "example": "Mega Sale"
    },
    {
     "name": "promotion_name",
     "type": "string",
     "description": "Promotion type as named in Agoda YCS 'Choose new promotion'",
     "filled": 39,
     "example": "Mega Sale"
    },
    {
     "name": "name_note",
     "type": "string",
     "description": "Note attached to the name in the source (e.g. booking window, 'running on 25AT11')",
     "filled": 6,
     "example": "đặt 16–30/11"
    },
    {
     "name": "search_card_badge",
     "type": "string",
     "description": "Label on the search-result card: yes (seen by guests on agoda.com) · sometimes · no (checked, none shown) · yes_per_ycs (Agoda's partner data says the promotion carries a badge, not yet seen on the guest site) · unknown (not measured)",
     "filled": 39,
     "example": "yes_per_ycs"
    },
    {
     "name": "badge_text",
     "type": "string",
     "description": "Exact label text seen on the card (null when not observed or no badge)",
     "filled": 10,
     "example": "Deals Abroad"
    },
    {
     "name": "measurement_gap",
     "type": "string",
     "description": "Part of the card behaviour that could not be measured (e.g. mobile)",
     "filled": 1,
     "example": "trên điện thoại chưa đo được (mobile web giả lập iPhone đứng ở \"Finding the best deals…\", không ra kết quả)"
    },
    {
     "name": "badge_evidence",
     "type": "string",
     "description": "observed_on_guest_site (measured on agoda.com) · ycs_payload_only (badge in YCS data, not yet seen by guests) · not_measured",
     "filled": 39,
     "example": "ycs_payload_only"
    },
    {
     "name": "search_card_text",
     "type": "string",
     "description": "Source description of what the search card shows",
     "filled": 39,
     "example": "nhãn chiến dịch (có BadgeCmsId, hộp YCS hứa Exclusive badge + banner trang chủ + landing page + mạng xã hội)"
    },
    {
     "name": "detail_page_text",
     "type": "string",
     "description": "What the property detail page shows under the room",
     "filled": 17,
     "example": "dải Special Price – Limited time only! · dòng \"<TÊN>: ₫ X off!\" · \"Limited Time Offer. Price includes X% discount!\""
    },
    {
     "name": "detail_page_evidence",
     "type": "string",
     "description": "Evidence level of detail_page_text (same codes as badge_evidence)",
     "filled": 38,
     "example": "ycs_payload_only"
    },
    {
     "name": "customer_visible_to",
     "type": "string",
     "description": "Which guests see the promotion",
     "filled": 39,
     "example": "mọi khách (VIP Priority: chỉ VIP)"
    },
    {
     "name": "measured",
     "type": "string",
     "description": "Cards with the label / cards checked on 28/09/2026",
     "filled": 39,
     "example": "chưa tới ngày đặt, chưa thấy"
    },
    {
     "name": "active_on_25anthuong11",
     "type": "boolean",
     "description": "true = listed as running on 25 An Thượng 11 when read (28/09/2026); null = not listed (not confirmed off). Other properties not checked",
     "filled": 5,
     "example": true
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault file the row was parsed from",
     "filled": 39,
     "example": "vault/18-ota-listings/platforms/agoda-promotion-badges.md"
    },
    {
     "name": "last_updated",
     "type": "date",
     "description": "Date of the source measurement",
     "filled": 39,
     "example": "2026-09-28"
    }
   ],
   "updated_at": "2026-09-28",
   "source": "vault/18-ota-listings/platforms/agoda-promotion-badges.md",
   "json_url": "/data/agoda-promotions.json",
   "csv_url": "/data/agoda-promotions.csv",
   "html_url": "/guide/agoda/agoda-promotion-badges/"
  },
  {
   "id": "agoda_card_labels",
   "name": "Agoda card labels that are not host promotions",
   "description": "Other labels on Agoda search cards (Agoda coupons, Domestic Deals chip, Boost Campaign, Preferred, Promoted…) — where each comes from and whether the host can enable it.",
   "category": "promotions",
   "subcategory": "badges",
   "platform": "agoda",
   "grain": "one label",
   "keywords": [
    "agoda",
    "label",
    "badge",
    "preferred",
    "promoted",
    "coupon",
    "boost campaign",
    "domestic deals",
    "not a promotion"
   ],
   "derived": true,
   "rows": 7,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "Always 'agoda'",
     "filled": 7,
     "example": "agoda"
    },
    {
     "name": "category",
     "type": "string",
     "description": "Always 'promotions'",
     "filled": 7,
     "example": "promotions"
    },
    {
     "name": "label_text",
     "type": "string",
     "description": "Text the guest sees on the card",
     "filled": 7,
     "example": "\"₫ 76,990 applied\" (ô tím cạnh giá) · AGODASPONSORED ở trang chi tiết"
    },
    {
     "name": "origin",
     "type": "string",
     "description": "Where the label comes from",
     "filled": 7,
     "example": "Coupon Agoda tự tài trợ (Instant discount)"
    },
    {
     "name": "host_can_enable",
     "type": "string",
     "description": "Whether the host can turn it on (and how)",
     "filled": 7,
     "example": "Không — Agoda tự áp"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault file",
     "filled": 7,
     "example": "vault/18-ota-listings/platforms/agoda-promotion-badges.md"
    },
    {
     "name": "last_updated",
     "type": "date",
     "description": "Date of the source measurement",
     "filled": 7,
     "example": "2026-09-28"
    }
   ],
   "updated_at": "2026-09-28",
   "source": "vault/18-ota-listings/platforms/agoda-promotion-badges.md",
   "json_url": "/data/agoda-card-labels.json",
   "csv_url": "/data/agoda-card-labels.csv",
   "html_url": "/guide/agoda/agoda-promotion-badges/"
  },
  {
   "id": "booking_promotions",
   "name": "Booking.com promotions and programs",
   "description": "Booking.com promotion types and programs (Targeting, Portfolio deals, Campaign deals, Limited-time, Genius/Preferred/Booster) with discount, who sees it, what the guest sees, stacking rules and badge.",
   "category": "promotions",
   "subcategory": null,
   "platform": "booking",
   "grain": "one promotion type / program",
   "keywords": [
    "booking",
    "promotion",
    "deal",
    "khuyen mai booking",
    "mobile rate",
    "country rate",
    "basic deal",
    "early booker",
    "last minute",
    "getaway",
    "late escape",
    "black friday",
    "limited time",
    "genius",
    "preferred",
    "visibility booster",
    "stacking",
    "chong khuyen mai",
    "badge"
   ],
   "derived": true,
   "rows": 14,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "Always 'booking'",
     "filled": 14,
     "example": "booking"
    },
    {
     "name": "category",
     "type": "string",
     "description": "Always 'promotions'",
     "filled": 14,
     "example": "promotions"
    },
    {
     "name": "promotion_group",
     "type": "string",
     "description": "Targeting · Portfolio deals · Campaign deals · Deep deal · Membership & visibility programs",
     "filled": 14,
     "example": "Targeting"
    },
    {
     "name": "promotion_name",
     "type": "string",
     "description": "Promotion or program name",
     "filled": 14,
     "example": "Mobile rate"
    },
    {
     "name": "name_note",
     "type": "string",
     "description": "Note attached to the name in the source",
     "filled": 1,
     "example": "tên cũ Deal of the Day"
    },
    {
     "name": "customer_visible_to",
     "type": "string",
     "description": "Which guests see it",
     "filled": 2,
     "example": "khách dùng app hoặc web trên điện thoại (chọn App and mobile web hoặc App only)"
    },
    {
     "name": "discount",
     "type": "string",
     "description": "Discount level / minimum",
     "filled": 9,
     "example": "≥ 10 % (Booking khuyên 15 %)"
    },
    {
     "name": "guest_sees",
     "type": "string",
     "description": "What the guest sees (badge, strike-through price…)",
     "filled": 2,
     "example": "badge Mobile-only + gạch giá cũ trong kết quả tìm, trang căn, lúc đặt"
    },
    {
     "name": "stacks_with",
     "type": "string",
     "description": "Promotions it combines with",
     "filled": 13,
     "example": "Genius · Basic / Last-minute / Early booker"
    },
    {
     "name": "not_stacks_with",
     "type": "string",
     "description": "Promotions it does not combine with",
     "filled": 5,
     "example": "Country rate · mọi campaign · Limited-time · Black Friday"
    },
    {
     "name": "eligibility",
     "type": "null",
     "description": "Conditions to join",
     "filled": 0,
     "example": null
    },
    {
     "name": "mechanism",
     "type": "string",
     "description": "How the program works",
     "filled": 7,
     "example": "giảm tự chọn %, tự chọn ngày ở · thứ trong tuần · kỳ ở tối thiểu · đối tượng"
    },
    {
     "name": "booking_window",
     "type": "null",
     "description": "Dates guests can book",
     "filled": 0,
     "example": null
    },
    {
     "name": "stay_window",
     "type": "string",
     "description": "Dates guests can stay",
     "filled": 4,
     "example": "26/03–30/09/2026"
    },
    {
     "name": "available_from",
     "type": "string",
     "description": "Date the campaign opens to hosts",
     "filled": 4,
     "example": "12/02/2026"
    },
    {
     "name": "platform_claim",
     "type": "string",
     "description": "Booking.com's own performance claim",
     "filled": 10,
     "example": "\"increase your bookings from mobile devices by up to 30 %\"; bật cả app + mobile web = \"reach 30 % more potential guests than app alone\""
    },
    {
     "name": "internal_note",
     "type": "string",
     "description": "Harth Living's own recommendation (not a platform fact)",
     "filled": 13,
     "example": "Nên bật cả 7 căn. Lượt tìm Đà Nẵng: mobile 61 %; 305 mới 10 % đơn mobile vs peer 77 %"
    },
    {
     "name": "badge",
     "type": "string",
     "description": "Whether a badge shows to guests: yes · no · unknown",
     "filled": 14,
     "example": "yes"
    },
    {
     "name": "badge_text",
     "type": "string",
     "description": "Exact badge text when read from the extranet (null otherwise)",
     "filled": 3,
     "example": "Mobile-only price"
    },
    {
     "name": "badge_evidence",
     "type": "string",
     "description": "booking_extranet_vuex_<date> (read from the extranet data) · playbook_text · section_heading · null",
     "filled": 12,
     "example": "booking_extranet_vuex_2026-09-20"
    },
    {
     "name": "attributes",
     "type": "object",
     "description": "All source attributes of the program as label → text (JSON object; JSON string in CSV)",
     "filled": 14,
     "example": null
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault file",
     "filled": 14,
     "example": "vault/18-ota-listings/platforms/booking-promotions-playbook.md"
    },
    {
     "name": "last_updated",
     "type": "date",
     "description": "Date of the source document",
     "filled": 14,
     "example": "2026-09-27"
    }
   ],
   "updated_at": "2026-09-27",
   "source": "vault/18-ota-listings/platforms/booking-promotions-playbook.md",
   "json_url": "/data/booking-promotions.json",
   "csv_url": "/data/booking-promotions.csv",
   "html_url": "/guide/booking/booking-promotions-playbook/"
  },
  {
   "id": "airbnb_reviews",
   "name": "Airbnb reviews",
   "description": "Airbnb guest reviews per property: rating, month and text. Reviewer names and photos are removed.",
   "category": "reviews",
   "subcategory": null,
   "platform": "airbnb",
   "grain": "one review",
   "keywords": [
    "airbnb",
    "review",
    "reviews",
    "danh gia airbnb",
    "rating",
    "stars",
    "sao"
   ],
   "derived": true,
   "rows": 117,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "Always 'airbnb'",
     "filled": 117,
     "example": "airbnb"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Property key",
     "filled": 117,
     "example": "15nuocman5"
    },
    {
     "name": "property_name",
     "type": "string",
     "description": "Property name",
     "filled": 117,
     "example": "15 Nước Mặn 5"
    },
    {
     "name": "review_no",
     "type": "integer",
     "description": "Order of the review in the source file",
     "filled": 117,
     "example": 1
    },
    {
     "name": "rating",
     "type": "integer",
     "description": "Stars (1–5)",
     "filled": 117,
     "example": 5
    },
    {
     "name": "month",
     "type": "string",
     "description": "Month of the stay/review as shown by Airbnb (e.g. 'April 2026')",
     "filled": 117,
     "example": "May 2026"
    },
    {
     "name": "comment",
     "type": "string",
     "description": "Review text (reviewer name and photo removed)",
     "filled": 117,
     "example": null
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault file",
     "filled": 117,
     "example": "vault/04-reviews/15nuocman5-reviews.json"
    },
    {
     "name": "last_updated",
     "type": "date",
     "description": "Date the source file was saved",
     "filled": 117,
     "example": "2026-06-27"
    }
   ],
   "updated_at": "2026-06-27",
   "source": [
    "vault/04-reviews/15nuocman5-reviews.json",
    "vault/04-reviews/181tohienthanh-reviews.json",
    "vault/04-reviews/41lehycat-reviews.json",
    "vault/04-reviews/alacarte305-reviews.json",
    "vault/04-reviews/alacarte404-reviews.json",
    "vault/04-reviews/alacarte502-reviews.json"
   ],
   "json_url": "/data/airbnb-reviews.json",
   "csv_url": "/data/airbnb-reviews.csv",
   "html_url": "/performance/reviews/"
  },
  {
   "id": "pricelabs_listings",
   "name": "PriceLabs listings — Min / Base / Max and sync",
   "description": "The 14 PriceLabs rows that push prices (2 per property: Airbnb + Booking): min, base and max price, previous base, sync status, last push and last booking. Snapshot 27/09/2026.",
   "category": "pricing",
   "subcategory": null,
   "platform": "pricelabs",
   "grain": "one PriceLabs listing (property × channel)",
   "keywords": [
    "pricelabs",
    "price",
    "pricing",
    "gia",
    "base price",
    "min price",
    "max price",
    "sync",
    "dynamic pricing",
    "dong bo gia"
   ],
   "derived": true,
   "rows": 14,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "Always 'pricelabs'",
     "filled": 14,
     "example": "pricelabs"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Property key",
     "filled": 14,
     "example": "alacarte305"
    },
    {
     "name": "property_name",
     "type": "string",
     "description": "Property name",
     "filled": 14,
     "example": "A La Carte 305"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "Channel the row pushes prices to: airbnb · booking",
     "filled": 14,
     "example": "airbnb"
    },
    {
     "name": "listing_id",
     "type": "string",
     "description": "Listing ID on that channel as known to PriceLabs",
     "filled": 14,
     "example": "1299210095000132691"
    },
    {
     "name": "listing_name",
     "type": "string",
     "description": "Listing name in PriceLabs",
     "filled": 14,
     "example": "305--305 · Newly built A La Carte 2b2ba - Free Airport Pickup"
    },
    {
     "name": "min_price_vnd",
     "type": "integer",
     "description": "Minimum price (VND)",
     "filled": 14,
     "example": 1552500
    },
    {
     "name": "base_price_vnd",
     "type": "integer",
     "description": "Base price (VND)",
     "filled": 14,
     "example": 2510420
    },
    {
     "name": "max_price_vnd",
     "type": "integer",
     "description": "Maximum price (VND)",
     "filled": 14,
     "example": 6276050
    },
    {
     "name": "previous_base_price_vnd",
     "type": "integer",
     "description": "Base price before the last change (VND)",
     "filled": 14,
     "example": 2182970
    },
    {
     "name": "previous_base_replaced_at",
     "type": "datetime",
     "description": "When the previous base was replaced",
     "filled": 14,
     "example": "2026-09-14T11:30:53Z"
    },
    {
     "name": "sync_on",
     "type": "boolean",
     "description": "Price sync switched on",
     "filled": 14,
     "example": true
    },
    {
     "name": "sync_status",
     "type": "string",
     "description": "Sync status text at snapshot time",
     "filled": 14,
     "example": "Queued"
    },
    {
     "name": "last_pushed_on",
     "type": "datetime",
     "description": "Last time prices were pushed to the channel",
     "filled": 14,
     "example": "2026-09-26T08:01:02.000Z"
    },
    {
     "name": "last_booked_date",
     "type": "date",
     "description": "Last booking date seen by PriceLabs",
     "filled": 13,
     "example": "2026-09-15"
    },
    {
     "name": "first_reservation_date",
     "type": "date",
     "description": "First reservation seen by PriceLabs",
     "filled": 13,
     "example": "2024-12-24"
    },
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date of the PriceLabs snapshot",
     "filled": 14,
     "example": "2026-09-27"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Snapshot archive in the vault",
     "filled": 14,
     "example": "vault/18-ota-listings/audits/2026-09-27-pricelabs-current-setup/raw-json.tar.gz"
    }
   ],
   "updated_at": "2026-09-27",
   "source": "vault/18-ota-listings/audits/2026-09-27-pricelabs-current-setup/raw-json.tar.gz",
   "json_url": "/data/pricelabs-listings.json",
   "csv_url": "/data/pricelabs-listings.csv",
   "html_url": "/status/pricelabs/"
  },
  {
   "id": "pricelabs_customizations",
   "name": "PriceLabs customizations",
   "description": "Customization settings applied to each PriceLabs listing (last-minute, orphan day, min stay, pricing offset, occupancy, far-out premium…), as resolved text. Snapshot 27/09/2026.",
   "category": "pricing",
   "subcategory": "customizations",
   "platform": "pricelabs",
   "grain": "one setting × PriceLabs listing",
   "keywords": [
    "pricelabs",
    "customization",
    "min stay",
    "minimum stay",
    "last minute",
    "orphan day",
    "offset",
    "tuy chinh",
    "far out premium"
   ],
   "derived": true,
   "rows": 120,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "Always 'pricelabs'",
     "filled": 120,
     "example": "pricelabs"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Property key",
     "filled": 120,
     "example": "alacarte305"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "airbnb · booking",
     "filled": 120,
     "example": "airbnb"
    },
    {
     "name": "listing_id",
     "type": "string",
     "description": "Listing ID",
     "filled": 120,
     "example": "1299210095000132691"
    },
    {
     "name": "setting",
     "type": "string",
     "description": "Customization key (last_minute, orphan_day, min_stay, pricing_offset, …)",
     "filled": 120,
     "example": "last_minute"
    },
    {
     "name": "value_text",
     "type": "string",
     "description": "Resolved setting as PriceLabs describes it",
     "filled": 106,
     "example": "Market Driven (Balanced): Currently, there is 32% discount for same day bookings which reduces to 0% after 6 days."
    },
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date of the PriceLabs snapshot",
     "filled": 120,
     "example": "2026-09-27"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Snapshot archive",
     "filled": 120,
     "example": "vault/18-ota-listings/audits/2026-09-27-pricelabs-current-setup/raw-json.tar.gz"
    }
   ],
   "updated_at": "2026-09-27",
   "source": "vault/18-ota-listings/audits/2026-09-27-pricelabs-current-setup/raw-json.tar.gz",
   "json_url": "/data/pricelabs-customizations.json",
   "csv_url": "/data/pricelabs-customizations.csv",
   "html_url": "/status/pricelabs/"
  },
  {
   "id": "pricelabs_calendar_monthly",
   "name": "PriceLabs nightly prices by month",
   "description": "Monthly average, minimum and maximum nightly price from each PriceLabs calendar (18 months ahead). Snapshot 27/09/2026.",
   "category": "pricing",
   "subcategory": "calendar",
   "platform": "pricelabs",
   "grain": "one month × PriceLabs listing",
   "keywords": [
    "pricelabs",
    "calendar",
    "nightly price",
    "gia dem",
    "gia theo thang",
    "monthly price",
    "lich gia"
   ],
   "derived": true,
   "rows": 266,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "Always 'pricelabs'",
     "filled": 266,
     "example": "pricelabs"
    },
    {
     "name": "slug",
     "type": "string",
     "description": "Property key",
     "filled": 266,
     "example": "alacarte305"
    },
    {
     "name": "channel",
     "type": "string",
     "description": "airbnb · booking",
     "filled": 266,
     "example": "airbnb"
    },
    {
     "name": "listing_id",
     "type": "string",
     "description": "Listing ID",
     "filled": 266,
     "example": "1299210095000132691"
    },
    {
     "name": "month",
     "type": "string",
     "description": "Month (YYYY-MM)",
     "filled": 266,
     "example": "2026-09"
    },
    {
     "name": "avg_price_vnd",
     "type": "integer",
     "description": "Average nightly price that month (VND)",
     "filled": 266,
     "example": 1667651
    },
    {
     "name": "min_price_vnd",
     "type": "integer",
     "description": "Lowest nightly price (VND)",
     "filled": 266,
     "example": 1552500
    },
    {
     "name": "max_price_vnd",
     "type": "integer",
     "description": "Highest nightly price (VND)",
     "filled": 266,
     "example": 1762592
    },
    {
     "name": "nights_in_calendar",
     "type": "integer",
     "description": "Nights of that month present in the calendar",
     "filled": 266,
     "example": 5
    },
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date of the PriceLabs snapshot",
     "filled": 266,
     "example": "2026-09-27"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Snapshot archive",
     "filled": 266,
     "example": "vault/18-ota-listings/audits/2026-09-27-pricelabs-current-setup/raw-json.tar.gz"
    }
   ],
   "updated_at": "2026-09-27",
   "source": "vault/18-ota-listings/audits/2026-09-27-pricelabs-current-setup/raw-json.tar.gz",
   "json_url": "/data/pricelabs-calendar-monthly.json",
   "csv_url": "/data/pricelabs-calendar-monthly.csv",
   "html_url": "/status/pricelabs/"
  },
  {
   "id": "issues",
   "name": "OTA issues log",
   "description": "Every open or closed issue L-nn on the listings (priority P0–P3, status, what to fix, where), tagged with properties and platforms by keyword match.",
   "category": "issues",
   "subcategory": null,
   "platform": "all",
   "grain": "one issue",
   "keywords": [
    "issue",
    "issues",
    "problem",
    "loi",
    "viec can lam",
    "todo",
    "p0",
    "p1",
    "open issues",
    "fix",
    "sua"
   ],
   "derived": true,
   "rows": 132,
   "fields": [
    {
     "name": "id",
     "type": "string",
     "description": "Issue code L-nn (never reused)",
     "filled": 132,
     "example": "L-01"
    },
    {
     "name": "level",
     "type": "string",
     "description": "Priority P0 (money lost / wrong facts live) · P1 · P2 · P3",
     "filled": 132,
     "example": "P0"
    },
    {
     "name": "status_group",
     "type": "string",
     "description": "Mở (open) · Đang chờ (waiting) · Đang xử lý (in progress) · Xong (done) · Tạm gác (parked) · Khác",
     "filled": 132,
     "example": "Xong"
    },
    {
     "name": "status",
     "type": "string",
     "description": "Status text from the log",
     "filled": 132,
     "example": "✅ XONG 14/09/2026 ~19:05. Bước 1 cleaning fee 7 căn ×1,15 (15 MN đặt mới 575.000) · bước 2 PriceLabs Base/Min ×1,15 Save+Sync, Airbnb khớp 100 % ngày không promo · bước 3 Single fee đã lưu (task Airbnb biến mất). Hệ số 15 %, thuế tắt. Việc phát sinh: L-96"
    },
    {
     "name": "task",
     "type": "string",
     "description": "What is wrong / what to do",
     "filled": 132,
     "example": "Airbnb đổi sang phí host-only 15,5% ngày 15/09/2026. Cảnh báo hiện ở cả Airbnb (\"Action required by September 15\") lẫn PriceLabs. Không chỉnh giá + phí dọn dẹp thì payout thực nhận giảm trên toàn bộ listing Airbnb. 14/09 — đã đọc trọn cơ chế hai tool, CHƯA áp dụng: Airbnb task CONFIRM_HOST_ONLY_FEE còn ELIGIBLE; wizard Airbnb áp ×1,1479 cho 13 listing toàn tài khoản (kể cả 4 San Jose + 2 căn ngoài PriceLabs), sửa cả cleaning/pet fee 2 năm lịch, không đảo ngược; PriceLabs preview 7 dòng chỉ Base + Min, 0 group/profile/DSO. Thứ tự theo drawer PriceLabs: Airbnb tool → PriceLabs drawer 15 % → Save → Sync. Checklist từng cú bấm ở platforms/airbnb-hof-migration-2026-09.md §5."
    },
    {
     "name": "fix_where",
     "type": "string",
     "description": "Where to fix it",
     "filled": 131,
     "example": "PriceLabs (giá) + Airbnb (cleaning & other fee)"
    },
    {
     "name": "properties",
     "type": "array",
     "description": "Property slugs mentioned (keyword match — may be incomplete)",
     "filled": 109,
     "example": [
      "15nuocman5"
     ]
    },
    {
     "name": "platforms",
     "type": "array",
     "description": "Platforms mentioned (keyword match)",
     "filled": 129,
     "example": [
      "airbnb",
      "pricelabs"
     ]
    },
    {
     "name": "tagging_method",
     "type": "string",
     "description": "How properties/platforms were tagged",
     "filled": 132,
     "example": "keyword_match"
    },
    {
     "name": "html_url",
     "type": "string",
     "description": "Issue page",
     "filled": 132,
     "example": "/issues/l-01/"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault file",
     "filled": 132,
     "example": "vault/18-ota-listings/issues.md"
    },
    {
     "name": "last_updated",
     "type": "date",
     "description": "Last update of the log",
     "filled": 132,
     "example": "2026-09-25"
    }
   ],
   "updated_at": "2026-09-25",
   "source": "vault/18-ota-listings/issues.md",
   "json_url": "/data/issues.json",
   "csv_url": "/data/issues.csv",
   "html_url": "/issues/",
   "legacy_json_url": "/issues.json"
  },
  {
   "id": "properties",
   "name": "Property directory",
   "description": "The 7 properties with their IDs on every platform (Booking hotel_id, Airbnb listing ID, Agoda ID), address, type and links.",
   "category": "properties",
   "subcategory": null,
   "platform": "all",
   "grain": "one property",
   "keywords": [
    "property",
    "properties",
    "villa",
    "apartment",
    "can ho",
    "danh sach can",
    "listing id",
    "hotel id",
    "agoda id",
    "address",
    "dia chi"
   ],
   "derived": true,
   "rows": 7,
   "fields": [
    {
     "name": "slug",
     "type": "string",
     "description": "Property key",
     "filled": 7,
     "example": "25anthuong11"
    },
    {
     "name": "name",
     "type": "string",
     "description": "Display name",
     "filled": 7,
     "example": "25 An Thượng 11"
    },
    {
     "name": "type",
     "type": "string",
     "description": "Villa or Căn hộ (apartment)",
     "filled": 7,
     "example": "Villa"
    },
    {
     "name": "address",
     "type": "string",
     "description": "Address",
     "filled": 7,
     "example": "25 An Thượng 11, Mỹ An, Ngũ Hành Sơn, Đà Nẵng"
    },
    {
     "name": "nickname",
     "type": "string",
     "description": "Internal nickname",
     "filled": 7,
     "example": "25 AT 11"
    },
    {
     "name": "booking_hotel_ids",
     "type": "array",
     "description": "Booking.com hotel_id(s)",
     "filled": 7,
     "example": [
      "16927056"
     ]
    },
    {
     "name": "booking_status",
     "type": "string",
     "description": "Booking.com status",
     "filled": 7,
     "example": "Open/Bookable"
    },
    {
     "name": "airbnb_listing_id",
     "type": "integer",
     "description": "Airbnb listing ID",
     "filled": 7,
     "example": "1729647978348243002"
    },
    {
     "name": "airbnb_listing_name",
     "type": "string",
     "description": "Airbnb listing title",
     "filled": 7,
     "example": "4BR Villa in An Thuong 500m to MyKhe Beach"
    },
    {
     "name": "agoda_id",
     "type": "integer",
     "description": "Agoda property ID",
     "filled": 7,
     "example": "96450982"
    },
    {
     "name": "airbnb_short_link",
     "type": "string",
     "description": "Short Airbnb link",
     "filled": 7,
     "example": "https://airbnb.com/h/25at11"
    },
    {
     "name": "booking_public_url",
     "type": "string",
     "description": "Public Booking.com page (when known)",
     "filled": 2,
     "example": "https://www.booking.com/hotel/vn/4br-villa-in-an-thuong-500m-to-mykhe-beach.html"
    },
    {
     "name": "html_url",
     "type": "string",
     "description": "Property page",
     "filled": 7,
     "example": "/properties/25anthuong11/"
    },
    {
     "name": "json_url",
     "type": "string",
     "description": "Full property JSON",
     "filled": 7,
     "example": "/properties/25anthuong11.json"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault files",
     "filled": 7,
     "example": "vault/18-ota-listings/listings.md · vault/01-context/business.md"
    },
    {
     "name": "last_updated",
     "type": "date",
     "description": "Last update of the ledger",
     "filled": 7,
     "example": "2026-09-05"
    }
   ],
   "updated_at": "2026-09-05",
   "source": "vault/18-ota-listings/listings.md · vault/01-context/business.md",
   "json_url": "/data/properties.json",
   "csv_url": "/data/properties.csv",
   "html_url": "/properties/"
  },
  {
   "id": "listing_status",
   "name": "Listing status by platform",
   "description": "One row per property × platform with the current status summary, read date and freshness — the matrix behind Platform Status.",
   "category": "listing_settings",
   "subcategory": null,
   "platform": "all",
   "grain": "one property × platform",
   "keywords": [
    "status",
    "platform status",
    "listing status",
    "trang thai",
    "cai dat",
    "settings",
    "freshness",
    "read date"
   ],
   "derived": true,
   "rows": 28,
   "fields": [
    {
     "name": "slug",
     "type": "string",
     "description": "Property key",
     "filled": 28,
     "example": "25anthuong11"
    },
    {
     "name": "property_name",
     "type": "string",
     "description": "Property name",
     "filled": 28,
     "example": "25 An Thượng 11"
    },
    {
     "name": "platform",
     "type": "string",
     "description": "pricelabs · booking · agoda · airbnb",
     "filled": 28,
     "example": "pricelabs"
    },
    {
     "name": "summary",
     "type": "string",
     "description": "Status summary shown on Platform Status",
     "filled": 28,
     "example": "2 dòng sync · Min 2.000.000 ₫ · Base 4.600.000 ₫ · Max 11.500.000 ₫"
    },
    {
     "name": "read_date",
     "type": "date",
     "description": "Date the settings were read from the platform",
     "filled": 24,
     "example": "2026-09-27"
    },
    {
     "name": "freshness",
     "type": "string",
     "description": "fresh (≤14 days) · aging (15–30) · stale (>30) · raw_only (raw dump not yet written up) · not_read",
     "filled": 28,
     "example": "fresh"
    },
    {
     "name": "html_url",
     "type": "string",
     "description": "Settings page for the property on that platform",
     "filled": 28,
     "example": "/status/pricelabs/25anthuong11/"
    }
   ],
   "updated_at": "2026-09-27",
   "source": [],
   "json_url": "/data/listing-status.json",
   "csv_url": "/data/listing-status.csv",
   "html_url": "/status/"
  },
  {
   "id": "guides",
   "name": "Guide book index",
   "description": "Every guide in the Guide book, grouped by platform, with a one-line 'use when' and a 30-second summary.",
   "category": "guides",
   "subcategory": null,
   "platform": "all",
   "grain": "one guide",
   "keywords": [
    "guide",
    "how to",
    "playbook",
    "huong dan",
    "cam nang",
    "ranking algorithm",
    "content score",
    "thuat toan"
   ],
   "derived": true,
   "rows": 19,
   "fields": [
    {
     "name": "id",
     "type": "string",
     "description": "Guide key",
     "filled": 19,
     "example": "so-tay-pricelabs"
    },
    {
     "name": "platform",
     "type": "string",
     "description": "pricelabs · booking · agoda · airbnb · chung (cross-platform)",
     "filled": 19,
     "example": "pricelabs"
    },
    {
     "name": "platform_name",
     "type": "string",
     "description": "Platform display name",
     "filled": 19,
     "example": "PriceLabs"
    },
    {
     "name": "title",
     "type": "string",
     "description": "Guide title",
     "filled": 19,
     "example": "Sổ tay PriceLabs — tóm tắt 225 bài help.pricelabs.co"
    },
    {
     "name": "kind",
     "type": "string",
     "description": "md (article) · html (summary page) · pdf (official document)",
     "filled": 19,
     "example": "html"
    },
    {
     "name": "use_when",
     "type": "string",
     "description": "When to read it",
     "filled": 19,
     "example": "Tra nhanh một chức năng PriceLabs khi đồng bộ giá Airbnb + Booking.com."
    },
    {
     "name": "summary_points",
     "type": "array",
     "description": "30-second summary points",
     "filled": 18,
     "example": [
      "Tóm tắt 225 bài hướng dẫn chính thức của PriceLabs, đối chiếu với tài khoản thật (đọc 27/09/2026).",
      "Mở đầu bằng \"8 điều phải nhớ\"; có phần soi riêng 7 căn."
     ]
    },
    {
     "name": "summary_written",
     "type": "string",
     "description": "Date the summary was written",
     "filled": 19,
     "example": "2026-09-28"
    },
    {
     "name": "html_url",
     "type": "string",
     "description": "Guide page",
     "filled": 19,
     "example": "/guide/pricelabs/so-tay-pricelabs/"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault file",
     "filled": 19,
     "example": "vault/07-outputs/pricelabs-guide.html"
    },
    {
     "name": "last_updated",
     "type": "date",
     "description": "Last update of the guide",
     "filled": 19,
     "example": "2026-09-27"
    }
   ],
   "updated_at": "2026-09-28",
   "source": [
    "vault/07-outputs/pricelabs-guide.html",
    "vault/07-outputs/promotions-airbnb-booking.html",
    "vault/10-rules/ota-messaging-rules.md",
    "vault/18-ota-listings/audits/2026-09-15-simple-fixes-guide.md",
    "vault/18-ota-listings/official-docs.md",
    "vault/18-ota-listings/platforms/agoda-homes-content-score-guideline-2025.pdf",
    "vault/18-ota-listings/platforms/agoda-listing-playbook.md",
    "vault/18-ota-listings/platforms/agoda-promotion-badges.md",
    "vault/18-ota-listings/platforms/agoda.md",
    "vault/18-ota-listings/platforms/airbnb-hof-migration-2026-09.md",
    "vault/18-ota-listings/platforms/airbnb.md",
    "vault/18-ota-listings/platforms/booking-prepay-eligibility.md",
    "vault/18-ota-listings/platforms/booking-promotions-playbook.md",
    "vault/18-ota-listings/platforms/booking-ranking-playbook.md",
    "vault/18-ota-listings/platforms/booking.md",
    "vault/18-ota-listings/platforms/pricelabs-connect-booking-playbook.md",
    "vault/18-ota-listings/platforms/pricelabs.md",
    "vault/18-ota-listings/platforms/promotions-airbnb-vs-booking.md"
   ],
   "json_url": "/data/guides.json",
   "csv_url": "/data/guides.csv",
   "html_url": "/guide/"
  },
  {
   "id": "message_templates",
   "name": "Automated guest message templates",
   "description": "Index of automated guest messages per platform (confirmation, check-in, check-out): stage, whether pasted on the platform, date.",
   "category": "messaging",
   "subcategory": null,
   "platform": "all",
   "grain": "one message template",
   "keywords": [
    "message",
    "messages",
    "tin nhan",
    "template",
    "check-in",
    "check-out",
    "confirmation",
    "auto message"
   ],
   "derived": true,
   "rows": 28,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "booking · airbnb · agoda",
     "filled": 28,
     "example": "booking"
    },
    {
     "name": "id",
     "type": "string",
     "description": "Template key",
     "filled": 28,
     "example": "15nuocman5-03-checkin"
    },
    {
     "name": "title",
     "type": "string",
     "description": "Template title",
     "filled": 28,
     "example": "Check-in 15 Nước Mặn 5 — Booking.com"
    },
    {
     "name": "stage",
     "type": "string",
     "description": "Guest journey stage (confirmation · checkin · checkout)",
     "filled": 28,
     "example": "checkin"
    },
    {
     "name": "language",
     "type": "string",
     "description": "Language code",
     "filled": 28,
     "example": "en"
    },
    {
     "name": "pasted_on_platform",
     "type": "string",
     "description": "Whether the current text is pasted on the platform (synced / not)",
     "filled": 10,
     "example": "synced"
    },
    {
     "name": "pasted_date",
     "type": "date",
     "description": "Date pasted",
     "filled": 10,
     "example": "2026-09-23"
    },
    {
     "name": "last_updated",
     "type": "date",
     "description": "Last edit in the vault",
     "filled": 28,
     "example": "2026-09-23"
    },
    {
     "name": "html_url",
     "type": "string",
     "description": "Template page (door codes and Wi-Fi masked)",
     "filled": 28,
     "example": "/status/booking/messages/15nuocman5-03-checkin/"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault file",
     "filled": 28,
     "example": "vault/16-ota-messages/booking/15nuocman5-03-checkin.md"
    }
   ],
   "updated_at": "2026-09-23",
   "source": [
    "vault/16-ota-messages/agoda/15nuocman5-03-checkin.md",
    "vault/16-ota-messages/agoda/181tohienthanh-03-checkin.md",
    "vault/16-ota-messages/agoda/25anthuong11-03-checkin.md",
    "vault/16-ota-messages/agoda/41lehycat-03-checkin.md",
    "vault/16-ota-messages/agoda/alacarte-03-checkin-305.md",
    "vault/16-ota-messages/agoda/alacarte-03-checkin-404.md",
    "vault/16-ota-messages/agoda/alacarte-03-checkin-502.md",
    "vault/16-ota-messages/agoda/alacarte-05-checkout.md",
    "vault/16-ota-messages/agoda/all-01-confirmation.md",
    "vault/16-ota-messages/agoda/villa-05-checkout.md",
    "vault/16-ota-messages/airbnb/15nuocman5-03-checkin.md",
    "vault/16-ota-messages/airbnb/41lehycat-03-checkin.md",
    "vault/16-ota-messages/airbnb/41lehycat-05-checkout.md",
    "vault/16-ota-messages/airbnb/alacarte-03-checkin-305.md",
    "vault/16-ota-messages/airbnb/alacarte-03-checkin-404.md",
    "vault/16-ota-messages/airbnb/alacarte-03-checkin-502.md",
    "vault/16-ota-messages/airbnb/alacarte-05-checkout.md",
    "vault/16-ota-messages/airbnb/all-01-confirmation.md",
    "vault/16-ota-messages/booking/15nuocman5-03-checkin.md",
    "vault/16-ota-messages/booking/181tohienthanh-03-checkin.md",
    "vault/16-ota-messages/booking/25anthuong11-03-checkin.md",
    "vault/16-ota-messages/booking/41lehycat-03-checkin.md",
    "vault/16-ota-messages/booking/alacarte-03-checkin-305.md",
    "vault/16-ota-messages/booking/alacarte-03-checkin-404.md",
    "vault/16-ota-messages/booking/alacarte-03-checkin-502.md",
    "vault/16-ota-messages/booking/alacarte-05-checkout.md",
    "vault/16-ota-messages/booking/all-01-confirmation.md",
    "vault/16-ota-messages/booking/villa-05-checkout.md"
   ],
   "json_url": "/data/message-templates.json",
   "csv_url": "/data/message-templates.csv",
   "html_url": "/status/booking/messages/"
  },
  {
   "id": "competitors_25anthuong11",
   "name": "Airbnb competitors of 25 An Thượng 11",
   "description": "The 34 Airbnb listings watched as competitors of 25 An Thượng 11: bedrooms, guests, rating, reviews, average price next 60 days, calendar booked %, distance.",
   "category": "competitors",
   "subcategory": null,
   "platform": "airbnb",
   "grain": "one competitor listing",
   "keywords": [
    "competitor",
    "competitors",
    "doi thu",
    "compset",
    "competitive set",
    "25anthuong11",
    "25 an thuong 11",
    "market"
   ],
   "derived": true,
   "rows": 34,
   "fields": [
    {
     "name": "platform",
     "type": "string",
     "description": "Always 'airbnb'",
     "filled": 34,
     "example": "airbnb"
    },
    {
     "name": "for_property",
     "type": "string",
     "description": "Property the competitive set belongs to",
     "filled": 34,
     "example": "25anthuong11"
    },
    {
     "name": "listing_id",
     "type": "integer",
     "description": "Airbnb listing ID",
     "filled": 34,
     "example": "1483355559414643120"
    },
    {
     "name": "name",
     "type": "string",
     "description": "Listing title",
     "filled": 34,
     "example": "200sq 4BR | Near My Khe Beach | Center | Full AC"
    },
    {
     "name": "bedrooms",
     "type": "integer",
     "description": "Bedrooms",
     "filled": 34,
     "example": 4
    },
    {
     "name": "guests",
     "type": "integer",
     "description": "Max guests",
     "filled": 34,
     "example": 10
    },
    {
     "name": "rating",
     "type": "number",
     "description": "Airbnb rating",
     "filled": 31,
     "example": 4.99
    },
    {
     "name": "reviews",
     "type": "integer",
     "description": "Number of reviews",
     "filled": 34,
     "example": 80
    },
    {
     "name": "avg_price_60d_vnd",
     "type": "integer",
     "description": "Average nightly price over the next 60 days (VND, Airbnb search, after discounts, before fees)",
     "filled": 32,
     "example": 2966667
    },
    {
     "name": "calendar_booked_60d_pct",
     "type": "integer",
     "description": "% of the next 60 nights not available",
     "filled": 34,
     "example": 50
    },
    {
     "name": "distance_m",
     "type": "integer",
     "description": "Distance to 25 An Thượng 11 (m)",
     "filled": 34,
     "example": 208
    },
    {
     "name": "airbnb_url",
     "type": "string",
     "description": "Airbnb listing URL",
     "filled": 34,
     "example": "https://www.airbnb.com/rooms/1483355559414643120"
    },
    {
     "name": "snapshot_date",
     "type": "date",
     "description": "Date the data was read",
     "filled": 34,
     "example": "2026-09-27"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault file",
     "filled": 34,
     "example": "vault/18-ota-listings/properties/25anthuong11/compset/airbnb-compset-2026-09-27.json"
    }
   ],
   "updated_at": "2026-09-27",
   "source": "vault/18-ota-listings/properties/25anthuong11/compset/airbnb-compset-2026-09-27.json",
   "json_url": "/data/competitors-25anthuong11.json",
   "csv_url": "/data/competitors-25anthuong11.csv",
   "html_url": "/competitors/25anthuong11/"
  },
  {
   "id": "reports",
   "name": "Dated reports and audits",
   "description": "Index of dated audit reports (date, title, type) with links.",
   "category": "reports",
   "subcategory": null,
   "platform": "all",
   "grain": "one report",
   "keywords": [
    "report",
    "audit",
    "bao cao",
    "snapshot"
   ],
   "derived": true,
   "rows": 22,
   "fields": [
    {
     "name": "id",
     "type": "string",
     "description": "Report key",
     "filled": 22,
     "example": "2026-09-03-danh-muc-toan-kenh"
    },
    {
     "name": "date",
     "type": "date",
     "description": "Report date",
     "filled": 22,
     "example": "2026-09-03"
    },
    {
     "name": "title",
     "type": "string",
     "description": "Report title",
     "filled": 22,
     "example": "Soát danh mục OTA toàn kênh — 03/09/2026"
    },
    {
     "name": "kind",
     "type": "string",
     "description": "article · data_folder · data_file",
     "filled": 22,
     "example": "article"
    },
    {
     "name": "html_url",
     "type": "string",
     "description": "Report page",
     "filled": 22,
     "example": "/library/reports/2026-09-03-danh-muc-toan-kenh/"
    },
    {
     "name": "source",
     "type": "string",
     "description": "Vault path",
     "filled": 22,
     "example": "vault/18-ota-listings/audits/2026-09-03-danh-muc-toan-kenh.md"
    }
   ],
   "updated_at": "2026-09-28",
   "source": [
    "vault/18-ota-listings/audits/2026-09-03-danh-muc-toan-kenh.md",
    "vault/18-ota-listings/audits/2026-09-05-airbnb-corpus.json",
    "vault/18-ota-listings/audits/2026-09-05-airbnb-listing-audit-corpus.md",
    "vault/18-ota-listings/audits/2026-09-05-booking-305-audit-corpus.md",
    "vault/18-ota-listings/audits/2026-09-08-booking-404-vs-305.md",
    "vault/18-ota-listings/audits/2026-09-12-25at11-opportunity-center.md",
    "vault/18-ota-listings/audits/2026-09-12-booking-reviews-all.md",
    "vault/18-ota-listings/audits/2026-09-14-airbnb-hof-migration",
    "vault/18-ota-listings/audits/2026-09-15-booking-promotions",
    "vault/18-ota-listings/audits/2026-09-15-cleaning-fee-strategy.md",
    "vault/18-ota-listings/audits/2026-09-15-post-mapping-verify",
    "vault/18-ota-listings/audits/2026-09-15-price-parity",
    "vault/18-ota-listings/audits/2026-09-15-price-parity-airbnb-vs-booking.md",
    "vault/18-ota-listings/audits/2026-09-15-pricing-setup-review.md",
    "vault/18-ota-listings/audits/2026-09-16-agoda-305-audit.md",
    "vault/18-ota-listings/audits/2026-09-23-booking-7-listing-report.md",
    "vault/18-ota-listings/audits/2026-09-25-pricelabs-minstay.json",
    "vault/18-ota-listings/audits/2026-09-26-agoda-search-rank.md",
    "vault/18-ota-listings/audits/2026-09-26-booking-search-rank.md",
    "vault/18-ota-listings/audits/2026-09-27-25at11-compset",
    "vault/18-ota-listings/audits/2026-09-27-pricelabs-current-setup",
    "vault/18-ota-listings/audits/2026-09-28-agoda-promo-badges"
   ],
   "json_url": "/data/reports.json",
   "csv_url": "/data/reports.csv",
   "html_url": "/library/reports/"
  }
 ]
}