Brokeys · Developers

Brokeys API v1

A read-only REST API for villa owners and the agencies they work with: show villas, photos, availability and prices on a website, compute quotes, and sync bookings with your tools. All responses are JSON.

Quick start

  1. Get a key. Villa owners: in Brokeys open Settings → Agency access, name the key (the agency, or your own website), choose its villas and type, then copy it: it is shown only once. Agencies have no Brokeys login: ask the villa owner for a key covering the villas you sell.
  2. Send it in the x-api-key header of every request to https://brokeys.app/api/v1.
  3. Start with GET /villas to get your villa ids, then use them with the other endpoints.
curl -H "x-api-key: bk_pub_..." https://brokeys.app/api/v1/villas
const res = await fetch('https://brokeys.app/api/v1/rates?villa=VILLA_ID&from=2027-07-01&to=2027-07-31', {
  headers: { 'x-api-key': 'bk_pub_...' },
});
const { data } = await res.json(); // [{ date, available, price_eur, min_nights, checkin_allowed }, ...]

API keys

TypePrefixWhereCan read
Publishablebk_pub_Website code, browser, appsVillas, photos, availability, rates, quotes. No guest data.
Secretbk_sec_Your server onlyEverything above, plus bookings with guest names and totals.

Secret keys are rejected when the request comes from a browser (it carries an Origin header), so a leaked front-end key can never expose guest data. A key sees only the villas the owner chose when creating it: all their villas (villas added later included) or a selection. Each agency gets its own key, limited to the villas it may sell; to change the villas, the owner revokes the key and creates a new one. A revoked key stops working immediately.

For publishable keys, villa coordinates are approximate (about 1 km), so a public website never reveals the exact address. Secret keys get the exact position.

Conventions

  • Successful responses wrap the result in data. Errors return { "error": { "code", "message" } }.
  • Dates are YYYY-MM-DD, in the villa's local time (Europe/Madrid). from and to are inclusive.
  • A stay occupies the nights from check_in up to the night before check_out: the check-out day is free for the next arrival. Busy ranges use the same rule (end = first free day).
  • Amounts are in euros (EUR), exactly as configured in Brokeys.
  • Bookings from Airbnb, Booking.com and other calendars imported into Brokeys appear in availability as busy ranges; only bookings managed in Brokeys appear in /bookings.
  • Prices come from the Pricing section of Brokeys: PriceLabs nightly prices when connected, otherwise seasonal rates.

Errors & limits

HTTPCodeMeaning
400invalid_parameter, missing_parameter, range_too_largeCheck the query parameters.
401missing_api_key, invalid_api_keyKey missing, mistyped or revoked.
402subscription_inactiveThe Brokeys subscription of the villa owner who issued the key is not active.
403secret_key_requiredThe endpoint needs a secret key (bookings).
403secret_key_in_browserA secret key was sent from a browser (Origin header). Use a publishable key there.
403account_not_allowedThe key does not belong to a Brokeys villa owner account. Keys are issued only by villa owners.
404villa_not_found, not_foundVilla id unknown or not shared with this key (the owner chooses which villas each key sees), or unknown endpoint.
405method_not_allowedThe API is read-only: only GET.
429rate_limitedToo many requests: wait for the Retry-After seconds.

Each key allows 600 requests per minute. Every response carriesX-RateLimit-Limit and X-RateLimit-Remaining. Data changes a few times a day at most: cache responses on your side (5–15 minutes is plenty) instead of calling the API on every page view.

GET /villas

Publishable or secret key

Every villa the key can see, with the essentials for a listing card. price_from_night_eur is the lowest nightly price in the next 12 months (null when no price is set).

curl -H "x-api-key: bk_pub_..." https://brokeys.app/api/v1/villas

Response

{
  "data": [
    {
      "id": "3f2a9c1e-5b7d-4e8a-9c0f-1a2b3c4d5e6f",
      "name": "Can Sol",
      "tagline": "Sunset views over Es Vedrà",
      "type": "villa",
      "license": "ETV-1234-E",
      "bedrooms": 5,
      "bathrooms": 5,
      "max_guests": 10,
      "location": { "area": "Sant Josep", "district": null, "destination": "Ibiza", "country": "Spain",
                    "lat": 38.92, "lng": 1.29, "approximate": true },
      "cover_photo": "https://.../cover.jpg",
      "price_from_night_eur": 1320,
      "min_nights": 7,
      "checkin_days": "saturday"
    }
  ]
}

GET /villas/{id}

Publishable or secret key

One villa with everything for its page: description, amenities, ordered photo gallery, check-in/out times, fees and the tourist tax configuration.

curl -H "x-api-key: bk_pub_..." https://brokeys.app/api/v1/villas/3f2a9c1e-5b7d-4e8a-9c0f-1a2b3c4d5e6f

Response

{
  "data": {
    "id": "3f2a9c1e-...", "name": "Can Sol", "...": "same fields as /villas, plus:",
    "description": "A restored finca with ...",
    "amenities": ["Air Conditioning", "Swimming Pool", "Wifi", "Sea View"],
    "photos": [
      { "url": "https://.../1.jpg", "thumbnail_url": "https://.../1_t.jpg", "caption": "Pool", "room": "exterior" }
    ],
    "check_in_time": "16:00",
    "check_out_time": "10:00",
    "cleaning_service": "3 Cleanings per week",
    "fees": { "cleaning_eur": 0, "security_deposit_eur": 3000 },
    "tourist_tax": { "per_adult_night_eur": 2, "exempt_under_age": 16, "half_rate_after_nights": 8 }
  }
}

