قائمة وثائق المطورين

نقاط الوصول

8 نقاط وصول للقراءة فقط ضمن https://jokerprice.com/api/v1. تتطلب جميعها Authorization: Bearer ss_…، وتُرجع جميعها JSON.

ملخص

نقطة الوصولالغرضالمدخلات الإلزامية
GET/api/v1/marketsعرض الأسواقلا شيء
GET/api/v1/markets/{slug}تقرير سوق واحدslug
GET/api/v1/metricsمؤشرات الأداءcity، أو north وsouth وeast وwest
GET/api/v1/trendsالاتجاهات اليوميةcity
GET/api/v1/paceوتيرة الحجز في السوقcity
GET/api/v1/eventsالمناسبات والعطلاتلا شيء
GET/api/v1/listingsعرض العقاراتcity
POST/api/v1/estimateتقدير الإيراداتlatitude, longitude

عرض الأسواق

GET/api/v1/markets

كل وجهة تضم 20 عقارًا مجمّعًا على الأقل، مرتبة حسب عدد العقارات. تكون قيمة tracker هي null إلى أن تتوفر للوجهة تقويمات متتبَّعة، ولا تصبح أرقام الإشغال ومتوسط السعر اليومي والإيرادات فيها ذات دلالة إلا عندما تكون قيمة maturity هي "estimating".

لا توجد معاملات.

مثال على الطلب

سطر الأوامر
curl -H "Authorization: Bearer $JOKERPRICE_API_KEY" \
  "https://jokerprice.com/api/v1/markets"

مثال على الاستجابة

200 OK, application/json
{
  "markets": [
    {
      "slug": "riyadh",
      "name": "Riyadh",
      "latitude": 24.7136,
      "longitude": 46.6753,
      "listings": 9412,
      "sources": {
        "gathern": 7650,
        "airbnb": 1762
      },
      "nightly": {
        "median": 420,
        "p25": 300,
        "p75": 650
      },
      "tracker": {
        "maturity": "estimating",
        "trackingDays": 41,
        "tracked": 812,
        "occupancy": 0.47,
        "adr": 512.4,
        "revpar": 240.8,
        "monthlyRevenuePerListing": 7225,
        "onTheBooks": 0.18
      }
    },
    {
      "slug": "jeddah",
      "name": "Jeddah",
      "latitude": 21.4858,
      "longitude": 39.1925,
      "listings": 6120,
      "sources": {
        "gathern": 5011,
        "airbnb": 1109
      },
      "nightly": {
        "median": 450,
        "p25": 320,
        "p75": 700
      },
      "tracker": null
    }
  ]
}

أهم الحقول

الحقلالمعنى
slugالمعرّف الذي تستخدمه جميع نقاط الوصول الأخرى.
listingsعدد العقارات المجمّعة للوجهة من جميع المصادر.
sourcesعدد العقارات من Gathern وAirbnb.
nightlyالوسيط والمئين الخامس والعشرون والمئين الخامس والسبعون للسعر المعروض بالريال السعودي.
trackerملخص تتبّع التقويمات خلال آخر 90 ليلة، أو null.

تقرير سوق واحد

GET/api/v1/markets/{slug}

التقرير الكامل الذي تستند إليه صفحة بيانات السوق العامة (/market-data): العرض حسب المصدر، وأرباع السعر المعروض، ووسيط السعر المعروض حسب عدد غرف النوم (للمجموعات التي تضم 5 عقارات فأكثر)، وتوزيع أنواع العقارات، ومتوسط التقييم (0–10)، وعند توفر التتبّع: الإشغال لآخر 90 يومًا، ومتوسط السعر اليومي (ADR)، والإيراد لكل وحدة متاحة (RevPAR)، والإيراد لكل عقار، مع تفصيل حسب أيام الأسبوع والأشهر والمهلة المسبقة للحجز.

المعاملات

المعاملالموضعإلزاميالوصف
slugالمسارنعممعرّف السوق بأحرف صغيرة كما يرد في «عرض الأسواق»، مثل riyadh وdubai وcairo.

مثال على الطلب

سطر الأوامر
curl -H "Authorization: Bearer $JOKERPRICE_API_KEY" \
  "https://jokerprice.com/api/v1/markets/riyadh"

مثال على الاستجابة

