The Zenoti API is a REST API served from api.zenoti.com and documented at docs.zenoti.com. It reads and writes the same data your front desk uses: centers, services, guests, appointments, invoices, gift cards, memberships and employees. Every response comes back as JSON, and Zenoti adds webhooks that push changes to your server as they happen.
This guide is for developers and store owners planning a Shopify store for salons, spas and wellness businesses whose bookings live in Zenoti. It covers what has to be in place before the first call, how requests are authenticated, the endpoints a storefront uses, the booking sequence, webhooks, the rate limit, and when a link to the Zenoti Webstore does the job without any API code. Every docs page and Help Center article cited here was read on 6 November 2026.
Key takeaways
- API access needs the Zenoti API package switched on by your Zenoti customer success manager (CSM). Zenoti does not publish what the package costs.
- Each integration gets its own backend app in Zenoti, and the app’s settings decide which data it can reach and how its bookings are labelled in Appointment Book.
- A service booking takes at least five calls: find the guest, create the booking, fetch open slots, reserve one, and confirm it.
- The standard limit refills 60 calls every 60 seconds and never banks more than 60, so a storefront has to cache its menus.
- Zenoti’s Shopify sign-in for Plus stores depends on Multipass, which Shopify now says is closed to new stores.
Before the first call: the API package and a backend app
Two things come first. Your CSM enables the API package for the organization; the webhooks guide says the same subscription covers webhooks. Then someone with organization-level access creates a backend app. In the current navigation that is the Configuration icon, then Apps under Integrations. Older guides point to Admin, Setup, API instead.
The app form asks for a name, the URL of your site or app, a description, the login user type (guest or employee), and a source app. The source app matters for a storefront. Bookings made through an app set to External Webstore get the Web Booking icon in Appointment Book, External CMA gets the Mobile Booking icon, and Bot gets its own icon, so the front desk and the reports can tell where each appointment came from. Client App is the fourth option.
Next you tick the data the app may touch, grouped by API group, and pick the authentication method: APIKEY groups for API keys or JWT groups for access tokens. Zenoti then shows an Application ID and a secret once; copy both before leaving the page, or the process starts again. The last step generates the API key.
Zenoti asks for one app per use case, with its own key, because audit logs and troubleshooting get harder when several systems share one key. A web booking flow and a mobile app are two apps.
The docs disagree on key expiry. The authentication page says API keys keep working until you rotate or revoke them. The backend app guide says a generated key expires after a set period and that an “Expiry of API keys” alert can warn you a chosen number of days ahead. Turn that alert on, and plan for rotating the key either way.
Authentication and authorization
Every request carries an Authorization header. With a key the value is apikey followed by the key. With a token it is bearer followed by an access token from POST /v1/tokens. A token lasts 24 hours and is renewed through the refresh token call.
Zenoti’s own comparison puts it this way: a key reaches every API group its app was granted, which makes it easy to run from a backend server and risky if it leaks; a token is tied to one person’s login and role, which fits a guest app or a therapist app.
Authorization is a second check. A call first needs the user’s security role to allow the data, and then the backend app’s group permissions. Passing one check and failing the other returns an error.
For a Shopify store, the key belongs on a server: an app backend, a Shopify app proxy, or a serverless function that the theme calls. A key placed in theme JavaScript is readable by any visitor, and it opens every group the app was given.
The endpoints a Shopify storefront uses
| Job | Endpoint | Notes from the docs |
|---|---|---|
| List locations | GET /v1/centers | expand=working_hours adds opening hours |
| Service menu | GET /v1/centers/{center_id}/services | Filters by category, catalog and add-ons; expand for images and variants |
| Retail products | GET /v1/centers/{center_id}/products | Products active in that center |
| Find a guest | GET /v1/guests/search | By email, phone, name and more; org-wide or per center, set by “Search Guest Across Centers” |
| Create a guest | POST /v1/guests | Must include the fields your organization marks as mandatory |
| Checkout as guest | POST /v1/guests/online_guests | A placeholder guest for custom webstores; not retrievable in Zenoti POS |
| Start a booking | POST /v1/bookings | Returns a 32-digit booking_id; several guests make a group booking |
| Open slots | GET /v1/bookings/{booking_id}/slots | Falls forward to the next open slot that week when the day is full |
| Hold a slot | POST /v1/bookings/{booking_id}/slots/reserve | Takes the chosen slot_time |
| Confirm | POST /v1/bookings/{booking_id}/slots/confirm | The response carries the invoice details |
| Read an invoice | GET /v1/invoices/{invoice_id} | Expand for items, appointments and transactions |
| Record an outside payment | POST /v1/invoices/{invoice_id}/payment/custom | For money taken by other software; your Zenoti representative sets it up |
| Gift card templates | GET /v1/giftcards/templates | Templates for one center |
| Gift card sale | POST /v1/invoices/giftcards | Creates the invoice from a template |
| Gift card balance | GET /v1/giftcards/{giftcard_number}/balance | Check before redeeming |
| Shopify sign-in | GET /v1/ecommerce/shopify/multipass-url | Takes user_id and return_url; returns a multipass_url |
List calls are paged with page (default 1) and size (default 10, at most 100). Each list response includes a page_info object with the total, the page and the size. Asking for more than 100 records returns a 422 error.
How a service booking runs through the API
Zenoti’s service booking recipe assumes five things are already set up in Zenoti: the services, employee schedules with at least one employee available and checked in, the center’s hours, block-out times, and an active payment processor. The calls then run in this order:
- Search for the guest, or create one if the search finds nobody.
- Pick the service from the center’s list. If the guest wants a particular therapist or room, list those for the center too; room choice works only after rooms are tied to services.
- Create the booking and keep the booking_id it returns. The request can mark the source as External-Webstore or External-CMA.
- Fetch the open slots for that booking. Zenoti’s note on this step points to the Appointment Book time-slot setting: at 5 minutes, times read 10:00, 10:05, 10:10.
- Reserve the slot the guest picked.
- Confirm the booking. The response includes the invoice.
- Collect payment: charge a saved card, add a new card, or record a payment taken elsewhere with the custom payment call. Then read the invoice again to check that it closed.
Separate calls reschedule or cancel a booking, and check a guest in at the center.
Gift cards through the API
Zenoti sells three kinds of gift card: amount cards, service or day-package cards, and predefined cards that carry a name, such as a fixed value or a set bundle of services. The gift card recipe offers two routes. One creates an invoice for the card without a template. The other starts from a template, using one of the predefined amounts, a custom amount template, or a template built from services and day packages, then creates the invoice, takes payment, and emails the card to the recipient with the send email call. The balance call checks what is left on a card.
This matters for Shopify because the feature table in Zenoti’s Shopify integration article marks “Using Zenoti Gift Cards on Shopify” as not supported. A store that wants to sell Zenoti gift cards on its own pages either sends buyers to the Webstore or builds on these calls.
Webhooks: Zenoti calls you
A webhook is set up as an event, a verb (POST, PUT or PATCH) and the URL that should receive it. The event reference lists these groups:
- Invoice: closed.
- Guest: created, updated, deleted.
- Appointment: started, completed, feedback created; appointment groups: created and status changes.
- Class: schedule created, updated, cancelled and deleted; bookings created, cancelled, deleted, approved, rejected and marked no-show.
- Guest membership: created, frozen, unfrozen, cancelled, reinstated.
- Guest package: created, redeemed, redemption reversed, status and validity updates.
- Employee: created, updated, deleted.
Each delivery has a signature in its HTTP header for verification and a JSON body with an id, event_id, event_schema, event_resource, event_type (for example Invoice.Closed), event_timestamp and a data object.
Delivery rules, from the failure handling page: Zenoti waits 10 seconds for your endpoint to answer, retries up to 5 times with backoff from 30 seconds to 10 minutes, and after 20 failures in a row deactivates the webhook and emails a link to the failure log. Once the endpoint is fixed, you switch the webhook back on from the inactive tab. Your receiver should answer fast and do slow work after it replies.
Rate limit, errors and caching
The rate limits page sets the standard at 60 calls a minute, with higher-volume add-ons available through your Zenoti account manager. The response header Organization-RateLimit-Limit: 60;w=60;b=60 means 60 calls are added every 60 seconds and no more than 60 can be stored, so two quiet hours still leave you 60 calls, not 7,200. RateLimit-Remaining shows what is left and RateLimit-Reset shows the seconds until the next refill.
At five calls per booking, 60 calls a minute covers at most 12 bookings a minute, and only if nothing else uses the key. Zenoti’s own advice is to cache data that rarely changes, naming the service list, the therapists who perform each service and their prices, to pause and try again when a call hits the limit, and to queue requests through a service such as Amazon SQS.
Successful calls return 200, with a null error field. A 4XX status is a problem with the request and a 5XX is a problem on Zenoti’s side. The support page says a 503 means a traffic spike that usually clears within 5 minutes.
Shopify sign-in: Multipass and what changed
Zenoti’s Shopify integration article describes two checkouts. On Shopify Plus, guests log in through the Zenoti Webstore and arrive in Shopify already signed in. On other Shopify plans they use Shopify’s guest checkout. The Plus route needs a Multipass secret from Shopify: in Settings, Checkout, accounts must be optional or required, and then Enable Multipass shows the secret, which goes into the Zenoti setup. On the API side, the multipass-url endpoint returns the URL that sends a signed-in guest to Shopify.
Shopify’s Multipass documentation, read the same day, now says Multipass is no longer available to new stores. Stores that already use it keep it, including after they move to new customer accounts, and Shopify points new integrations to a third-party identity provider. Multipass also requires Shopify Plus, and a store that drops off Plus loses it on new customer accounts.
So a store opened today cannot follow Zenoti’s Multipass step. The options in the docs are Shopify’s guest checkout, which Zenoti names for non-Plus plans, or the identity-provider route Shopify recommends, which Zenoti’s Shopify article does not cover. Check this before promising a client one login across the Webstore and the store.
Build on the API or link to the Webstore?
| Route | What it covers | What it needs |
|---|---|---|
| Deep links to the Zenoti Webstore | Booking, memberships, packages and gift cards stay in Zenoti | No API code; each service and location links to its own Webstore page |
| Zenoti’s Shopify integration | Retail orders lower Zenoti stock and create Zenoti invoices | Matching SKUs and product codes; no variants, exchanges or pickup |
| Custom booking on the API | Slot picker and booking inside the Shopify theme | The API package, a server for the key, payment handling, caching for the rate limit, a webhook receiver |
| Zapier | Event-driven tasks between Zenoti and other apps | The API and webhooks subscription; no hosting of your own |
The link route is the quickest and keeps every booking rule inside Zenoti. The API route gives full control of the booking screens, and in return you own the server, the key, the payment step and the limit.
Gene Juarez uses the link route across its 13 Washington salons and spas. Every Book Now button, service tile and location page on its Shopify Plus theme deep-links to the matching Zenoti Webstore page, with DNS prefetched and origins preconnected so the handoff takes under one second. Its homepage LCP is 1,200 ms. Disclosure: Gene Juarez is our client, and our team built that theme and its Zenoti booking links. The case study for Gene Juarez covers how the theme and links were built.
For the full list of what Zenoti connects to, see our guide to Zenoti integrations, and for the storefront itself, the best Shopify themes for Zenoti. Custom work on the API, such as a booking screen, a server for the key or a webhook receiver, is what our Shopify app development team builds, and the whole store-to-Zenoti connection is the job of our Zenoti Shopify integration service.
FAQ
How do I get access to the Zenoti API?
Ask your Zenoti customer success manager to enable the API package for your organization. Then create a backend app under Configuration, Integrations, Apps, choose its data permissions and authentication method, and generate an API key for that app. Zenoti suggests a separate app and key for each use case.
How does Zenoti API authentication work?
Each request sends an Authorization header. Server-side integrations send “apikey” plus the app’s API key. Apps where a guest or employee logs in send “bearer” plus an access token from the tokens endpoint, which is valid for 24 hours and renewed with a refresh call.
What is the Zenoti API rate limit?
The documented standard is 60 calls per minute for the organization, refilled every 60 seconds and capped at 60 stored calls. Response headers show the calls remaining and the seconds until the next refill. Your Zenoti account manager can offer add-ons for more volume.
Can a Shopify store book Zenoti appointments?
Yes, in two ways. The store can link each service and location to its Zenoti Webstore page, or a developer can build booking into the theme with the API: search or create the guest, create the booking, fetch slots, reserve one, confirm it, and collect payment on the invoice.
Does the Zenoti Shopify integration use Multipass?
Yes, for single sign-on on Shopify Plus, where guests log in through the Zenoti Webstore and reach Shopify already signed in. Shopify’s documentation now says Multipass is no longer available to new stores, so a new store uses Shopify’s guest checkout or the third-party identity provider route Shopify recommends.
Sources: the Zenoti developer docs on authentication, authorization, creating a backend app, custom sources, pagination, response codes, rate limits, service booking, gift card sales, webhook events, event structure and webhook failures, plus the API reference for available slots, online guests and the Shopify Multipass URL; the Zenoti Help Center article on Shopify integrations; and Shopify’s Multipass documentation. We read each one on 6 November 2026. Zenoti lists no public price for the API package, so the cost comes from your Zenoti account team. More about the company is at zenoti.com.