OnSeasonChannel API

Quickstart

Make your first staging booking in four requests.

In this quickstart we find a staging property, quote a three-night stay, book it, and cancel it. You need the staging API key that OnSeason sent you and a terminal with curl and jq.

Keep the API key on your servers. Never send it from a browser or a mobile app.

Set your key

Export the key and the staging base URL so the commands below can use them:

export ONSEASON_API_KEY="<your staging key>"
export ONSEASON_BASE_URL="https://zepl-staging.calry.app"

Search for a stay

Search near Paris for four guests. Change the dates to a range in the future.

curl --get "$ONSEASON_BASE_URL/api/v1/search" \
  --header "x-calry-api-key: $ONSEASON_API_KEY" \
  --data-urlencode "checkInDate=2026-12-10" \
  --data-urlencode "checkOutDate=2026-12-13" \
  --data-urlencode "guests=4" \
  --data-urlencode "location=48.8566,2.3522" \
  --data-urlencode "radius=25" \
  --data-urlencode "displayCurrency=EUR" \
  | jq '.listings[] | {id, name, avgNightlyPrice, totalPrice}'

You see one object per matching listing. Copy an id. If the list is empty, widen radius or remove location, because the staging catalogue is small.

Quote the stay

Ask for a firm price for the listing you picked:

curl --request POST "$ONSEASON_BASE_URL/api/v1/quote?displayCurrency=EUR" \
  --header "x-calry-api-key: $ONSEASON_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "listingID": "<listing id>",
    "checkInDate": "2026-12-10",
    "checkOutDate": "2026-12-13",
    "guests": 4,
    "guestCountInfo": { "adults": 3, "children": 1, "infants": 0, "pets": 0 }
  }' > quote.json

jq '{totalPrice, currency, quoteTokenExpiresAt, terms: .cancellationPolicy.description}' quote.json

You see the total, its currency, the token expiry, and a one-line summary of the cancellation terms. The token is valid for 15 minutes, so do the next step now.

Book it

Send the token and the quoted prices with the guest details:

jq '{
  quoteToken, listingID, checkInDate, checkOutDate, guests, currency, totalPrice,
  totalBasePrice: .components.basePrice.amount,
  totalFeePrice: (.components.fees.amount // 0),
  totalTaxPrice: (.components.taxes.amount // 0),
  adults: 3, children: 1, infants: 0, pets: 0,
  guest: { firstName: "Jane", lastName: "Doe", email: "jane.doe@example.com", phone: "+33123456789" },
  notes: "", source: "<your channel name>", reservationType: "INSTANT_BOOKING"
}' quote.json > reservation-request.json

curl --request POST "$ONSEASON_BASE_URL/api/v1/reservation?displayCurrency=EUR" \
  --header "x-calry-api-key: $ONSEASON_API_KEY" \
  --header "Content-Type: application/json" \
  --data @reservation-request.json \
  | jq '{id, providerReservationID, status, totalPrice, currency}'

You see "status": "CONFIRMED". Store id and providerReservationID. You need id to read or cancel the booking.

Cancel it

Cancel the staging booking so the dates free up again:

curl --request DELETE "$ONSEASON_BASE_URL/api/v1/reservation/<reservation id>" \
  --header "x-calry-api-key: $ONSEASON_API_KEY" \
  | jq

You see "status": "CANCELLED" and a cancellationCharge worked out from the terms you were quoted. Some PMSs return CANCELLATION_PENDING instead. Cancel a reservation explains why.

Next steps

On this page