API v1Docs version 1.6.3· Last updated 2026-11-02Changelog

Nordtinde API

Connect your website or system to Nordtinde. Display homes, manage your own prices and calendar, and receive booking updates. Guests still book on Nordtinde.

Get an API key

Get started in 3 steps

  1. Sign in and open Hosting → API access.
  2. Create a key. Choose Read only to display your homes, or Read + write to edit them.
  3. Copy the key once, save it securely, and include it in each request as shown below.

Your first request

curl https://YOUR-NORDTINDE-DOMAIN/api/public/v1/listings \
  -H "Authorization: Bearer ns_live_YOUR_KEY"

Replace ns_live_YOUR_KEY with your key. A successful response is JSON with a data list of your published homes.

JavaScript and write examples

Read example (JavaScript — run on your server)

const res = await fetch("https://YOUR-NORDTINDE-DOMAIN/api/public/v1/listings", {
  headers: { Authorization: "Bearer ns_live_YOUR_KEY" },
});
const { data } = await res.json();

Write example (curl, needs a read + write key)

curl -X PATCH https://YOUR-NORDTINDE-DOMAIN/api/public/v1/listings/LISTING_ID/price \
  -H "Authorization: Bearer ns_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"nightly_price": 1500}'

Keep keys on your server, not in public website code. Booking access is an optional permission when creating a key. Full catalog access needs a separate application and approval.

What can you do?

