The Nowistay public REST API lets your own tools, scripts and partners read and update data from your Nowistay account in a secure way. You can list properties, read and update availability, rates and stay restrictions, fetch bookings, update direct reservations, create cleaning or check-in missions, manage custom booking fields and pull a feed of activity events. Everything is documented, browsable and testable from a single page at /public/docs.
This guide walks you through three paths: the fastest way to try the API (the interactive docs playground), the simplest way to run your own scripts (a personal API credential created in the app) and the standard OAuth flow you will use when you build an app for other hosts.
external_status) and set their values per reservation.https://api.nowistay.com/public/v1/* require an OAuth2 access token, sent as Authorization: Bearer ....Open https://api.nowistay.com/public/docs in your browser. The page is a full Swagger UI of the API, with a built-in OAuth playground that auto-registers a client for you. No coding needed to test calls.
Cmd+Shift+R on Mac, Ctrl+F5 on Windows)./public/docs, already authenticated.GET /public/v1/properties, click Try it out, then Execute.[Screenshot to add: the /public/docs page with the green "OAuth playground ready" banner at the top and the Authorize button on the right]
From there you can try every endpoint with one click, see the exact JSON Nowistay returns and copy the cURL command for any call. This is the recommended way to explore the API before writing code.
Important. The playground client lives only in your browser. It is fine for testing, but for a real integration you should create a personal API credential or register your own OAuth client (both explained below).
If you are automating your own account (a reporting script, a sync with your accounting tool, a small dashboard), you do not need the full OAuth flow at all. Create a personal API credential in the app and exchange it for a token in a single call. No consent screen, no refresh tokens to manage.
Reporting script) and tick only the permissions it needs.[Screenshot to add: the Developer page with the New credential dialog open, showing the name field and the permissions checkboxes]
Your script then exchanges the credential for an access token (valid one hour) and calls the API:
When the token expires, request a new one the same way. There is no refresh token on this flow, and that is the point: two lines of code, nothing to babysit.
You can create up to 10 credentials, each with its own name and permissions. A credential only reads and writes the data your own account can access, and it needs the same active AI Channel Manager subscription as the rest of the API.
The API uses standard OAuth 2.1 with the authorization code flow and PKCE. In one sentence: the user opens a Nowistay page, says yes, you receive a short code, you exchange it for an access token, and you call the API with that token. Tokens expire and can be refreshed without bothering the user again.
The three OAuth endpoints you will use:
/public/oauth/register (POST)/public/oauth/authorize (GET, browser redirect)/public/oauth/token (POST)You can also fetch the OAuth metadata at /.well-known/oauth-authorization-server/public-api, which lists every endpoint and supported feature.
Anyone can register an OAuth client, so hosts need a way to tell a brand-new app from an established integration. Every newly registered app therefore starts as unverified:
Building something for more than 3 accounts? Write to support with your app name, website and use case. Once your app is verified, the warning disappears and the account limit is lifted.
Ask only for the scopes your app actually needs. The fewer scopes you request, the faster the consent screen reads.
properties.read: List properties and their basic info.calendar.read: Read daily availability, rates and stay restrictions for a property.calendar.write: Update availability, rates and stay restrictions for a property.bookings.read: List bookings and read a booking detail (no guest contact info).bookings.sensitive.read: Adds guest email, phone, address and smart-lock code to the booking detail.bookings.write: Update direct bookings (dates, amounts, guest info).booking_parameters.read: List your custom booking fields.booking_parameters.write: Create custom booking fields and set values on bookings.missions.read: List missions on your properties.missions.write: Create or update missions, assign team members.activity.read: Read the activity feed for a property.team_members.read: List team members and their property assignments.webhooks.read: List your webhook subscriptions and read their config.webhooks.write: Create, update, pause and delete webhook subscriptions.customers.read: List guest profiles with their contact details (email, phone).Call POST /public/oauth/register once. Save the client_id (and client_secret if you set token_endpoint_auth_method to something other than none).
Response (shortened):
Tip: if you are building a single-page app or a CLI without a backend, use "tokenEndpointAuthMethod": "none" and rely on PKCE only (no client secret). The Nowistay docs playground does exactly that.
Generate a PKCE pair (code verifier and S256 code challenge) and a random state value. Then redirect the user to:
The user lands on the Nowistay consent page, signs in if needed, sees the scopes you requested, and approves or denies. On approval, Nowistay redirects back to your redirect_uri with a one-time code and the same state you sent.
Always check that state matches what you sent. If it does not, abort.
Response:
Store the access_token and the refresh_token securely on your side (server side, encrypted at rest). The access token is valid for expires_in seconds (one hour by default).
Send the access token in the Authorization header.
Sample response:
When the API returns 401 token_expired, call the token endpoint again with the refresh token. You do not need to send the user back to the consent page.
GET /public/v1/properties/{property_id}/calendar requires calendar.read. Pass an inclusive from and to date; one request can cover up to 730 days.
GET /public/v1/properties/101/calendar?from=2026-12-18&to=2026-12-20
Each day can return availability, rate, minStay, maxStay, stopSell, closedToArrival, closedToDeparture, restricted and restrictionReasons. availability is the remaining sellable inventory after confirmed bookings. The restriction fields explain why a date or a check-in/check-out action is restricted.
PATCH /public/v1/properties/{property_id}/calendar requires calendar.write. The request is partial: send only the controls that should change, and omitted fields remain unchanged.
{
"from": "2026-12-18",
"to": "2026-12-31",
"availability": 1,
"rate": 145.0,
"minStay": 2,
"maxStay": 14,
"stopSell": false,
"closedToArrival": false,
"closedToDeparture": false,
"daysOfWeek": [0, 1, 2, 3, 4]
}
daysOfWeek is optional: 0 is Monday and 6 is Sunday. Omit it to update every date in the range. The response reports daysUpdated and the normalized update that was applied. Changes are synchronized through Nowistay PMS.
Calendar access is limited at request time to properties that belong to the connected account, have an active AI Channel Manager subscription and use Nowistay calendar management. Existing OAuth apps must add the new scopes and ask the user to authorize again before an existing integration can call these endpoints. In the docs playground, refresh the page and authorize again to select the new scopes.
Supported filters: propertyId, status, channel, fromDate, toDate. Pagination with limit (max 100) and offset.
Requires the extra bookings.sensitive.read scope. Without it, email, phone and the smart-lock code are omitted.
Only direct bookings (channel direct) you created in Nowistay can be edited. Reservations from Airbnb, Booking.com, VRBO and Expedia are read-only here, because the OTA owns them.
Set "silent": false if you want Nowistay to send the usual notifications (guest messages, calendar push) on the update. Default is silent.
Custom booking parameters are useful when you want to mirror data from your own system on each Nowistay reservation.
Send null as the value to clear a custom field on a booking.
Events are grouped into three categories: booking, mission and automation (guest messages, smart-lock events).
If you do not want to poll the API to detect changes, you can subscribe to webhooks. Nowistay will then call a URL you provide each time a booking is created or updated on the property, and send the same booking data that GET /public/v1/bookings/{id} returns.
Two events are supported today:
booking.created: a new reservation has been recorded on the property.booking.updated: an existing reservation has changed (dates, status, guest info, smart-lock code, etc.).Each webhook is tied to a single property and you can register up to three per property. Deliveries are signed (HMAC-SHA256) so you can verify they really come from Nowistay, retried with exponential backoff on failure, and the endpoint is auto-disabled if it keeps failing for more than 72 hours. Webhook payloads do not contain sensitive guest fields (email, phone, address, smart-lock code). When you need those, call the API with the bookings.sensitive.read scope.
Full setup and signature verification details are in the dedicated article: Public API: receive real-time booking webhooks.
When you hit the limit, the API returns 429 Rate limit exceeded. Back off and retry after a few seconds.
Every error follows the same shape, with a stable code, a human message and a requestId you can include in support requests.
400: Bad request (malformed body, missing field).
silent flag on writes. Set to true when you are syncing data in bulk and do not want to trigger guest notifications.requestId in your logs. It makes support requests much faster to resolve./public/openapi.json.