200 OK, application/json
{
  "market": {
    "slug": "riyadh",
    "name": "Riyadh",
    "latitude": 24.7136,
    "longitude": 46.6753,
    "listings": 9412,
    "sources": {
      "gathern": 7650,
      "airbnb": 1762
    },
    "nightly": {
      "median": 420,
      "p25": 300,
      "p75": 650
    },
    "bedrooms": [
      {
        "bedrooms": 1,
        "listings": 2210,
        "median": 300
      },
      {
        "bedrooms": 2,
        "listings": 3105,
        "median": 420
      },
      {
        "bedrooms": 3,
        "listings": 1980,
        "median": 600
      }
    ],
    "types": [
      {
        "type": "Apartment",
        "count": 5120
      },
      {
        "type": "Chalet",
        "count": 1870
      },
      {
        "type": "Villa",
        "count": 990
      }
    ],
    "rating": 8.9,
    "tracker": {
      "maturity": "estimating",
      "trackingDays": 41,
      "tracked": 812,
      "occupancy": 0.47,
      "adr": 512.4,
      "revpar": 240.8,
      "monthlyRevenuePerListing": 7225,
      "onTheBooks": 0.18,
      "observedNights": 30122,
      "byMonth": [
        {
          "month": "2026-09",
          "period": "observed",
          "bookedNights": 11920,
          "nights": 24800,
          "occupancy": 0.48,
          "adr": 505
        }
      ],
      "byWeekday": [
        {
          "weekday": 4,
          "bookedNights": 2410,
          "nights": 3900,
          "occupancy": 0.62,
          "adr": 560
        }
      ],
      "leadTimes": [
        {
          "label": "0–1 days",
          "nights": 3120
        },
        {
          "label": "2–7 days",
          "nights": 4800
        }
      ]
    }
  }
}

أهم الحقول

الحقلالمعنى
bedroomsوسيط السعر المعروض لكل عدد من غرف النوم، للمجموعات التي تضم 5 عقارات على الأقل.
typesحتى 8 أنواع من العقارات مرتبة حسب عدد العقارات.
ratingمتوسط التقييم من 10.
tracker.byWeekdayاليوم 0 هو الأحد. الليالي المحجوزة والليالي المرصودة والإشغال ومتوسط السعر اليومي.
tracker.byMonthقيمة period هي observed أو mixed أو ahead (ليالٍ مستقبلية محجوزة مسبقًا).
tracker.leadTimesالليالي المحجوزة موزعة حسب المهلة المسبقة للحجز.

مؤشرات الأداء

GET/api/v1/metrics

الإشغال ومتوسط السعر اليومي والإيرادات من التتبّع اليومي للتقويمات، لمدينة أو لمستطيل على الخريطة. يغطي past الليالي السابقة لليوم، ويمثل forward نسبة الليالي القادمة المحجوزة مسبقًا، ويضم series صفًا لكل ليلة. وتبقى قيمة maturity هي "collecting" حتى يتوفر سجل لمدة 7 أيام و100 ليلة عقار مرصودة.

المعاملات

المعاملالموضعإلزاميالوصف
cityالاستعلاملامعرّف السوق أو اسمه. أرسل city، أو المعاملات الأربعة north وsouth وeast وwest معًا.
north, south, east, westالاستعلاملامستطيل بالدرجات العشرية، لا يتجاوز عرضه 5 درجات.
past_daysالاستعلاملاعدد الليالي السابقة، من 1 إلى 365. القيمة الافتراضية 30.
forward_daysالاستعلاملاعدد الليالي القادمة، من 1 إلى 365. القيمة الافتراضية 60.

مثال على الطلب

سطر الأوامر
curl -H "Authorization: Bearer $JOKERPRICE_API_KEY" \
  "https://jokerprice.com/api/v1/metrics?city=riyadh&past_days=30&forward_days=60"

# Or a map rectangle
curl -H "Authorization: Bearer $JOKERPRICE_API_KEY" \
  "https://jokerprice.com/api/v1/metrics?north=24.85&south=24.70&east=46.80&west=46.60"

مثال على الاستجابة

