{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"342a7a52-9b61-4eb3-bfe0-7aec1e959d10","name":"Zenoti API","description":"## **Disclaimer**: This API documentation is an older version and does not receive any updates. For updated API documentation, [click here](https://docs.zenoti.com/reference/generate-an-access-token).\n\nThe Zenoti API allows you to programmatically access the data stored in your Zenoti account with ease.\n\n<h1>Overview</h1>\n\n<ol><li><p>You need to create a backend app and require a valid bearer token or an API key to send requests to the API endpoints. To create your app and key, navigate at the organization-level, <b>Admin</b> &gt; <b>Setup</b> &gt; <b>Apps.</b></p></li><p><a href=\"https://help.zenoti.com/en/articles/5587726-zenoti-api-create-the-backend-app-and-generate-a-new-api-key\">Learn how to create a backend app and generate a new API key.</a></p><p>The API key is valid for one year, after which you must<a href=\"https://help.zenoti.com/en/articles/5587780-zenoti-api-update-the-existing-api-key\">update the API key before expiry.</a></p><li><p>The response to every request is sent in<a href=\"https://en.wikipedia.org/wiki/JSON\">JSON format</a>. If the API request results in an error, it is represented by an <code>\"error\": {}</code> key in the JSON response.</p></li><li><p>The request method (verb) determines the nature of action that you intend to perform. A request made by using the <code>GET</code> method implies that you want to fetch something from Postman. Similarly, a request made by using the <code>POST</code> method implies you want to save something new to Zenoti.</p></li><li><p>The API calls will respond with appropriate<a href=\"https://en.wikipedia.org/wiki/List_of_HTTP_status_codes\">HTTP status codes</a>for all requests. A <code>200 OK</code> indicates that the response was successfully sent, while <code>4XX</code> or <code>5XX</code> response codes indicate an error from the requesting client or our API servers respectively.</p></li></ol>\n\n<h1>Authentication</h1>\n\n---\n\n<h2>API Key-based Authentication</h2>\n\nAn API Key is required to be sent as part of every request to the Zenoti API. All the APIs use API Key to authenticate the requests and identify your account\n\n<blockquote><br>If you do not have an API Key, you can easily generate one by going to <b>Admin</b> &gt; <b>Setup</b> &gt; <b>Apps</b>.<br></blockquote>\n\nTo hit Zenoti APIs, you must pass the **api_key** (that you obtained from **Admin** > **Setup** > **Apps**) as **Authorization** header in the following format:\n\n<blockquote><br>apikey {{api_key}}<br></blockquote>\n\nAn API Key tells our API server that the request it received came from a specific app or from your account. This API key allows you to access all the APIs supported by Zenoti.\n\nAPI keys should be kept confidential and only stored on your own servers.\n\n<h2>Token-based Authentication</h2>\n\nBesides the API Key authentication described earlier, you can also perform token-based authentication.\n\nFor Token-based Authentication, you must pass the token to all API calls. For generating tokens please refer to [Generate an access token](https://docs.zenoti.com/#074707bc-a5ab-4321-a00c-f512db7e8207). You can also [Refresh an access token](https://docs.zenoti.com/#f0422ee6-7443-43e3-9a9f-0ef7fc62b088) or [Revoke an existing access token](https://docs.zenoti.com/#6ee9cc68-9356-4bb1-bab5-47d36bf89cb6)\n\n**Note**: Employee tokens are auto-expired whenever an employee's password has been changed via Web or mobile and after an employee has been terminated.\n\n<h1>Map API calls to a custom source</h1>\n\nMap all your API calls and\n\n<a href=\"https://docs.zenoti.com/?version=latest#a9e8e1fe-ac19-41c9-93f5-5884e8404a5a\">bookings</a>\n\nto these two custom sources that are defined in Zenoti: **External-Webstore** and **External-CMA**.\n\nTo do so, follow these steps:\n\n<ol><li><p>Contact your Zenoti Customer Service Manager (CSM) and request to enable the credentials of a custom source app as per your requirement.</p></li><li><p>Zenoti's team will share these three parameters for each source app:<a href=\"https://docs.zenoti.com/?version=latest#authentication\">App ID</a>,<a href=\"https://docs.zenoti.com/?version=latest#authentication\">App Secret</a>, and<a href=\"https://docs.zenoti.com/?version=latest#authentication\">API Key</a>.</p></li><li><p>All API calls that you make with the provided API Key as the authorization parameter will be automatically mapped to the corresponding source: either External-Webstore or External-CMA.</p></li><li><p>Alternatively, you can leverage the App ID and App Secret details along with your user credentials to<a href=\"https://docs.zenoti.com/?version=latest#authentication\">generate a bearer token</a>for authorizing API calls. The calls that you make by using such a bearer token will be automatically mapped to the corresponding source: either External-Webstore or External-CMA.</p></li></ol>\n\n<h1>Support</h1>\n\nIf you require any help related to accessing the Zenoti API, reach out to us at\n\n<a href=\"mailto:apisupport@zenoti.com\">apisupport@zenoti.com</a>\n\n.\n\nIf you receive a 503 response from our servers, it implies that we have hit an unexpected spike in API access traffic and would usually be operational within the next 5 minutes. If the outage persists or if you receive any other form of 5XX error, do let us know.\n\n<h1>Rate Limits</h1>\n\nZenoti uses Rate Limits to ensure faster API response times and to maintain overall stability. If we receive a large quantity of API call requests within a small period, those requests may be throttled.\n\nIf the Rate Limit feature is enabled for your organization, here is a sample of the response headers that are displayed when only the organization (account)-level limit is defined:\n\n## Rate Limit Response Headers\n\n| Name | Value |\n| --- | --- |\n| Organization-RateLimit-Limit | 60;w=60;b=60 |\n| RateLimit-Remaining | 48 |\n| RateLimit-Reset | 50 |\n\nThe interpretation of the Rate Limit response headers is as follows:\n\n| Response Header | Description |\n| --- | --- |\n| Organization-RateLimit-Limit | 60;w=60;b=60  <br>This indicates that the refill rate is **60 calls per 60 seconds** (where, **w=60 sec**). After every 1 minute, 60 calls will be added to the bucket.  <br>  <br>**b=60** indicates that the maximum number of calls that can get accumulated over time is 60. In other words, even if you do not make any API call for 2 hours, a maximum of 60 calls will get accumulated. No more call accumulation can occur beyond this value, because 60 is the maximum capacity of the bucket. |\n| RateLimit-Remaining | The value of this response header indicates the number of remaining API calls that you can make within that particular 48 seconds. This value continuously gets updated after every API call you make and is refreshed after the end of every 48 seconds. |\n| RateLimit-Reset | The value of this response header indicates the time in seconds for the next refill of API calls. If the value is 50, it means that the rate limit will be refreshed to the maximum value of 60 after 50 seconds. |\n\nFor a detailed explanation on the use cases of different request policies and the interpretation of the respective values of the Rate Limit Response Headers, refer to [this Help article](http://help.zenoti.com/en/articles/4774922-rate-limit-response-headers).\n\n> **The standard applicable rate limit is 60 calls per minute.** To opt for a higher-volume API rate limit, reach out to your Zenoti account manager and the relevant team will share the available add-on options with you.\n\n#### Strategies to Effectively Manage Rate Limits\n\nTo avoid reaching your rate limits, you must make only the essential requests that you require.  \nHere are a few strategies that can help you to reduce the number of requests and avoid getting rate limit exception responses.\n\n- **Eliminate unnecessary API calls**.  \n    Are some of your requests receiving data items that are not used in your application? You can optimize your code to only fetch the data that your app requires.\n- **Cache frequently used data**.  \n    You can cache data on the server or on the client by using DOM storage. You can also save relatively static information in a database or serialize it in a file.For example, you can cache the list of services, therapists performing the services, and their pricing details for a service booking workflow.\n- **Use Retry Logic**.  \n    You can implement Retry logic after a certain amount of time if you receive an API rate limit exception as a response. For instance, Zenoti recommends that you verify the API responses after each API call you make. If you get an API rate limit exception, you must implement the Sleep option for some time and then try again. You should include code that catches errors. If you ignore such API rate limit exception errors and continue to make requests, your app will not be able to recover in a graceful manner. You can use the Retry-After header if you receive a 429 response for the back-off time. Alternatively, you can use metadata (included with all API responses) for your app’s API usage to dynamically control the app’s behavior.\n- **Queue API requests.**  \n    To queue your API requests for effectively managing API rate limits, use any one of several cloud applications that are available in the market. Here are a few such cloud applications that you can try out:  \n    [Amazon Simple Queue Service](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Welcome.html),  \n    [Apache ActiveMQ](http://activemq.apache.org/restful-queue.html), and [Rackspace Cloud Queues API 1.0](https://developer.rackspace.com/docs/cloud-queues/v1/).\n    \n\n**Note**: HTTP 503 and 504 errors can occur over bad network or in case of a downtime. It is general practice to have a retry mechanism in place. Zenoti recommends the API consumers to retry 2-3 times in case of HTTP 503 and HTTP 504 errors with a delay between each retry. Please contact us if you receive HTTP 503/504 errors continuously.\n\n<h1>API Reference</h1>\n\nThis section explains in detail about the various API categories and their respective API endpoints in Zenoti.","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"16255247","collectionId":"342a7a52-9b61-4eb3-bfe0-7aec1e959d10","publishedId":"2s8YmKSPwT","public":true,"publicUrl":"https://documenter-api.postman.tech/view/16255247/2s8YmKSPwT","privateUrl":"https://go.postman.co/documentation/16255247-342a7a52-9b61-4eb3-bfe0-7aec1e959d10","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"EF5B25"},"documentationLayout":"classic-double-column","customisation":null,"version":"8.10.1","publishDate":"2022-11-16T09:26:29.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{},"logos":{}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/768118b36f06c94b0306958b980558e6915839447e859fe16906e29d683976f0","favicon":""},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/2s8YmKSPwT"}