Base URL: https://YOUR-NORDTINDE-DOMAIN/api/public/v1. All prices are in NOK.

  • GET /bookings?limit=50&offset=0Booking access

    Get dates, status, guest counts and prices for your host bookings.

    Examples and technical details

    Read reservations where you are the host, including draft homes. Requires explicit booking access on the key. Optional listing_id (UUID), status, from and to (valid YYYY-MM-DD dates). Date filters select stays overlapping [from,to); checkout on from and check-in on to are excluded. Status: requested, pending_payment, confirmed, declined, cancelled, expired, completed. limit 1–100 (default 50), offset 0–100000 (default 0). Newest first, with id as tie-breaker. Follow next_offset until null; offset pagination may shift during concurrent inserts, so deduplicate by id.

    Example response (selected fields)

    {
      "data": [{
        "id": "BOOKING_UUID", "listing_id": "LISTING_UUID", "status": "confirmed",
        "check_in": "2027-08-01", "check_out": "2027-08-05",
        "adults": 2, "children": 0, "infants": 0, "pets": 0, "nights": 4,
        "total": 5936, "currency": "NOK", "host_payout": 5141,
        "created_at": "2026-11-02T10:00:00Z", "updated_at": "2026-11-02T10:00:00Z"
      }],
      "pagination": { "limit": 50, "offset": 0, "next_offset": null }
    }
  • GET /listingsRead key

    Get your published homes and their basic details.

    Examples and technical details

    Your published listings (summary fields, no photos/amenities/house_rules).

    Example response (selected fields)

    {
      "data": [
        {
          "id": "130f42b8-…",
          "title": "Fjord-edge cabin with sauna",
          "city": "Balestrand",
          "nightly_price": 1200,
          "cleaning_fee": 500,
          "instant_book": true,
          "cover_photo": "https://…/cover.jpg",
          "booking_url": "https://nordtinde…/stays/130f42b8-…"
        }
      ]
    }
  • GET /listings/{id}Read key

    Get one of your homes with photos, amenities and house rules.

    Examples and technical details

    One listing with photos, amenities and house rules.

    Example response (selected fields)

    {
      "data": {
        "id": "130f42b8-…",
        "title": "Fjord-edge cabin with sauna",
        "description": "Timber cabin on the water's edge …",
        "photos": [{ "url": "https://…/1.jpg", "caption": "Living room" }],
        "amenities": ["Sauna", "Wi-Fi", "Fireplace"],
        "house_rules": ["No smoking", "Quiet hours 23:00–07:00"],
        "booking_url": "https://nordtinde…/stays/130f42b8-…"
      }
    }
  • GET /listings/{id}/availability?from=YYYY-MM-DD&to=YYYY-MM-DDRead key

    Check which nights are available and what they cost.

    Examples and technical details

    Each night with available true/false and price. Max 366 days.

    Example response (selected fields)

    {
      "data": [
        { "date": "2027-08-01", "available": true, "price": 1200 },
        { "date": "2027-08-02", "available": false, "price": 1200 },
        { "date": "2027-08-03", "available": true, "price": 1500 }
      ]
    }
  • GET /listings/{id}/quote?check_in=YYYY-MM-DD&check_out=YYYY-MM-DDRead key

    Get the total price for a stay, including fees.

    Examples and technical details

    Price breakdown for a stay, same math as Nordtinde checkout. weekly_discount and monthly_discount are savings in NOK already deducted from nights_total. For 28+ nights a nonzero monthly discount replaces the weekly discount; otherwise the weekly discount applies from 7 nights. Discounts apply to nightly prices including overrides, not cleaning or extras. Fees are calculated after the discount.

    Example response (selected fields)

    {
      "data": {
        "check_in": "2027-08-01",
        "check_out": "2027-08-05",
        "available": true,
        "min_nights": 2,
        "currency": "NOK",
        "nights": 4,
        "nights_total": 4800,
        "weekly_discount": 0,
        "monthly_discount": 0,
        "cleaning_fee": 500,
        "service_fee": 636,
        "total": 5936,
        "booking_url": "https://nordtinde…/stays/130f42b8-…?check_in=2027-08-01&check_out=2027-08-05"
      }
    }
  • PATCH /listings/{id}Read + write key

    Change your home's title, description, capacity and other settings.

    Examples and technical details

    Edit listing properties. Body may include any of: title, description, property_type, max_guests, max_infants, max_pets, bedrooms, beds, bathrooms, cleaning_fee, min_nights, instant_book, pets_allowed, check_in_time (HH:MM), check_out_time (HH:MM), cancellation_policy, calendar_closed_by_default. Location, photos and publishing can only be changed on Nordtinde.

    Request body

    {
      "title": "Fjord-edge cabin with sauna",
      "min_nights": 3,
      "pets_allowed": true
    }

    Example response (selected fields)

    {
      "data": {
        "id": "130f42b8-…",
        "updated": ["title", "min_nights", "pets_allowed"]
      }
    }
  • PATCH /listings/{id}/priceRead + write key

    Change your nightly price, weekly discount or monthly discount.

    Examples and technical details

    Set the base nightly price, weekly discount and/or monthly discount. All fields optional, at least one required. Price in NOK, 100–100 000; discounts are integer percentages 0–90. Weekly applies from 7 nights; a nonzero monthly discount replaces weekly from 28 nights. Set a discount to 0 to disable it.

    Request body

    {
      "nightly_price": 1500,
      "weekly_discount_percent": 10,
      "monthly_discount_percent": 20
    }

    Example response (selected fields)

    {
      "data": {
        "id": "130f42b8-…",
        "nightly_price": 1500,
        "weekly_discount_percent": 10,
        "monthly_discount_percent": 20
      }
    }
  • POST /listings/{id}/availabilityRead + write key

    Block or open dates, or change prices for specific nights.

    Examples and technical details

    Adjust the calendar. "to" is the checkout day (not included). set_price requires price (NOK, 100–100 000). Nights that are booked or synced from other sites can't be changed.

    Request body

    {
      "action": "block",
      "from": "2027-08-01",
      "to": "2027-08-05"
    }
    
    // or: { "action": "set_price", "from": "2027-08-10", "to": "2027-08-12", "price": 1800 }
    // actions: "block" | "unblock" | "set_price" | "reset_price"

    Example response (selected fields)

    {
      "data": { "action": "block", "from": "2027-08-01", "to": "2027-08-05", "changed": 4 }
    }

Access the full property catalog

Want to display homes from all Nordtinde hosts? Selected partners can apply for read-only access to all published homes.

  1. Sign in and submit your company, website and intended use.
  2. Nordtinde reviews your application. Check the status under API access.
  3. Once approved, create a Full catalog key and keep it on your server.
Apply for catalog access