200 OK, application/json
{
  "metrics": {
    "source": "all",
    "today": "2026-10-28",
    "from": "2026-09-28",
    "to": "2026-12-27",
    "trackingDays": 41,
    "maturity": "estimating",
    "listings": {
      "tracked": 812,
      "checked": 806,
      "medianAskingNightly": 430,
      "bedrooms": [
        {
          "value": "2",
          "count": 301
        },
        {
          "value": "1",
          "count": 244
        }
      ],
      "types": [
        {
          "value": "6",
          "count": 520
        },
        {
          "value": "2",
          "count": 160
        }
      ]
    },
    "past": {
      "nights": 24180,
      "bookedNights": 11365,
      "occupancy": 0.47,
      "adr": 512.4,
      "revpar": 240.8,
      "monthlyRevenuePerListing": 7225
    },
    "forward": {
      "nights": 48360,
      "bookedNights": 8705,
      "onTheBooks": 0.18
    },
    "byWeekday": [
      {
        "weekday": 0,
        "bookedNights": 1450,
        "nights": 3460,
        "occupancy": 0.42,
        "adr": 480
      },
      {
        "weekday": 4,
        "bookedNights": 2410,
        "nights": 3460,
        "occupancy": 0.7,
        "adr": 560
      }
    ],
    "byMonth": [
      {
        "month": "2026-10",
        "period": "mixed",
        "bookedNights": 10220,
        "nights": 21900,
        "occupancy": 0.47,
        "adr": 510
      }
    ],
    "leadTimes": [
      {
        "label": "0–1 days",
        "nights": 3120
      },
      {
        "label": "2–7 days",
        "nights": 4800
      },
      {
        "label": "8–14 days",
        "nights": 1900
      }
    ],
    "series": [
      {
        "night": "2026-10-27",
        "past": true,
        "booked": 401,
        "eligible": 806,
        "occupancy": 0.4975,
        "adr": 498.2
      }
    ]
  }
}

أهم الحقول

الحقلالمعنى
maturity"collecting" أو "estimating". اعتبر أرقام الإشغال ومتوسط السعر اليومي استرشادية فقط ما دامت البيانات قيد الجمع.
pastالليالي المرصودة، والليالي المحجوزة، والإشغال، ومتوسط السعر اليومي، والإيراد لكل وحدة متاحة، وناتج متوسط السعر اليومي × الإشغال × 30.
forward.onTheBooksنسبة الليالي القادمة المرصودة المحجوزة بالفعل.
listingsالعقارات المتتبَّعة ضمن النطاق، ووسيط سعرها المعروض، وتوزيعها حسب عدد غرف النوم والنوع (معرّفات الأنواع).
seriesصف لكل ليلة: العقارات المحجوزة والمؤهلة، والإشغال، ومتوسط السعر اليومي.

وتيرة الحجز في السوق

GET/api/v1/pace

وتيرة الحجز من اللقطات اليومية. لكل تاريخ إقامة خلال الأيام الثلاثين القادمة: يمثل onTheBooks نسبة الليالي المحجوزة من الليالي المتتبَّعة في أحدث لقطة، ويمثل pickup7 وpickup14 مقدار ارتفاع هذه النسبة خلال الأيام السبعة والأربعة عشر السابقة. ويحسب curve متوسط نسبة الحجز حسب عدد الأيام السابقة للوصول. وتبقى قيمة status هي "collecting" حتى تتوفر لقطات 7 أيام.

المعاملات

المعاملالموضعإلزاميالوصف
cityالاستعلامنعممعرّف السوق أو اسمه.

مثال على الطلب

سطر الأوامر
curl -H "Authorization: Bearer $JOKERPRICE_API_KEY" \
  "https://jokerprice.com/api/v1/pace?city=dubai"

مثال على الاستجابة

200 OK, application/json
{
  "pace": {
    "destination": "dubai",
    "today": "2026-11-20",
    "snapshotDays": 21,
    "minSnapshotDays": 7,
    "basis": "tracked public calendars (estimate)",
    "status": "ready",
    "latestSnapshot": "2026-11-20",
    "stayDates": [
      {
        "stayDate": "2026-11-27",
        "onTheBooks": 0.41,
        "eligible": 1180,
        "pickup7": 0.09,
        "pickup14": 0.15
      }
    ],
    "curve": [
      {
        "lead": 0,
        "onTheBooks": 0.52,
        "stayDates": 14
      },
      {
        "lead": 7,
        "onTheBooks": 0.4,
        "stayDates": 14
      }
    ]
  }
}

أهم الحقول

الحقلالمعنى
status"collecting" أو "ready".
stayDatesstayDate وonTheBooks وعدد الليالي المتتبَّعة المؤهلة وpickup7 وpickup14 (وقيمتهما null إن لم يتوفر سجل بهذا الطول).
curvelead (عدد الأيام السابقة للوصول، من 0 إلى 30)، ومتوسط onTheBooks، وعدد تواريخ الإقامة التي يستند إليها المتوسط؛ والقيمة null إذا قل عددها عن ثلاثة.
basisتأتي النسب من التقويمات العامة، لذا فهي تقديرات.

