Build a custom booking flow with the JavaScript SDK
Use the SDK when you are building a custom website or app and want to control the UI yourself.
Install
Section titled “Install”npm install @odeva/booking-sdkCreate a client
Section titled “Create a client”import { OdevaClient } from "@odeva/booking-sdk";
const odeva = new OdevaClient({ organizationSlug: "crystal-springs",});The SDK uses the production Odeva Booking API and checkout URL by default.
Search accommodation
Section titled “Search accommodation”const accommodations = await odeva.searchAccommodations({ startDate: "2026-07-01", endDate: "2026-07-08", guests: 2,});Show the returned accommodations in your own UI. Each accommodation includes units, guest limits, pricing information, images, and status fields needed for a search result or detail page.
Check availability
Section titled “Check availability”const availability = await odeva.checkAvailability({ unitId: "unit_123", startDate: "2026-07-01", endDate: "2026-07-08",});
if (availability.available) { // Continue to pricing or booking.}Calculate price
Section titled “Calculate price”const price = await odeva.calculatePrice({ unitId: "unit_123", startDate: "2026-07-01", endDate: "2026-07-08", numAdults: 2, numChildren: 0,});The result includes subtotal, charges, discounts, VAT, total amount, down payment amount, and security deposit amount.
Create a reservation
Section titled “Create a reservation”const reservation = await odeva.createReservation({ unitId: "unit_123", startDate: "2026-07-01", endDate: "2026-07-08", numAdults: 2, numChildren: 0, mainGuest: { firstName: "Alex", lastName: "Morgan", email: "alex@example.com", }, returnUrl: "https://example.com/booking-confirmation",});The reservation response includes a checkout token. Use the hosted checkout flow to collect payment when payment is required.
Server-side API keys
Section titled “Server-side API keys”Only use apiKey in trusted server-side code. Do not ship an API key in browser JavaScript.
const odeva = new OdevaClient({ apiKey: process.env.ODEVA_API_KEY, organizationSlug: "crystal-springs",});See example: https://github.com/Odeva-Labs/odeva-examples/tree/main/examples/astro-backend-proxy
Troubleshooting
Section titled “Troubleshooting”No accommodation loads
Section titled “No accommodation loads”Check that organizationSlug matches the organisation that owns the accommodation, availability, pricing, and checkout settings:
const odeva = new OdevaClient({ organizationSlug: "crystal-springs",});If you pass a custom API URL, confirm it points to the production API unless Odeva gave you a different endpoint:
https://booking.odeva.app/graphqlCheckout does not open
Section titled “Checkout does not open”Use the hosted checkout URL from the reservation response when payment is required. If you set a custom returnUrl, make sure it is a full public URL and not a local development address.
Browser code exposes an API key
Section titled “Browser code exposes an API key”Move API-key calls to server-side code. Browser code should use public booking methods that do not require a secret.
Local testing works but production does not
Section titled “Local testing works but production does not”Confirm production can reach:
https://booking.odeva.app/graphqlhttps://booking.odeva.app/checkoutAlso check browser console errors for blocked requests, content security policy rules, or mixed-content warnings.