Start with an example

Choose an example, authorize the required scopes, then use the endpoint's Try it out controls below. Request bodies also appear in Swagger's Examples selector and in the downloadable OpenAPI schema. Replace placeholder IDs, credentials, dates and URLs with your own values. Requests you execute affect the connected account.

Access requires ownership and the property's assistant entitlement. Calendar operations and direct-booking creation additionally require an active PMS connection. New write endpoints return minimal action results unless you also hold their read scope.

Add scopes to an existing integration

Existing tokens and credentials do not gain permissions automatically. For personal access, create a replacement credential in My account > Developer > New credential. Select the existing permissions you still need plus the new ones. Request a new access token with grant_type=client_credentials, verify its scope, test the integration, switch credentials and cached tokens, then delete the previous credential once no consumers use it. Rotate secret does not add scopes.

Partner apps must register the complete desired scope set and obtain fresh user consent through authorization code and PKCE. Equivalent registrations reuse a client only for the exact same scope set; changed scopes create a new registration. Authorization codes and refresh tokens retain their original permissions. Refreshing cannot add scopes. In this playground, reload and authorize again after a scope change.

GET /public/v1/properties requires properties.read. Write permissions do not implicitly include reads. Payment requests and full/partial cancellation refunds require bookings.write plus payments.write. Knowledge copying requires both knowledge scopes.

All 25 REST permissions
Payment safeguards and partial outcomes

Once a payment order exists, changed booking dates or pricing are rejected, including for historical failed or expired orders. Accepted no-op pricing inputs remain allowed. Paid confirmed bookings cannot return to pending; refunded cancelled bookings cannot be reactivated. Contact, postal address, notes and supported check-in/out edits remain available.

A created booking remains successful if payment-link generation fails. Inspect paymentRequest.sent and paymentRequest.error before retrying. A persisted message with failed delivery returns its ID and status. Cancellation alone does not confirm refund completion. The payment-status GET never exposes a checkout URL.

Browse 39 request examples
Read property operating settings

Required scopes (all): properties.read

Includes booking cutoffs and default pricing and stay settings.

curl -X GET https://api.nowistay.com/public/v1/properties/101 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Update property operating settings

Required scopes (all): properties.write

Add properties.read to receive property details; write-only access returns its ID.

curl -X PATCH https://api.nowistay.com/public/v1/properties/101 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "capacity": 4,
  "cutOffDays": 1,
  "defaultMinStay": 2
}'
Create a direct booking

Required scopes (all): bookings.write

Requires an active PMS connection. Creation defaults to silent=false. Add bookings.read for booking details.

curl -X POST https://api.nowistay.com/public/v1/bookings \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "propertyId": 101,
  "arrival": "2026-12-18",
  "departure": "2026-12-20",
  "guestFirstName": "Maya",
  "guestLastName": "Martin",
  "guestEmail": "maya@example.com",
  "adults": 2,
  "amount": "290.00",
  "currency": "EUR",
  "requestPayment": false
}'
Create a booking and request payment

Required scopes (all): bookings.write + payments.write

Both scopes are required. The booking starts pending payment. If payment-link generation fails, creation still succeeds: inspect paymentRequest.sent and error before retrying to avoid duplicate bookings.

curl -X POST https://api.nowistay.com/public/v1/bookings \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "propertyId": 101,
  "arrival": "2026-12-18",
  "departure": "2026-12-20",
  "guestFirstName": "Maya",
  "guestLastName": "Martin",
  "guestEmail": "maya@example.com",
  "adults": 2,
  "amount": "290.00",
  "currency": "EUR",
  "requestPayment": true
}'
Read safe payment-request status

Required scopes (all): bookings.read

Returns bookingType and paymentRequest status, never a checkout URL. Cancellation alone does not prove a refund completed.

curl -X GET https://api.nowistay.com/public/v1/bookings/9001/payment-request \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Update a reservation reference and notes

Required scopes (all): bookings.write

Existing PATCH defaults to silent=true. Contact, postal address, notes and check-in/out edits remain supported when a payment order exists.

curl -X PATCH https://api.nowistay.com/public/v1/bookings/9001 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "reservationNumber": "DIRECT-9001",
  "notes": "Guest requested a baby cot.",
  "silent": true
}'
Cancel without a refund

Required scopes (all): bookings.write

No payments.write scope is required when no refund is requested.

curl -X PATCH https://api.nowistay.com/public/v1/bookings/9001 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "status": "cancelled",
  "cancellationRefundMode": "none"
}'
Cancel and request a full refund

Required scopes (all): bookings.write + payments.write

Both scopes are required. Check payment status before reporting refund completion.

curl -X PATCH https://api.nowistay.com/public/v1/bookings/9001 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "status": "cancelled",
  "cancellationRefundMode": "full"
}'
Cancel and request a partial refund