المناسبات والعطلات

GET/api/v1/events

تقويم العطل والمناسبات المحلية الموثّق المصادر، الذي تعتمد عليه قواعد التسعير حسب المناسبات. لكل مناسبة اسم بالعربية والإنجليزية، ونوع، والمدن التي تشملها (all-sa لجميع مدن السعودية)، وتاريخا بداية ونهاية شاملان، ودرجة تأكيد، ومصدر. وقد تتغير التواريخ المصنفة "expected" (مثل التواريخ الهجرية قبل إعلان رؤية الهلال).

المعاملات

المعاملالموضعإلزاميالوصف
cityالاستعلاملامعرّف السوق أو اسمه؛ احذفه لعرض جميع المناسبات.
from, toالاستعلاملانطاق التواريخ بصيغة YYYY-MM-DD، وتُرجع المناسبات التي تتقاطع مع هذا النطاق.
kindالاستعلاملاأنواع مفصولة بفواصل: religious وnational وschool وseason وsports وculture وbusiness.

مثال على الطلب

سطر الأوامر
curl -H "Authorization: Bearer $JOKERPRICE_API_KEY" \
  "https://jokerprice.com/api/v1/events?city=riyadh&from=2026-11-01&to=2027-03-31"

مثال على الاستجابة

200 OK, application/json
{
  "version": "2026-10-28.2",
  "lastReviewed": "2026-10-28",
  "coverage": {
    "start": "2026-01-01",
    "end": "2027-12-31"
  },
  "certainty": {
    "official": "Published by the authority or organiser itself on its own site.",
    "expected": "Computed (for example from the Umm al-Qura calendar), not fully announced, or reported only in the news; may move."
  },
  "count": 1,
  "events": [
    {
      "id": "saudi-national-day-2026",
      "name": {
        "en": "Saudi National Day",
        "ar": "اليوم الوطني السعودي"
      },
      "kind": "national",
      "cities": [
        "all-sa"
      ],
      "start": "2026-09-23",
      "end": "2026-09-23",
      "certainty": "official",
      "sourceUrl": "https://www.my.gov.sa/",
      "verifiedAt": "2026-10-28"
    }
  ]
}

أهم الحقول

الحقلالمعنى
eventsid، والاسم (en وar)، وkind، وcities، وstart، وend، وcertainty، وsourceUrl، وverifiedAt، مع ملاحظة اختيارية.
certaintyمعنى القيمتين official وexpected.
version, lastReviewedإصدار التقويم وتاريخ آخر مراجعة له.

عرض العقارات

GET/api/v1/listings

العقارات المجمّعة لوجهة ما، مرتبة حسب listingKey. قيمة source هي gathern أو airbnb أو agoda. ويمثل nightly آخر سعر معروض رُصد بالريال السعودي قبل الرسوم، والتقييم rating من 10 (تُضاعف تقييمات Airbnb). واصل الطلب مع cursor=nextCursor حتى تصبح قيمة nextCursor هي null.

المعاملات

المعاملالموضعإلزاميالوصف
cityالاستعلامنعممعرّف السوق أو اسمه.
limitالاستعلاملاعدد العقارات في كل صفحة، من 1 إلى 500. القيمة الافتراضية 100.
cursorالاستعلاملاقيمة nextCursor من الصفحة السابقة.

مثال على الطلب

سطر الأوامر
curl -H "Authorization: Bearer $JOKERPRICE_API_KEY" \
  "https://jokerprice.com/api/v1/listings?city=riyadh&limit=100"

مثال على الاستجابة

200 OK, application/json
{
  "listings": [
    {
      "id": "48213",
      "source": "gathern",
      "sourceListingId": "48213",
      "listingKey": "gathern:48213",
      "title": "Modern 2BR in Al Malqa",
      "city": "Riyadh",
      "district": "Al Malqa",
      "typeId": "6",
      "latitude": 24.8094,
      "longitude": 46.6112,
      "bedrooms": 2,
      "area": 120,
      "nightly": 420,
      "rating": 9.4,
      "reviews": 87,
      "url": "https://gathern.co/view/1234/unit/48213",
      "updatedAt": "2026-10-27T21:14:03.000Z"
    }
  ],
  "nextCursor": "gathern:48213"
}

أهم الحقول