Not an anonymous API. Approval can be withdrawn at any time. Catalog access never permits editing other hosts' homes or reading their bookings.

  • GET /catalog/listings?limit=50&offset=0Approved catalog key

    Get all published Nordtinde homes, one page at a time.

    Examples and technical details

    All published Nordtinde homes, across hosts. Requires an approved catalog application and dedicated catalog key. Optional country and city filters use exact stored values. limit 1–100 (default 50), offset 0–100000 (default 0). Newest first, then id. Follow next_offset until null. Concurrent additions may shift pages; deduplicate by id. No drafts, suspended listings, host identities, guest data or private check-in information. Summary uses the same listing fields as GET /listings.

    Example response (selected fields)

    {
      "data": [{ "id": "LISTING_UUID", "title": "Fjord-edge cabin", "city": "Balestrand", "nightly_price": 1200, "booking_url": "https://YOUR-NORDTINDE-DOMAIN/stays/fjord-edge-cabin-130f42b8" }],
      "pagination": { "limit": 50, "offset": 0, "next_offset": null }
    }
  • GET /catalog/listings/{id}Approved catalog key

    Get photos and details for one home in the full catalog.

    Examples and technical details

    One published home from any host, including photos, amenities and house rules. id must be a listing UUID returned by the catalog. Requires current approval and a dedicated catalog key. Unpublished or unknown homes return 404. No write access, booking access or private data.

    Example response (selected fields)

    {
      "data": { "id": "LISTING_UUID", "title": "Fjord-edge cabin", "photos": [{ "url": "https://YOUR-PHOTO-DOMAIN/cabin.jpg", "caption": "Living room" }], "amenities": ["Wi-Fi"], "house_rules": ["No smoking"], "booking_url": "https://YOUR-NORDTINDE-DOMAIN/stays/fjord-edge-cabin-130f42b8" }
    }

Receive booking updates

A webhook is a message sent to your system when a booking is created or its status changes. You don't need to keep asking Nordtinde for updates.

  1. Add your HTTPS receiver under Hosting → API access → Booking webhooks.
  2. Save the signing secret. Your developer uses it to check that messages really come from Nordtinde.
  3. After Nordtinde is published, send a test and check Recent deliveries.

If a delivery fails, resend it manually. There are no automatic retries. Your system should handle the same message arriving more than once. Booking success is never affected by a failed webhook.

Advanced webhook details

Receiver requirements

Configure one enabled webhook per account in Hosting → API access. Use your own public HTTPS domain, Make, Zapier or another receiver. Port 443 only, without URL credentials, query parameters or fragments. IP literals, local/internal domains and private or special-purpose DNS answers are rejected. All A/AAAA records are checked when saving and before delivery; Delivery then connects by hostname with full certificate verification from a network with no access to private addresses. No redirects are followed. Events cover new bookings and every actual status transition, including scheduled expiry/completion. No guest names, email, phone, guest IDs, messages, addresses, Wi-Fi or access codes are sent. The signing secret is shown once; delete and recreate the webhook to rotate it.

Events and payload

booking.created, booking.status_changed, webhook.test

{
  "id": "EVENT_UUID", "type": "booking.status_changed", "api_version": "v1",
  "created_at": "2026-11-02T10:00:00Z",
  "data": {
    "id": "BOOKING_UUID", "listing_id": "LISTING_UUID", "status": "confirmed",
    "previous_status": "requested", "check_in": "2027-08-01", "check_out": "2027-08-05",
    "adults": 2, "children": 0, "infants": 0, "pets": 0, "total": 5936, "currency": "NOK"
  }
}

Delivery guarantees, timeouts and retries

The booking transaction stores an event and queues an authenticated callback to Nordtinde's published delivery relay, which sends the signed HTTP POST. Publication is required for automatic and test delivery. Connection/response timeout: 5 seconds after DNS checks. Booking success never depends on the receiver. Delivery is best effort, not exactly-once and not guaranteed: failed or missing deliveries can be replayed manually from Recent deliveries, up to 10 attempts per event; there are no automatic retries. Disabled or suspended accounts send no events; paused events are not backfilled. Receiver HTTP status and failure state are stored with durable event history. A 2xx response means success. Respond quickly after storing the event. Duplicate or out-of-order events are possible: deduplicate by event id and reconcile against GET /bookings. Deleting a webhook deletes its event history but cannot retract HTTP requests already queued.

Signature verification (Node.js)

// Node.js receiver: keep the signing secret in your server's secret store.
import { createHmac, timingSafeEqual } from "node:crypto";
function verifyNordtinde(rawBody, headers, secret) {
  const stamp = headers["x-nordistay-timestamp"];
  const signature = headers["x-nordistay-signature"];
  if (!/^\d+$/.test(stamp ?? "") || !/^v1=[0-9a-f]{64}$/.test(signature ?? "")) return false;
  if (Math.abs(Date.now() / 1000 - Number(stamp)) > 300) return false;
  const expected = createHmac("sha256", secret).update(stamp + "." + rawBody).digest();
  const received = Buffer.from(signature.slice(3), "hex");
  return expected.length === received.length && timingSafeEqual(expected, received);
}
// Verify BEFORE parsing JSON. Use the exact raw UTF-8 request body.
// Header: X-Nordistay-Event-Id matches payload.id.
// Save payload.id atomically; duplicates should return 2xx without reprocessing.
// webhook.test has data: {}; booking.created has previous_status: null.