Required scopes (all): bookings.write + payments.write

The amount must satisfy the booking's refund rules. payments.write does not authorize repricing an existing checkout.

curl -X PATCH https://api.nowistay.com/public/v1/bookings/9001 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "status": "cancelled",
  "cancellationRefundMode": "partial",
  "cancellationRefundAmount": "50.00"
}'
Update only custom parameters

Required scopes (all): booking_parameters.write

Also supported for OTA bookings. Create the parameter definition first; null clears its value. Parameters named <key>_submitted may also be set by the forms integration when a guest submits a form.

curl -X PATCH https://api.nowistay.com/public/v1/bookings/9001 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "customParameters": {
    "external_status": null
  }
}'
Update notes and custom parameters atomically

Required scopes (all): bookings.write + booking_parameters.write

Create the parameter definition first. Invalid parameters or denied permissions leave both parts unchanged.

curl -X PATCH https://api.nowistay.com/public/v1/bookings/9001 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "notes": "Arrival confirmed.",
  "customParameters": {
    "external_status": "ready"
  }
}'
Create a guest record

Required scopes (all): customers.write

Duplicate guest creation returns 409. Add customers.read to receive the guest profile; otherwise the response contains its ID.

curl -X POST https://api.nowistay.com/public/v1/guests \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "firstName": "Maya",
  "lastName": "Martin",
  "email": "maya@example.com",
  "language": "en"
}'
Filter and sort guest records

Required scopes (all): customers.read

Omit property filters to retain the owner-wide customer base. Prefix orderBy with - for descending order.

curl -X GET 'https://api.nowistay.com/public/v1/guests?propertyIds=101&propertyIds=102&orderBy=-last_stay' \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Read a guest's booking history

Required scopes (all): customers.read + bookings.read

Both scopes are required. History includes bookings on eligible properties.

curl -X GET https://api.nowistay.com/public/v1/guests/501/bookings \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Read a mission

Required scopes (all): missions.read

Includes related booking context under missions.read.

curl -X GET https://api.nowistay.com/public/v1/missions/701 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Read a mission completion report

Required scopes (all): missions.read

A valid mission without a report returns 200 with report: null.

curl -X GET https://api.nowistay.com/public/v1/missions/701/report \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Filter team workload

Required scopes (all): missions.read

fromDate and toDate filter scheduled UTC dates inclusively. Repeat propertyIds and teamMemberIds for multiple values.

curl -X GET 'https://api.nowistay.com/public/v1/missions?propertyIds=101&propertyIds=102&teamMemberIds=301&fromDate=2026-12-01&toDate=2026-12-31' \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Find guest conversations

Required scopes (all): messages.read

Filter by propertyId and/or bookingId; multi-room booking lookups resolve the related conversation.

curl -X GET 'https://api.nowistay.com/public/v1/conversations?propertyId=101&bookingId=9001' \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Read conversation messages

Required scopes (all): messages.read

Read message content, delivery status and related booking context.

curl -X GET 'https://api.nowistay.com/public/v1/conversations/801/messages?limit=20' \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Send a host reply for a booking

Required scopes (all): messages.write

Provide exactly one of bookingId or conversationId. A saved message with failed delivery still returns its ID and status. Attachments are not supported.

curl -X POST https://api.nowistay.com/public/v1/messages \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "bookingId": 9001,
  "message": "Hello Maya, your arrival instructions are ready."
}'
Send through a selected conversation channel

Required scopes (all): messages.write

channelKind or threadChannelId can select a delivery channel; never provide both. Add messages.read for the detailed message and delivery response.

curl -X POST https://api.nowistay.com/public/v1/messages \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "conversationId": 801,
  "message": "Your check-in is confirmed.",
  "channelKind": "email"
}'
Read private property knowledge

Required scopes (all): knowledge.read

Read the property's private questions and answers.

curl -X GET https://api.nowistay.com/public/v1/properties/101/knowledge-questions \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Read one knowledge answer

Required scopes (all): knowledge.read

Read the current answer before changing it.

curl -X GET https://api.nowistay.com/public/v1/properties/101/knowledge-questions/201 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Add a private knowledge answer

Required scopes (all): knowledge.write

Add knowledge.read for the complete question response; write-only access returns action identifiers.

curl -X POST https://api.nowistay.com/public/v1/properties/101/knowledge-questions \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "question": "Where is the recycling area?",
  "answer": "In the courtyard, next to the bicycle shelter."
}'
Update a private knowledge answer

Required scopes (all): knowledge.write

Omitted fields remain unchanged.

curl -X PATCH https://api.nowistay.com/public/v1/properties/101/knowledge-questions/201 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "answer": "Use the labelled bins in the courtyard."
}'
Merge knowledge into other properties

Required scopes (all): knowledge.read + knowledge.write

Both scopes are required. The URL identifies the source. All targets are validated before writes. Copying never deletes or overwrites target answers.