الحقلالمعنى
listingKeyبصيغة source:id. ثابت عبر عمليات الجمع ويُستخدم مؤشرًا للصفحات.
typeIdمعرّف نوع العقار (الجدول أدناه).
nightlyآخر سعر ليلي معروض بالريال السعودي، قبل الرسوم.
rating, reviewsالتقييم من 10 وعدد المراجعات، حيث تعرضهما المنصة.
updatedAtآخر وقت جُمع فيه العقار.

تقدير الإيرادات

POST/api/v1/estimate

حاسبة الإيرادات. العقارات المماثلة هي العقارات المحفوظة ضمن نصف القطر التي تطابق عدد غرف النوم والنوع. يعتمد متوسط السعر اليومي على أسعار الليالي المحجوزة في التقويمات المتتبَّعة القريبة (أو ضمن 20 كم) متى اكتمل نضج البيانات، وإلا فعلى وسيط السعر المعروض للعقارات المماثلة. وفي غياب إشغال مقيس تكون قيمة projection هي null، ويضم scenarios سيناريوهات إشغال بنسب 40٪ و55٪ و70٪. أضف كائن investment لتحصل على التدفق النقدي ومعدل العائد (Cap rate) وفترة الاسترداد للتوقع نفسه.

المعاملات

المعاملالموضعإلزاميالوصف
latitude, longitudeجسم الطلبنعمموقع العقار بالدرجات العشرية.
radiusKmجسم الطلبلانصف قطر البحث عن العقارات المماثلة، من 0.5 إلى 20 كم. القيمة الافتراضية 3.
bedroomsجسم الطلبلاعدد غرف النوم بالضبط من 1 إلى 6، أو 0 لأي عدد. القيمة الافتراضية 0.
typeIdجسم الطلبلامعرّف نوع العقار (انظر أدناه) أو "all". القيمة الافتراضية "all".
investmentجسم الطلبلااختياري. purchasePrice، وdownPaymentPct (افتراضيًا 25)، وloanRatePct (6)، وloanTermYears (25)، وsetupCost، وmonthlyFixedCosts، وplatformFeePct (15)، وcleaningPerStay، وavgStayNights (2)، وmanagementFeePct. تُكتب النسب أعدادًا صحيحة (6 = 6٪).
compsجسم الطلبلااختياري. من 3 إلى 50 قيمة key من candidates. يستخدم التقدير عندها هذه العقارات وحدها: أسعارها المعروضة، ومتوسط سعر لياليها المحجوزة وإشغالها من تقويماتها المتتبَّعة متى بلغت 7 أيام و100 ليلة مرصودة، دون اللجوء إلى نطاق أوسع. وتُستبعد المفاتيح التي لم تعد بين العقارات المرشحة، ويُحسب عددها في selection.ignored.

أنواع العقارات

1 منتجع، 2 شاليه، 3 استراحة، 4 مزرعة، 5 مخيم، 6 شقة، 7 فيلا، 8 غرفة، 9 استوديو، 11 شقة فندقية

مثال على الطلب

سطر الأوامر
curl -X POST -H "Authorization: Bearer $JOKERPRICE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"latitude":24.7743,"longitude":46.7386,"radiusKm":3,"bedrooms":3,"typeId":"7"}' \
  "https://jokerprice.com/api/v1/estimate"

مثال على الاستجابة

