Lappitude logo
Northern Lights with Fell on a Background

For Developers

Live availability and booking from our booking system

Lappitude Booking API

The same availability our local guides plan their tours around is open to apps and AI agents, which can also book an experience for the person they help. The endpoints are public and need no API key.

Base URL: https://api.lappitude.fi. All dates and times are Helsinki time, and dates use the yyyy-MM-dd format. Prices are in EUR and include VAT.

Machine-readable spec: OpenAPI 3.1 (/openapi.json). Questions: contact@lappitude.fi.

Booking for a user

  1. Find an open departure with the availability endpoint and check the price for the group size.
  2. Send the booking with the user's own name, email, phone and pickup location. The slot is held for them while they finish.
  3. Paying online: give the user the checkoutUrl, which we also email to them. They pay on a secure Stripe page within 30 minutes, and we email the confirmation.
  4. Paying on site: we email the user a link, and the booking counts once they confirm it within 2 hours.

Example request

POST https://api.lappitude.fi/api/activities/booking/agent

{
  "activityId": 1,
  "bookedForDate": "2026-12-15T19:00:00+02:00",
  "numberOfAdults": 2,
  "numberOfChildren": 0,
  "firstName": "Anna",
  "lastName": "Virtanen",
  "email": "anna.virtanen@example.com",
  "phoneNumber": "+358401234567",
  "pickupLocation": "Hotel name, Rovaniemi city centre",
  "specialRequests": "Celebrating an anniversary",
  "paymentOption": "online"
}

Example response

{
  "reference": "281215417",
  "paymentOption": "online",
  "total": 700,
  "holdExpiresAt": "2026-12-01T10:32:00Z",
  "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_...",
  "sessionId": "cs_live_...",
  "confirmationRequired": false,
  "message": "Give the checkout URL to the customer; we also emailed it to anna.virtanen@example.com. The booking is confirmed once they pay, which must happen within 30 minutes."
}

If the booking can't be made, the API answers 400 with a list of reasons, for example ["This time is fully booked."].

Activity availability for a month

GET /api/activities/{activityId}/dates/{month}/{year}

Returns every day of the month with its booking status and departure time slots. Dates and times are Helsinki local time.

  • activityId (path, required): Activity id. 1 = Private Northern Lights Hunting; 2 = Private Snowshoeing Experience; 3 = Private Ice Fishing Experience; 5 = Private Hiking in Autumn; 6 = Small Group Northern Lights Hunting; 7 = Small Group Ice Fishing Experience; 8 = Small Group Snowshoeing Experience.
  • month (path, required): Month, 1-12.
  • year (path, required): Four-digit year, 2020 or later.

Activity details and price for a group size

GET /api/activities/{activityId}/{participants}/{month}/{year}

Returns the activity description, duration, participant limits and prices valid in the given month. Private activities charge one price for the whole group; small group activities charge the price per person. Prices are in EUR and include VAT.

  • activityId (path, required): Activity id. 1 = Private Northern Lights Hunting; 2 = Private Snowshoeing Experience; 3 = Private Ice Fishing Experience; 5 = Private Hiking in Autumn; 6 = Small Group Northern Lights Hunting; 7 = Small Group Ice Fishing Experience; 8 = Small Group Snowshoeing Experience.
  • participants (path, required): Number of participants in the group.
  • month (path, required): Month, 1-12.
  • year (path, required): Four-digit year, 2020 or later.

Available payment options

GET /api/activities/payment-options

Tells whether paying on site is currently offered in addition to paying online.

Villa availability

GET /api/villas/{villaId}/availability

Returns, for each month in the range, whether the villa takes bookings and which nights are already taken. Villa stays are booked by enquiry on lappitude.fi.

  • villaId (path, required): Villa id: villa-tolonen, villa-manhattan.
  • fromYear (query, required): Year of the first month in the range.
  • fromMonth (query, required): First month in the range, 1-12.
  • monthsCount (query): Number of months to return, 1-36. Defaults to 12.

Book an experience for a user

POST /api/activities/booking/agent

Books a departure for the user you act for. Pick an open slot first with the calendar endpoint and send its date and time as bookedForDate. With paymentOption online, the response has a checkoutUrl, which we also email to the user: give it to them; they pay on a secure Stripe page within 30 minutes, after which the booking is confirmed. With on_site (only while getPaymentOptions allows it), we email the user a link and the booking counts only once they confirm it, within 2 hours. Always use the user's own name, email and phone number.

  • activityId (body, required): Activity id. 1 = Private Northern Lights Hunting; 2 = Private Snowshoeing Experience; 3 = Private Ice Fishing Experience; 5 = Private Hiking in Autumn; 6 = Small Group Northern Lights Hunting; 7 = Small Group Ice Fishing Experience; 8 = Small Group Snowshoeing Experience.
  • bookedForDate (body, required): Start of the chosen slot in Helsinki time with its offset, e.g. 2026-12-15T19:00:00+02:00.
  • numberOfAdults (body, required)
  • numberOfChildren (body, required)
  • childrenAges (body): Required when the activity has a minimum age and children are included.
  • firstName (body, required)
  • lastName (body, required)
  • email (body, required): The user's own email. Confirmations go here.
  • phoneNumber (body, required): Include the country code, e.g. +358 40 1234567.
  • pickupLocation (body, required): Hotel or address in Rovaniemi or Ivalo where the guide picks the group up.
  • specialRequests (body)
  • paymentOption (body)
  • partnerCode (body): Optional partner referral code.

Payment status of an online booking

GET /api/activities/booking/status

Tells whether the user has paid for a booking made with paymentOption online. Use the sessionId from the booking response.

  • sessionId (query, required): sessionId returned when the booking was made.

Health check

GET /health

Returns 200 when the API is running.