Advanced reference

All prices are in NOK. Guest identities, exact addresses, door codes and Wi-Fi are never returned.

Listing field reference
FieldTypeMeaning
idstringUnique listing id.
titlestringListing title.
descriptionstring | nullFull description.
property_typestringcabin, apartment, rorbu, …
citystring | nullCity or town.
regionstringRegion / area.
countrystring | nullCountry.
latnumber | nullApproximate latitude.
lngnumber | nullApproximate longitude.
max_guestsnumberMax adults + children.
bedroomsnumberNumber of bedrooms.
bedsnumberNumber of beds.
bathroomsnumberNumber of bathrooms.
nightly_pricenumberBase nightly price in NOK.
cleaning_feenumberCleaning fee in NOK.
weekly_discount_percentnumberNightly subtotal discount for 7+ nights (0–90%). Used if no monthly discount applies.
monthly_discount_percentnumberNightly subtotal discount for 28+ nights (0–90%). When nonzero, replaces rather than stacks with the weekly discount. Cleaning and extras are not discounted; fees use the discounted subtotal.
min_nightsnumberMinimum nights per stay.
instant_bookbooleanGuests can book without approval.
pets_allowedbooleanPets are welcome.
check_in_timestring | nullCheck-in from (HH:MM).
check_out_timestring | nullCheck-out by (HH:MM).
cancellation_policystringflexible, moderate, strict or non_refundable.
cover_photostring | nullURL of the cover photo.
photos{ url, caption }[]All photos in display order (detail endpoint only).
amenitiesstring[]Amenity names (detail endpoint only).
house_rulesstring[]House rules (detail endpoint only).
booking_urlstringLink where guests book on Nordtinde.
Booking field reference
FieldTypeMeaning
idstringBooking UUID; stable identity for deduplication.
listing_idstringListing UUID, including owned draft homes.
statusstringrequested, pending_payment, confirmed, declined, cancelled, expired or completed.
check_instringArrival date (YYYY-MM-DD).
check_outstringDeparture date (YYYY-MM-DD), excluded from nights.
adultsnumberBooked count.
childrennumberBooked count.
infantsnumberBooked count.
petsnumberBooked count.
nightsnumberBooked nights.
totalnumberGuest total including fees and selected add-ons; not a payment confirmation.
currencystringBooking currency (NOK).
host_payoutnumberBooking's original calculated payout snapshot after saved stay and add-on host fees (currently 3% on accommodation/cleaning and 20% on add-ons; admin-adjustable). Existing bookings retain saved rates. Not proof of a transfer or a currently payable amount. Unpaid payouts stop on cancellation; host cancellation fees and support cases are private.
created_atstringISO timestamp.
updated_atstringISO timestamp.
Errors, limits and troubleshooting

Limit: 60 requests per minute per key. A 401 usually means a missing or deleted key; 403 means the key or account lacks permission. On 429, slow down and wait before retrying.

{ "error": { "code": "forbidden", "message": "An approved catalog application and catalog key are required" } }
  • 400
    invalid_request

    Missing or malformed parameters.

  • 401
    unauthorized

    Missing, invalid or deleted API key.

  • 403
    forbidden

    Account is suspended, or a read-only key tried to make changes.

  • 404
    not_found

    Listing doesn't exist or isn't yours/published.

  • 409
    conflict

    Nights are booked or synced from other sites and can't be changed.

  • 429
    rate_limited

    More than 60 requests per minute for this key.

  • 500
    internal_error

    Could not read reservations. Retry with backoff.

  • 503
    unavailable

    Account or rate-limit verification temporarily unavailable. Retry with backoff.

External requests require a published site. Use the published site's base URL, not an editor-only preview. Keep booking and catalog keys server-side; each has separate permissions. Catalog keys cannot be used on host endpoints.

API versions and compatibility

The version is part of the URL (/v1/). Responses may gain new fields. Breaking changes use a new API version; the previous version stays available for at least 6 months. See the changelog for every update.