200 OK, application/json
{
  "estimate": {
    "input": {
      "latitude": 24.7743,
      "longitude": 46.7386,
      "radiusKm": 3,
      "bedrooms": 3,
      "typeId": "7"
    },
    "asking": {
      "count": 64,
      "median": 900,
      "p25": 700,
      "p75": 1200
    },
    "adr": {
      "value": 860,
      "basis": "booked nights nearby"
    },
    "occupancy": {
      "value": 0.44,
      "basis": "tracked calendars nearby",
      "trackingDays": 41,
      "trackedNearby": 58
    },
    "projection": {
      "occupancy": 0.44,
      "adr": 860,
      "monthly": 11352,
      "annual": 138116
    },
    "range": {
      "low": {
        "occupancy": 0.44,
        "adr": 700,
        "monthly": 9240,
        "annual": 112420
      },
      "high": {
        "occupancy": 0.44,
        "adr": 1200,
        "monthly": 15840,
        "annual": 192720
      }
    },
    "scenarios": [],
    "seasonality": [
      {
        "month": "2026-09",
        "period": "observed",
        "occupancy": 0.41,
        "adr": 840,
        "revenue": 10332
      }
    ],
    "comparables": [
      {
        "id": "50991",
        "source": "gathern",
        "title": "Villa with pool",
        "nightly": 950,
        "bedrooms": 3,
        "typeId": "7",
        "rating": 9.1,
        "url": "https://gathern.co/view/2211/unit/50991",
        "latitude": 24.771,
        "longitude": 46.741,
        "distanceKm": 0.43
      }
    ],
    "selection": {
      "mode": "all",
      "status": "ok",
      "inRadius": 64,
      "candidates": 50,
      "kept": 50,
      "requested": 0,
      "ignored": 0,
      "minimum": 3,
      "maximum": 50
    },
    "candidates": [
      {
        "key": "gathern:50991",
        "ref": "3f9c2a7e01b4",
        "kept": true,
        "source": "gathern",
        "title": "Villa with pool",
        "url": "https://gathern.co/view/2211/unit/50991",
        "nightly": 950,
        "checkIn": "2026-10-29",
        "bedrooms": 3,
        "typeId": "7",
        "rating": {
          "value": 9.1,
          "scale": 10
        },
        "reviews": 42,
        "distanceKm": 0.43,
        "position": "within",
        "tracked": {
          "since": "2026-09-14T06:00:00.000Z",
          "observedNights": 44,
          "bookedNights": 19,
          "minNights": 30,
          "occupancy": 0.4318,
          "adr": 905
        }
      }
    ]
  }
}

أهم الحقول

الحقلالمعنى
askingعدد الأسعار المعروضة للعقارات المماثلة وأرباعها.
adr, occupancyالقيمة المستخدمة وأساسها، لتميّز الأرقام المقيسة من القيم البديلة.
projectionالإيرادات الشهرية (× 30) والسنوية (× 365)، أو null في غياب إشغال مقيس.
rangeالتوقع عند المئين الخامس والعشرين والمئين الخامس والسبعين للسعر المعروض.
scenariosسيناريوهات إشغال بنسب 40٪ و55٪ و70٪ عندما لا يكون الإشغال مقيسًا.
comparablesأقرب 12 عقارًا مماثلًا كحد أقصى، مع المسافة بالكيلومتر.
candidatesأقرب 50 عقارًا مماثلًا، لكل منها مفتاحه، وهل أُبقي، وسعره المعروض والليلة التي عُرض لها، وتقييمه على مقياس منصته، وموقع سعره من النصف الأوسط للأسعار المستخدمة، وتقويمه المتتبَّع خلال آخر 90 ليلة.
selectionهل استخدم التقدير كل العقارات المماثلة ضمن النطاق (all) أم مجموعة مختارة (chosen)، مع الأعداد؛ وتكون قيمة status هي too-few حين يطابق أقل من 3 مفاتيح مختارة.

مع مدخلات الاستثمار

جسم الطلب
{
  "latitude": 24.7743,
  "longitude": 46.7386,
  "bedrooms": 3,
  "typeId": "7",
  "investment": {
    "purchasePrice": 1500000,
    "downPaymentPct": 30,
    "loanRatePct": 6,
    "loanTermYears": 25,
    "monthlyFixedCosts": 900,
    "platformFeePct": 15,
    "cleaningPerStay": 120,
    "avgStayNights": 2
  }
}

وتتضمن الاستجابة عندئذٍ الحقل estimate.investment:

estimate.investment
{
  "investment": {
    "inputs": {
      "purchasePrice": 1500000,
      "downPaymentPct": 30,
      "loanRatePct": 6,
      "loanTermYears": 25,
      "monthlyFixedCosts": 900,
      "platformFeePct": 15,
      "cleaningPerStay": 120,
      "avgStayNights": 2,
      "setupCost": 0,
      "managementFeePct": 0
    },
    "basis": "projection",
    "projection": {
      "occupancy": 0.44,
      "adr": 860,
      "revenue": 138116,
      "expenses": {
        "platformFees": 20717,
        "management": 0,
        "cleaning": 9636,
        "fixed": 10800
      },
      "operatingExpenses": 41153,
      "netOperatingIncome": 96963,
      "capRate": 0.0646,
      "loanAmount": 1050000,
      "annualDebtService": 81181,
      "cashInvested": 450000,
      "annualCashFlow": 15782,
      "monthlyCashFlow": 1315,
      "cashOnCash": 0.0351,
      "paybackYears": 28.5,
      "breakEvenOccupancy": 0.3756
    },
    "scenarios": []
  }
}