Reserve

For partners

D-Max B2B API

Search, price, book and cancel Dhananjaya Hospitality's resorts and private pool villas in Bali from your own system, at your contract prices, with live availability and instant confirmation.

Getting started

  1. Become a partner at dhananjaya.id/partners and sign a contract (net rates or a percentage off the public price).
  2. Ask reservation@dhananjaya.id for API access. You receive a test key first (dmx_test_…): it reads live availability and prices but never creates a booking. A live key (dmx_live_…) follows once your integration is checked.
  3. Keep the key on your server. It is shown to you once; if it leaks, ask us to switch it off and issue a new one.

Every call is a POST to one URL, with JSON in and out:

POST https://wqmcxlcjqlpsnvaxvhgm.supabase.co/functions/v1/dmax-b2b-api
X-Api-Key: dmx_test_…
Content-Type: application/json

{ "action": "availability", ... }

Prices are in IDR, net to you, tax and service included. Dates are YYYY-MM-DD, Bali time (UTC+8).

hotels

Static content of every property your key may sell: address, coordinates, description, facilities, house rules, images, room types and rate plans. Cache it and refresh daily.

{ "action": "hotels" }               // or { "action": "hotels", "hotels": ["AKSH", "VELA"] }
{
  "partner": "Your company",
  "environment": "test",
  "distribution": { "b2b_resale": true, "booking_com": false, ... },
  "hotels": [{
    "hotel_code": "AKSH", "name": "Akshaya Resort Ubud", "category": "...",
    "address": { "street": "...", "city": "Gianyar", "country": "ID" },
    "geo": { "latitude": -8.4, "longitude": 115.3 },
    "images": ["https://..."],
    "room_types": [{ "code": "...", "name": "...", "max_adults": 2, "max_occupancy": 3 }],
    "rate_plans": [{ "code": "...", "name": "...", "breakfast_included": true }]
  }]
}

availability

Bookable offers at your net price. Up to 30 nights and 5 rooms per search.

{ "action": "availability", "check_in": "2026-12-10", "check_out": "2026-12-13",
  "rooms": 1, "adults": 2, "children": 0, "hotels": ["AKSH"] }   // hotels is optional
{
  "check_in": "2026-12-10", "check_out": "2026-12-13", "currency": "IDR",
  "hotels": [{ "hotel_code": "AKSH", "hotel_name": "Akshaya Resort Ubud", "offers": [{
    "offer_id": "eyJo...",
    "room_type": { "code": "...", "name": "One Bedroom Pool Villa" },
    "rate_plan": { "code": "...", "name": "Room with breakfast", "breakfast_included": true },
    "nights": 3, "rooms": 1, "adults": 2, "rooms_available": 4,
    "net_total": 5100000, "net_per_room_per_night": 1700000,
    "payment": "credit",
    "cancellation_policy": "...",
    "distribution": { ... }
  }]}]
}

prebook

Checks one offer again just before you take the guest's payment. Returns the same offer shape with the current net_total.

{ "action": "prebook", "offer_id": "eyJo..." }

book

Confirms the booking on your credit facility and sends it to the hotel at once. expected_total is the net_total you agreed to; if the price moved by more than IDR 1,000 you get 409 price_changed with the new total and nothing is booked.

{ "action": "book", "offer_id": "eyJo...", "expected_total": 5100000,
  "guest": { "name": "Jane Doe", "email": "jane@example.com", "phone": "+61..." },
  "partner_reference": "YOUR-REF-123", "special_requests": "Late arrival" }
{ "status": "confirmed", "confirmation_number": "SH-261210-0421", "partner_reference": "YOUR-REF-123", ... }

With a test key the response carries "test": true and a TEST-… number; no booking is made.

booking

One of your bookings and its current status.

{ "action": "booking", "confirmation_number": "SH-261210-0421" }

cancel

Cancels one of your bookings and releases the room at the hotel. Cancellation fees, if any, follow your contract's cancellation policy. Cancelling an already cancelled booking returns it unchanged.

{ "action": "cancel", "confirmation_number": "SH-261210-0421" }

Distribution rules

Each key carries the channels where you may resell our properties, agreed in your contract and returned with every offer as distribution. A channel set to false must not show our properties or prices. Resale outside the agreed channels ends API access.

FieldChannel
b2b_resaleResale to other agents and tour operators
public_websitesYour own consumer website
packages_onlyOnly inside a package, never as a room-only price
booking_com, agoda, expedia, other_otasResale on online travel agencies
metasearchGoogle Hotels, Trivago, Kayak, Tripadvisor

Errors

Errors come back as { "error": { "code": "...", "message": "..." } } with an HTTP status:

StatusCodeMeaning
400bad_dates, bad_offer, expected_total_required, guest_requiredThe request is missing a field or a field is not valid.
401unauthorizedThe X-Api-Key header is missing, not valid, or the key has been switched off.
402prepayment_requiredYour contract is on prepayment. Booking through the API needs a credit facility or a deposit.
403partner_inactiveYour partner account is suspended.
404hotel_unavailable, not_foundThe hotel is not available to your key, or the booking is not yours.
409sold_out, price_changed, no_contract, not_contractedAvailability or price moved since your search, or the room is outside your contract. Search again.

Support

Integration questions and API access: reservation@dhananjaya.id.