GET /availability

Publishable or secret key

Busy ranges per villa (confirmed bookings, owner blocks and imported calendars), merged. end is the first free day.

ParameterRequiredDescription
villanoVilla id. Omit to get every villa of the key.
fromnoFirst day. Default: today.
tonoLast day. Default: from + 18 months. Max range: 2 years.
curl -H "x-api-key: bk_pub_..." "https://brokeys.app/api/v1/availability?from=2027-07-01&to=2027-08-31"

Response

{
  "from": "2027-07-01",
  "to": "2027-08-31",
  "data": {
    "3f2a9c1e-...": [
      { "start": "2027-07-03", "end": "2027-07-17" },
      { "start": "2027-08-07", "end": "2027-08-14" }
    ]
  }
}

GET /rates

Publishable or secret key

A day-by-day calendar for one villa: whether the night is free, its price, the minimum stay and whether a check-in is allowed that day. Everything a booking calendar widget needs in one call.

ParameterRequiredDescription
villayesVilla id.
fromnoFirst day. Default: today.
tonoLast day. Default: from + 364 days. Max range: 550 days.

price_eur is null when the night has no price (price on request). Some villas price shorter stays differently: use /quote for the exact total of a stay.

curl -H "x-api-key: bk_pub_..." "https://brokeys.app/api/v1/rates?villa=3f2a9c1e-...&from=2027-07-01&to=2027-07-31"

Response

{
  "villa": "3f2a9c1e-...",
  "currency": "EUR",
  "data": [
    { "date": "2027-07-03", "available": true,  "price_eur": 2515, "min_nights": 7, "checkin_allowed": true },
    { "date": "2027-07-04", "available": true,  "price_eur": 2515, "min_nights": 7, "checkin_allowed": false },
    { "date": "2027-07-05", "available": false, "price_eur": 2515, "min_nights": 7, "checkin_allowed": false }
  ]
}

GET /quote

Publishable or secret key

The price of a stay and whether it can be booked as requested: availability, minimum stay, check-in/out days and capacity.

ParameterRequiredDescription
villayesVilla id.
check_inyesArrival day.
check_outyesDeparture day (1–365 nights after check_in).
adultsnoAdults. When given, the tourist tax is computed and included in total_eur.
childrennoGuests under the tourist tax exempt age. Default 0.

bookable is true only when issues is empty. Possible issues: unavailable, min_nights, checkin_day and checkout_day (Saturday-to-Saturday villas), max_guests, no_rate (some nights have no price: amounts are null) and past_dates. The security deposit is refundable and not part of the total.

curl -H "x-api-key: bk_pub_..." "https://brokeys.app/api/v1/quote?villa=3f2a9c1e-...&check_in=2027-07-03&check_out=2027-07-10&adults=6&children=2"

Response

{
  "data": {
    "villa": "3f2a9c1e-...",
    "check_in": "2027-07-03", "check_out": "2027-07-10", "adults": 6, "children": 2,
    "nights": 7,
    "min_nights": 7,
    "available": true,
    "bookable": true,
    "issues": [],
    "currency": "EUR",
    "accommodation_eur": 17605,
    "cleaning_fee_eur": 0,
    "tourist_tax_eur": 84,
    "total_eur": 17689,
    "security_deposit_eur": 3000,
    "nightly": [{ "date": "2027-07-03", "price_eur": 2515 }, "..."]
  }
}

GET /bookings

Secret key only

Confirmed stays managed in Brokeys, oldest arrival first. For server-side syncs (CRM, accounting, your own back office).

ParameterRequiredDescription
villanoVilla id. Omit for every villa of the key.
fromnoStays still running on or after this day. Default: today.
tonoStays starting on or before this day. Default: no limit.
statusnoComma-separated: booked, completed, cancelled. Default: all except cancelled.
limitno1–500, default 100.
offsetnoFor paging: pass the next_offset of the previous response.
curl -H "x-api-key: bk_sec_..." "https://brokeys.app/api/v1/bookings?from=2027-01-01&limit=100"

Response

{
  "data": [
    {
      "id": "8d1e...", "villa": "3f2a9c1e-...",
      "check_in": "2027-07-03", "check_out": "2027-07-10", "nights": 7,
      "status": "booked", "total_eur": 17605,
      "guest_name": "Ana López", "adults": 6, "children": 2,
      "direct": true, "created_at": "2026-11-02T10:14:00+00:00"
    }
  ],
  "next_offset": null
}

Example: availability calendar on your website

Runs in the browser with a publishable key. It marks free days, shows the nightly price and lets guests pick only allowed check-in days.

<div id="brokeys-calendar"></div>
<script>
  const KEY = 'bk_pub_...';
  const VILLA = '3f2a9c1e-...';
  fetch('https://brokeys.app/api/v1/rates?villa=' + VILLA, { headers: { 'x-api-key': KEY } })
    .then((r) => r.json())
    .then(({ data }) => {
      const el = document.getElementById('brokeys-calendar');
      el.innerHTML = data.slice(0, 60).map((d) =>
        '<div class="day ' + (d.available ? 'free' : 'busy') + '">' + d.date +
        (d.available && d.price_eur ? ' · €' + d.price_eur : '') +
        (d.available && d.checkin_allowed ? ' · check-in ok' : '') + '</div>'
      ).join('');
    });
</script>

When a guest picks dates, call /quote to show the exact total before sending them to your booking or contact form.

Questions or a higher rate limit? Villa owners: open a ticket from Support in Brokeys. Agencies: ask the villa owner who issued your key.