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.
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.
properties.read: Read property details and operating settings.properties.write: Update property details and operating settings.calendar.read: Read property availability, nightly rates, and stay restrictions.calendar.write: Update property availability, nightly rates, and stay restrictions.bookings.read: Read bookings and their financial details.bookings.sensitive.read: Include guest contact details, addresses, and access codes in booking responses.bookings.write: Create and update direct bookings. Payment requests and refunds also require payments.write.booking_parameters.read: Read booking parameter definitions and values.booking_parameters.write: Create and update booking parameter definitions and values.missions.read: Read missions and completion reports.missions.write: Create, update, and assign missions.activity.read: Read property activity logs.team_members.read: Read team members, contact details, and property assignments.webhooks.read: Read webhook subscriptions.webhooks.write: Create, update, and delete webhook subscriptions.customers.read: Read guest records, contact details, and stay history.customers.write: Create guest records.upsells.read: Read property upsells and booking purchases.payments.write: Request payment when creating a booking and issue cancellation refunds. Also requires bookings.write.messages.read: Read guest conversations and their messages.messages.write: Send messages to guests.guides.read: Read welcome guides and their page content.guides.write: Update welcome guides, create and edit pages, reorder pages, and upload guide images.knowledge.read: Read private property knowledge questions and answers.knowledge.write: Create and update private property knowledge. Copying from another property also requires knowledge.read.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.
Required scopes (all): properties.read
Search the eligible properties owned by your account.
curl -X GET 'https://api.nowistay.com/public/v1/properties?search=Apartment' \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"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"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
}'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
}'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
}'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"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
}'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"
}'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"
}'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"
}'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
}
}'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"
}
}'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"
}'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"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"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"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"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"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"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"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."
}'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"
}'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"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"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."
}'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."
}'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
]
}'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"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."
}
}'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"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"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"
}'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
}'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"
}'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="
}'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"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"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"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"