curl -X POST https://api.nowistay.com/public/v1/properties/101/knowledge-questions/copy \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "targetPropertyIds": [
    102,
    103
  ],
  "questionIds": [
    201
  ]
}'
Read a welcome guide

Required scopes (all): guides.read

Reads localized introductions and settings without guide tokens or guest access links.

curl -X GET https://api.nowistay.com/public/v1/properties/101/welcome-guide \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Update localized guide introductions

Required scopes (all): guides.write

Omitted locales remain unchanged. Add guides.read to receive guide details.

curl -X PATCH https://api.nowistay.com/public/v1/properties/101/welcome-guide \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "intros": {
    "en": "Welcome! Your practical information is below.",
    "fr": "Bienvenue ! Retrouvez les informations pratiques ci-dessous."
  }
}'
List guide pages

Required scopes (all): guides.read

Read page identifiers and ordering before editing.

curl -X GET https://api.nowistay.com/public/v1/properties/101/welcome-guide/pages \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Read a structured guide page

Required scopes (all): guides.read

Read content/contents before an edit to preserve EditorJS block IDs, nested formatting and media.

curl -X GET https://api.nowistay.com/public/v1/properties/101/welcome-guide/pages/301 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Create a structured guide page

Required scopes (all): guides.write

Supports start, end or after_page positioning; after_page requires afterPageId. REST validates each block type and its data before saving (422 on failure). Supported types: paragraph, header, quote, list, delimiter, table, image, video, embed, upsellCatalog and upsellProduct. Nested list items are validated; supplied block IDs must be non-empty unique strings. Editor-only imageLibrary blocks are rejected.

curl -X POST https://api.nowistay.com/public/v1/properties/101/welcome-guide/pages \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "locale": "en",
  "title": "Parking",
  "content": {
    "blocks": [
      {
        "id": "parking-info",
        "type": "paragraph",
        "data": {
          "text": "Use the <b>marked parking space</b> in the courtyard."
        }
      }
    ]
  },
  "position": "end"
}'
Edit and position a structured guide page

Required scopes (all): guides.write

Start from the existing complete content and keep all unaffected blocks and IDs. This example assumes a page containing the single shown block. Plain-text replacement of structured pages is rejected; omitted locales remain unchanged. Every supplied language is validated before any write: unsupported types, malformed block data and duplicate IDs return 422. Unknown metadata is preserved; IDs remain optional for existing documents. Title/order-only updates do not revalidate untouched content.

curl -X PATCH https://api.nowistay.com/public/v1/properties/101/welcome-guide/pages/301 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "locale": "en",
  "content": {
    "blocks": [
      {
        "id": "parking-info",
        "type": "paragraph",
        "data": {
          "text": "Use the <b>marked parking space</b> in the courtyard."
        }
      }
    ]
  },
  "order": 2
}'
Upload a guide image from a public URL

Required scopes (all): guides.write

Replace this example URL with a real public image. Redirects and destination addresses are checked, with size limits before upload.

curl -X POST https://api.nowistay.com/public/v1/properties/101/welcome-guide/images \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "imageUrl": "https://images.example.com/parking.jpg",
  "filename": "parking.jpg",
  "caption": "The marked parking space"
}'
Upload a base64 guide image

Required scopes (all): guides.write

A small PNG example. filename is required with base64 input; download and decoded image size limits still apply.

curl -X POST https://api.nowistay.com/public/v1/properties/101/welcome-guide/images \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
  "filename": "pixel.png",
  "contentType": "image/png",
  "imageBase64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII="
}'
Read the upsell catalog

Required scopes (all): upsells.read

Read-only catalog access; booking purchases additionally require bookings.read.

curl -X GET https://api.nowistay.com/public/v1/upsells \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Read a booking's upsell purchases

Required scopes (all): upsells.read + bookings.read

Both scopes are required. This endpoint does not create or modify purchases.

curl -X GET https://api.nowistay.com/public/v1/bookings/9001/upsell-purchases \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Export a booking table

Required scopes (all): bookings.read

Returns columns, rows and pagination. Table limit is 500; default JSON remains capped at 100. Dates retain overlap semantics: departure >= fromDate and arrival <= toDate. Cleaning assignments also need missions.read; conversation presence needs messages.read.

curl -X GET 'https://api.nowistay.com/public/v1/bookings?propertyIds=101&propertyIds=102&responseFormat=table&limit=500&offset=0&fromDate=2026-12-01&toDate=2026-12-31' \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Export a mission table

Required scopes (all): missions.read

Returns columns, rows and pagination. Multiple propertyIds intersect propertyId when both are supplied. Use offset for subsequent pages.

curl -X GET 'https://api.nowistay.com/public/v1/missions?propertyIds=101&propertyIds=102&responseFormat=table&limit=500&offset=0' \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"