{"id":350059,"date":"2026-08-17T19:11:48","date_gmt":"2026-08-17T19:11:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/qaiyo-smart-appointment\/"},"modified":"2026-10-28T12:27:40","modified_gmt":"2026-10-28T12:27:40","slug":"qaiyo-smart-appointment","status":"publish","type":"plugin","link":"https:\/\/sl.wordpress.org\/plugins\/qaiyo-smart-appointment\/","author":23510315,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.3.3.1","stable_tag":"1.3.3.1","tested":"7.1.4","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Qaiyo Smart Appointment","header_author":"Qaiyo","header_description":"Smart appointment booking with fluid, gap-based slot allocation \u2014 let clients book mixed durations (30 min, 1 h, 2 h) that pack into the remaining open time, instead of a rigid fixed grid. Services, staff, working hours, email reminders, FluentCRM sync and a step-by-step booking form (shortcode + block).","assets_banners_color":"","last_updated":"2026-10-28 12:27:40","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/qaiyo-plugins.com\/qaiyo-smart-appointment\/","header_author_uri":"https:\/\/qaiyo-plugins.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":666,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"qaiyo","date":"2026-10-21 10:26:28","revision":3758127},"1.2.0":{"tag":"1.2.0","author":"qaiyo","date":"2026-10-21 10:26:28","revision":3758127},"1.3.0":{"tag":"1.3.0","author":"qaiyo","date":"2026-10-21 10:26:28","revision":3758127},"1.3.1":{"tag":"1.3.1","author":"qaiyo","date":"2026-10-21 08:06:56","revision":3757910},"1.3.2":{"tag":"1.3.2","author":"qaiyo","date":"2026-10-21 10:26:28","revision":3758127},"1.3.3":{"tag":"1.3.3","author":"qaiyo","date":"2026-10-27 19:47:28","revision":3769368},"1.3.3.1":{"tag":"1.3.3.1","author":"qaiyo","date":"2026-10-28 12:27:40","revision":3770657}},"upgrade_notice":{"1.3.3.1":"<p>Fixes an email-signature status image stuck on an old status behind some CDNs. Copy the signature HTML again after updating.<\/p>","1.3.3":"<p>Adds a live status image for email signatures, and gives Days off, Booking layout and Email signature screens of their own.<\/p>","1.3.2":"<p>Adds the opening hours widget and named days off, makes the booking form fully keyboard and screen-reader accessible and ready for right-to-left languages, and keeps it working on cached pages.<\/p>","1.3.1":"<p>Adds &quot;Add to calendar&quot;: a calendar file and a Google Calendar link in the confirmation and reminder emails and on the booking form. Also restores built-in email wording on sites where saving the settings had frozen it.<\/p>","1.3.0":"<p>Stops double bookings when two customers submit the same slot at once, and makes the emailed Approve \/ Decline links ask before they act. Adds the &quot;Upcoming&quot; agenda card. Requires WordPress 6.2.<\/p>","1.2.0":"<p>A &quot;Today&#039;s appointments&quot; card for the Qaiyo ecosystem dashboard widget (needs the free Admin Booster plugin), showing today&#039;s count and the next booking&#039;s time.<\/p>","1.1.0":"<p>Native widgets for Elementor, Bricks, Breakdance and Oxygen, and a fix for the Gutenberg block, which never actually worked before this release.<\/p>","1.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3656630,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.2.0","1.3.0","1.3.1","1.3.2","1.3.3","1.3.3.1"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"The step-by-step booking wizard.","2":"Admin dashboard with upcoming appointments.","3":"Services management with per-service duration and buffers.","4":"Booking rules and working hours."}},"plugin_section":[],"plugin_tags":[8132,269,416,191665,268],"plugin_category":[40],"plugin_contributors":[267332],"plugin_business_model":[],"class_list":["post-350059","plugin","type-plugin","status-publish","hentry","plugin_tags-appointments","plugin_tags-booking","plugin_tags-calendar","plugin_tags-fluentcrm","plugin_tags-scheduling","plugin_category-calendar-and-events","plugin_contributors-qaiyo","plugin_committers-qaiyo"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/qaiyo-smart-appointment\/assets\/icon-256x256.png?rev=3656630","icon_2x":"https:\/\/ps.w.org\/qaiyo-smart-appointment\/assets\/icon-256x256.png?rev=3656630","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Qaiyo Smart Appointment is a clean, fast scheduling plugin for service businesses \u2014 salons, clinics, coaches, consultants, studios and freelancers.<\/p>\n\n<p>Its standout feature is <strong>fluid slot allocation<\/strong>. Most booking plugins slice the day into a fixed grid for one chosen duration. Qaiyo instead works on the <em>open gaps<\/em> around existing appointments and fits each requested service into whatever space is left. Book a 2-hour service, then a 1-hour one, and the remaining time stays fully bookable for any mix of shorter or longer services that still fit \u2014 packed dynamically, never wasted.<\/p>\n\n<h4>Free features<\/h4>\n\n<ul>\n<li>Fluid, gap-based slot engine (mixed durations in the same day)<\/li>\n<li>Unlimited services, staff members and bookings \u2014 no caps of any kind<\/li>\n<li>Step-by-step booking wizard, placed with a shortcode <code>[qsab_booking]<\/code>, a Gutenberg block, or a native widget in Elementor, Bricks, Breakdance or Oxygen \u2014 the same settings in every one<\/li>\n<li>\"Anyone available\" or specific staff selection<\/li>\n<li>Per-service duration, price, colour and buffer times<\/li>\n<li>Fixed mode too \u2014 classic back-to-back time bands, if you prefer them, set globally or per service<\/li>\n<li>Quote requests \u2014 a booking mode that reserves no time at all: the customer names a preferred day and part of day and asks for a price, so an enquiry never takes a slot away from a real booking and two enquiries never clash<\/li>\n<li>Online payments \u2014 require payment before confirming a service, and the customer pays on a hosted checkout before the booking is confirmed. WooCommerce is the built-in provider, so you keep whatever gateways your shop already has (card, PayPal, bank transfer, cash on arrival)<\/li>\n<li>Working hours per staff member, with split shifts (e.g. a lunch break), falling back to your global opening hours<\/li>\n<li>Days off \/ vacation blocking \u2014 each range can carry a name (\"Vacation\", \"Public holiday\") that your visitors see<\/li>\n<li>Opening hours widget \u2014 <code>[qsab_hours]<\/code> shortcode, block and page-builder widget: your weekly hours with today highlighted, whether you are open right now and until when, and a notice for coming days off. It stays correct on cached pages<\/li>\n<li>Soft hold \u2014 a request can leave the time open until you approve it, so an enquiry never locks a resource; first approval wins<\/li>\n<li>One-click Approve \/ Decline buttons right inside the admin notification email<\/li>\n<li>Editable emails \u2014 five messages (request received, confirmed, cancelled, completed, reminder) plus the admin alert, each with its own on\/off switch and its own wording, written with merge tags like <code>{customer_name}<\/code> and <code>{when}<\/code><\/li>\n<li>Appointment reminders \u2014 an automatic email a set number of hours before a confirmed booking, sent once and only once<\/li>\n<li>Add to calendar \u2014 the confirmation and the reminder carry a calendar file (.ics) for Apple Calendar, Outlook and the rest, plus an \"Add to Google Calendar\" link; the booking form offers both the moment a booking is confirmed. The entry shows the service and its time, never the customer<\/li>\n<li>Public availability calendar \u2014 <code>[qsab_availability]<\/code> shortcode and block showing free and fully-booked days at a glance, with no customer details on the page<\/li>\n<li>\"Upcoming\" agenda card \u2014 <code>[qsab_upcoming]<\/code> shortcode and page-builder widget: today's date, how many bookings today has, and the next few bookings with their service colour and time. It shows what runs and when, never who booked, so it is safe on a public page; it can also be kept to logged-in users for a team page<\/li>\n<li>Two customers cannot take the same time \u2014 a booking is re-checked the moment it is stored, so simultaneous submissions for one slot never both succeed<\/li>\n<li>Customers always see the time their service starts, not the buffer reserved around it<\/li>\n<li>Personal data tools \u2014 bookings appear in WordPress's own Export \/ Erase Personal Data screens, and the suggested privacy-policy text lists what is stored<\/li>\n<li>Spam trap and a per-connection limit on the booking form, so bots cannot fill your calendar with junk requests<\/li>\n<li>One-click confirm \/ cancel \/ complete in the admin, and permanent delete (single or in bulk) for clearing out test data<\/li>\n<li>Customer self-cancellation links<\/li>\n<li>Settings export \/ import (JSON)<\/li>\n<li>FluentCRM integration \u2014 add booking customers to your lists &amp; tags automatically<\/li>\n<li>Qaiyo ecosystem dashboard card \u2014 if you also run Qaiyo Admin Booster, a \"Today's appointments\" card on your WordPress dashboard shows today's booking count and the next appointment's time<\/li>\n<li>Live status in your email signature \u2014 a small image (\"Open now \u00b7 until 17:00\") for an HTML signature, drawn at the moment the email is opened. Off until you switch it on<\/li>\n<li>Accessible to WCAG 2.2 AA (keyboard, screen readers, focus, contrast, reduced motion) and ready for right-to-left languages<\/li>\n<li>Translated into Hungarian, German, French, Spanish, Japanese, Portuguese, Italian, Russian, Turkish and Polish<\/li>\n<\/ul>\n\n<h4>Pro features<\/h4>\n\n<p>The Pro add-on is a separate plugin. Everything above keeps working without it.<\/p>\n\n<ul>\n<li>Stripe and PayPal connected directly, for sites with no shop \u2014 the customer pays on the provider's own hosted page, and the booking confirms from the webhook, from the customer's return, or from an hourly check, whichever comes first<\/li>\n<li>Deposits \u2014 collect a percentage or a fixed amount up front instead of the full price<\/li>\n<li>Five more booking modes: group sessions for classes, hourly and multi-day rentals where the customer picks the length, an arrival-order queue, and recurring series booked (and paid for) in one go<\/li>\n<li>Customer booking portal \u2014 customers look up and cancel their upcoming bookings through a short-lived emailed link, with no account to create<\/li>\n<li>Waiting list \u2014 customers join a full day and are emailed, one at a time, when a slot frees up<\/li>\n<li>Multiple locations, each with its own opening hours; the customer picks one on the form<\/li>\n<li>Staff days off \u2014 take one person out for a holiday or a sick day while the rest of the team stays bookable<\/li>\n<li>Daily breaks and per-service booking windows<\/li>\n<li>Custom branding (colour, font, logo) and three more booking-form layouts<\/li>\n<li>A richer \"Today's appointments\" dashboard card (with Admin Booster)<\/li>\n<\/ul>\n\n<p>Learn more at <a href=\"https:\/\/qaiyo-plugins.com\/qaiyo-smart-appointment\/\">qaiyo-plugins.com<\/a>.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin makes one outbound request, and only from the WordPress admin.<\/p>\n\n<p><strong>WordPress.org plugin directory API<\/strong> \u2014 used by the \"Discover Qaiyo\" screen\n(Smart Booking \u2192 Discover Qaiyo) to list the plugin author's other free plugins so\nyou can install one without leaving your site.<\/p>\n\n<ul>\n<li>What it is used for: fetching the public plugin listings (name, description,\nicon, ratings, install count) for author \"qaiyo\".<\/li>\n<li>When the request happens: only when a logged-in administrator opens that screen,\nand at most once every 12 hours \u2014 the response is cached in a transient.<\/li>\n<li>What is sent: the query itself (the author name and the fields requested). This\ngoes through WordPress's own <code>plugins_api()<\/code> function, which is the same call the\nbuilt-in Plugins \u2192 Add New screen makes. No personal data, no site data and\nnothing about your visitors or bookings is transmitted.<\/li>\n<li>Endpoint: https:\/\/api.wordpress.org\/plugins\/info\/1.2\/<\/li>\n<\/ul>\n\n<p>This service is provided by WordPress.org: <a href=\"https:\/\/wordpress.org\/about\/privacy\/\">terms of service<\/a>,\n<a href=\"https:\/\/wordpress.org\/about\/privacy\/\">privacy policy<\/a>.<\/p>\n\n<p><strong>Google Calendar \u2014 a link, not a connection.<\/strong> With \"Add to calendar\" on (Settings \u2192 Emails, on by default), confirmation and reminder emails and the booking form's success screen contain an \"Add to Google Calendar\" link. The plugin itself never contacts Google.<\/p>\n\n<ul>\n<li>What it is used for: letting a customer add their own booking to their own Google Calendar.<\/li>\n<li>When anything is sent: only if the customer follows the link. Their browser then opens Google Calendar's new-event page.<\/li>\n<li>What is sent: what the link itself holds \u2014 the service name, your site's name, the staff member's name, the start and end time and, with the Pro add-on, the location. Nothing about the customer is in it.<\/li>\n<li>Endpoint: https:\/\/calendar.google.com\/calendar\/render<\/li>\n<\/ul>\n\n<p>This service is provided by Google: <a href=\"https:\/\/policies.google.com\/terms\">terms of service<\/a>, <a href=\"https:\/\/policies.google.com\/privacy\">privacy policy<\/a>.<\/p>\n\n<p>The calendar file (.ics) involves no service at all: it is attached to the email and generated in the booking response.<\/p>\n\n<p>The booking form itself makes no external requests. Booking data stays in your\ndatabase, and notification emails are sent with <code>wp_mail()<\/code> through whatever your\nsite is already configured to use.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>\/wp-content\/plugins\/<\/code> and activate it.<\/li>\n<li>Go to <strong>Smart Booking \u2192 Services<\/strong> and add your services.<\/li>\n<li>(Optional) Add staff under <strong>Smart Booking \u2192 Staff<\/strong>.<\/li>\n<li>Set your opening hours under <strong>Smart Booking \u2192 Settings<\/strong>.<\/li>\n<li>Add the booking form to any page with the <code>[qsab_booking]<\/code> shortcode or the block.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20makes%20the%20slot%20engine%20%22fluid%22%3F\"><h3>What makes the slot engine \"fluid\"?<\/h3><\/dt>\n<dd><p>It computes availability from the real free gaps around existing bookings, then fits the chosen service duration into them on a configurable step grid \u2014 instead of pre-dividing the day into fixed equal slots. Mixed-length services share the same day efficiently.<\/p><\/dd>\n<dt id=\"does%20it%20work%20without%20staff%3F\"><h3>Does it work without staff?<\/h3><\/dt>\n<dd><p>Yes. With no staff defined, bookings run on the global working hours automatically.<\/p><\/dd>\n<dt id=\"does%20it%20require%20woocommerce%3F\"><h3>Does it require WooCommerce?<\/h3><\/dt>\n<dd><p>No, the plugin works standalone without it. A payment provider is only needed if you turn on \"Require payment\" for a service, and WooCommerce is the one this plugin ships with \u2014 activate it and the option appears. (Pro adds Stripe and PayPal as direct alternatives, for sites that do not want a shop.) Nothing changes for services that don't require payment.<\/p><\/dd>\n<dt id=\"can%20customers%20ask%20for%20a%20price%20without%20booking%20a%20time%3F\"><h3>Can customers ask for a price without booking a time?<\/h3><\/dt>\n<dd><p>Yes. Set the service's booking mode to quote request. The customer picks a day and whether morning, afternoon or evening suits them, and nothing is reserved \u2014 the enquiry never blocks a real booking, and two enquiries for the same morning never clash. Answer it, then book the agreed time normally.<\/p><\/dd>\n<dt id=\"can%20i%20change%20what%20the%20emails%20say%2C%20or%20switch%20some%20of%20them%20off%3F\"><h3>Can I change what the emails say, or switch some of them off?<\/h3><\/dt>\n<dd><p>Yes. Under Smart Booking \u2192 Settings \u2192 Emails every message has its own on\/off switch and its own editable subject and wording. Write them with merge tags \u2014 <code>{customer_name}<\/code>, <code>{service}<\/code>, <code>{when}<\/code>, <code>{price}<\/code>, <code>{cancel_link}<\/code> and more \u2014 and clear a field to go back to the built-in text.<\/p><\/dd>\n<dt id=\"how%20do%20customers%20get%20a%20booking%20into%20their%20calendar%3F\"><h3>How do customers get a booking into their calendar?<\/h3><\/dt>\n<dd><p>Two ways, both automatic once a booking is confirmed. The confirmation and reminder emails have a calendar file attached (<code>appointment.ics<\/code>) \u2014 opening it adds the appointment to Apple Calendar, Outlook or any other calendar app \u2014 and an \"Add to Google Calendar\" link. The booking form shows the same two options on its success screen when a booking is confirmed on the spot.<\/p>\n\n<p>The calendar entry holds the service, its time and the staff member. It never names the customer and never contains the cancel link, because calendar entries get shared and synced. A request that is still waiting for your approval gets neither, and nor does a quote request. If you rewrote an email, add the <code>{calendar_link}<\/code> tag where the link should go; the file is attached either way. Switch the whole thing off under Settings \u2192 Emails \u2192 Add to calendar.<\/p><\/dd>\n<dt id=\"how%20do%20reminders%20work%3F\"><h3>How do reminders work?<\/h3><\/dt>\n<dd><p>Turn the reminder email on under Settings \u2192 Emails and set how many hours before the booking it should go out. A background sweep runs hourly and sends the reminder to every confirmed booking that has entered the window, marking each one so it can never be sent twice. Pending bookings are skipped, because there is nothing confirmed to remind anyone about yet.<\/p><\/dd>\n<dt id=\"can%20i%20show%20my%20availability%20on%20a%20page%20without%20the%20booking%20form%3F\"><h3>Can I show my availability on a page without the booking form?<\/h3><\/dt>\n<dd><p>Yes, with the <code>[qsab_availability]<\/code> shortcode or the matching block. It shows which days and times are still open and which are fully booked or closed. It never shows who booked what \u2014 only free and busy, exactly what the booking form itself would reveal.<\/p>\n\n<p>Attributes: <code>service<\/code> (a service id, defaults to your first active service), <code>staff<\/code> (a staff id, defaults to anyone) and <code>days<\/code> (how many days to show, default 7).<\/p><\/dd>\n<dt id=\"can%20i%20show%20today%27s%20schedule%20on%20a%20page%2C%20like%20a%20reception%20screen%3F\"><h3>Can I show today's schedule on a page, like a reception screen?<\/h3><\/dt>\n<dd><p>Yes, with the <code>[qsab_upcoming]<\/code> shortcode or the \"Qaiyo Upcoming\" widget in your page builder. It shows today's date and how many bookings today has, then the next confirmed bookings \u2014 the service, its colour and its time. It never shows who booked, so it is safe on a public page.<\/p>\n\n<p>Attributes: <code>title<\/code> (defaults to \"Upcoming\" in the visitor's language), <code>count<\/code> (1\u201310, default 3), <code>service<\/code> and <code>staff<\/code> (ids, to show one of them only), <code>show_date<\/code> (<code>0<\/code> hides the date tile), <code>theme<\/code> (<code>auto<\/code>, <code>light<\/code> or <code>dark<\/code>) and <code>audience<\/code> (<code>logged_in<\/code> shows it to logged-in users only).<\/p><\/dd>\n<dt id=\"can%20i%20show%20my%20opening%20hours%20and%20whether%20i%20am%20open%20right%20now%3F\"><h3>Can I show my opening hours and whether I am open right now?<\/h3><\/dt>\n<dd><p>Yes, with the <code>[qsab_hours]<\/code> shortcode or the \"Qaiyo Opening Hours\" widget. It shows your weekly hours (from Settings \u2192 Working hours, lunch breaks included) with today highlighted, a line saying whether you are open at this moment and when you open next, and a notice for any day off coming up \u2014 give a range a name under Settings \u2192 Days off, such as \"Vacation\", and that is what your visitors read.<\/p>\n\n<p>Pages are often cached, and \"open now\" is only true for a moment, so the widget carries the next two weeks with it and keeps itself current in the visitor's browser.<\/p>\n\n<p>Attributes: <code>title<\/code>, <code>show_title<\/code> (<code>0<\/code> hides the heading), <code>staff<\/code> (one person's hours), <code>layout<\/code> (<code>box<\/code>, the default, or <code>full<\/code> for the full width of the column \u2014 in a page builder the width you give the element wins), <code>show_status<\/code>, <code>show_week<\/code> (<code>0<\/code> hides either part), <code>notice_days<\/code> (how many days ahead to announce a day off, default 14; <code>0<\/code> only while it lasts) and <code>theme<\/code> (<code>auto<\/code>, <code>light<\/code> or <code>dark<\/code>).<\/p><\/dd>\n<dt id=\"can%20my%20email%20signature%20show%20whether%20i%20am%20available%3F\"><h3>Can my email signature show whether I am available?<\/h3><\/dt>\n<dd><p>Yes. Switch on the status image under Smart Booking \u2192 <strong>Email signature<\/strong> and copy the HTML it gives you into your signature. It is a small image \u2014 \"Open now \u00b7 until 17:00\", \"Vacation \u00b7 Opens Monday at 09:00\" \u2014 that your site draws at the moment a reader's mail program loads it, from the same hours and days off as the opening hours widget, and it links to the page you choose.<\/p>\n\n<p>Gmail, Outlook and most mail programs load it every time the email is opened. Apple Mail with Mail Privacy Protection loads images in advance, so there it can show the status of when the message arrived; and some programs only show images after the reader allows them. The address is public (anyone who receives your email can open it) and shows nothing your opening hours do not already show. Drawing it needs PHP's GD extension with FreeType, which most hosts have; the settings card tells you if yours does not.<\/p><\/dd>\n<dt id=\"can%20i%20change%20%22open%20now%22%20on%20the%20status%20image%3F\"><h3>Can I change \"Open now\" on the status image?<\/h3><\/dt>\n<dd><p>Yes: under Email signature, <strong>Text while open<\/strong> and <strong>Text while closed<\/strong> \u2014 \"Available\" and \"Away\", say. The time after it stays, and a day off still shows its own name.<\/p><\/dd>\n<dt id=\"can%20i%20call%20the%20break%20%22lunch%20break%22%3F\"><h3>Can I call the break \"Lunch break\"?<\/h3><\/dt>\n<dd><p>With the Pro add-on, yes: each weekday's daily break under Availability has a name field, and the opening hours widget shows \"Lunch break: 12:00 \u2013 13:00\". Without a name it reads \"Break\".<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20put%20a%20link%20to%20qaiyo%20on%20my%20site%3F\"><h3>Does the plugin put a link to Qaiyo on my site?<\/h3><\/dt>\n<dd><p>Not unless you ask it to. A small \"Booking by Qaiyo\" line under the booking form is off by default; you can switch it on under Settings \u2192 Booking rules.<\/p><\/dd>\n<dt id=\"can%20i%20use%20this%20with%20my%20page%20builder%3F\"><h3>Can I use this with my page builder?<\/h3><\/dt>\n<dd><p>Yes. The booking form, the availability calendar, the \"Upcoming\" card and the opening hours are available as native widgets in Gutenberg, Elementor, Bricks, Breakdance and Oxygen, alongside the shortcodes. Each one offers the same settings, and each renders exactly what the front end renders \u2014 no separate preview to drift out of date.<\/p><\/dd>\n<dt id=\"what%20is%20the%20%22today%27s%20appointments%22%20card%20on%20my%20dashboard%3F\"><h3>What is the \"Today's appointments\" card on my dashboard?<\/h3><\/dt>\n<dd><p>If you also run the free <a href=\"https:\/\/qaiyo-plugins.com\/qaiyo-admin-booster\/\">Qaiyo Admin Booster<\/a> plugin, it collects a summary card from every installed Qaiyo plugin into one \"Qaiyo ecosystem\" widget on your WordPress dashboard. This plugin's card shows today's booking count and the time of the next one. It costs nothing extra and needs no setup \u2014 it simply appears once Admin Booster is active. Without Admin Booster, nothing changes; this plugin does not add a card of its own to the dashboard.<\/p><\/dd>\n<dt id=\"someone%20is%20spamming%20my%20booking%20form.%20what%20can%20i%20do%3F\"><h3>Someone is spamming my booking form. What can I do?<\/h3><\/dt>\n<dd><p>Two things, both built in. The form already carries a hidden spam trap that silently refuses automated submissions. And under Settings \u2192 Booking rules, turning off auto-confirm and turning on <strong>Requests do not reserve the time (soft hold)<\/strong> means a pending request no longer blocks the slot for anyone else \u2014 so even a flood of junk requests cannot take your calendar out of action. You approve the real ones, and the first approval wins.<\/p><\/dd>\n<dt id=\"how%20does%20the%20plugin%20handle%20personal%20data%3F\"><h3>How does the plugin handle personal data?<\/h3><\/dt>\n<dd><p>A booking stores the name, email address and phone number the customer gives, the service and time, and any note. Nothing is sent anywhere else. Bookings are included in WordPress's own Tools \u2192 Export Personal Data and Erase Personal Data screens \u2014 erasing anonymises a booking rather than deleting it, so the calendar still knows the time was taken \u2014 and a suggested paragraph for your privacy policy is added under Settings \u2192 Privacy.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20my%20data%20if%20i%20delete%20the%20plugin%3F\"><h3>What happens to my data if I delete the plugin?<\/h3><\/dt>\n<dd><p>Nothing is removed by default. Deactivating never touches your data, and deleting the plugin from the Plugins screen keeps every service, staff member, booking and setting in place \u2014 so reinstalling, moving hosts or troubleshooting costs you nothing.<\/p>\n\n<p>If you would rather leave no trace, tick <strong>Delete all plugin data when the plugin is deleted<\/strong> under Smart Booking \u2192 Settings \u2192 Data on uninstall. With that armed, deleting the plugin drops its database tables and options for good. There is no undo, so export your settings and back up the database first.<\/p><\/dd>\n<dt id=\"can%20customers%20rent%20something%20by%20the%20hour%20or%20by%20the%20day%2C%20or%20book%20a%20class%3F\"><h3>Can customers rent something by the hour or by the day, or book a class?<\/h3><\/dt>\n<dd><p>Those are Pro booking modes. Hourly and multi-day rentals let the customer choose the length; group sessions let several people share one fixed time.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.3.3.1<\/h4>\n\n<ul>\n<li>Fixed: the email-signature status image could keep showing an old status \u2014 yesterday evening's \"Closed\" in the morning \u2014 in Apple Mail and in browsers. A CDN in front of some sites (Cloudflare, for one) told mail programs to keep anything ending in .png for a year. The image now has to be asked for again every time it is shown (an unchanged one costs a bodiless \"not modified\" answer), and CDNs are told not to store it.<\/li>\n<li>The signature HTML carries a new image address, so copies kept under the old one are left behind: copy the HTML from the Email signature screen again and paste it into your signature.<\/li>\n<li>The preview on the Email signature screen always shows the current status.<\/li>\n<\/ul>\n\n<h4>1.3.3<\/h4>\n\n<ul>\n<li>New: live status in your email signature. Switch it on under the new Email signature screen and paste the HTML it gives you into an HTML signature: a small image \u2014 \"Open now \u00b7 until 17:00\", \"Vacation \u00b7 Opens Monday at 09:00\" \u2014 drawn at the moment the email is opened, linking to the page you choose. Light or dark, the default hours or one person's. Off until you switch it on.<\/li>\n<li>New: your own wording on the status image \u2014 \"Available\" \/ \"Away\" instead of \"Open now\" \/ \"Closed now\". Translatable with WPML and Polylang.<\/li>\n<li>New: every part of the status line can be reworded \u2014 the time after it too (\"{time}-ig\", \"Back {day} at {time}\") \u2014 and the image comes as a pill or as plain text on a clear background, light, dark or automatic (follows light \/ dark mode where the mail program can, as Apple Mail does). The link, layout, colours and person are saved with the screen.<\/li>\n<li>The image address ends in <code>qsab-status.png<\/code>, which Apple Mail needs before it shows an image at all; where a server does not pass such addresses to WordPress, the screen says so and the address falls back to the site's main one.<\/li>\n<li>Changed: Days off \/ vacation, Booking layout (when there is more than one) and Email signature have screens and tabs of their own instead of living inside Settings.<\/li>\n<li>For add-ons: the opening hours ask <code>qsab_hours_break_label<\/code> for each date's name of the break (the Pro add-on names its daily breaks per weekday).<\/li>\n<li>The status image is drawn in Inter (SIL Open Font License), bundled in <code>assets\/fonts<\/code> and limited to Latin and Cyrillic; the <code>qsab_status_badge_font<\/code> filter supplies a font for other scripts.<\/li>\n<li>For developers: <code>qsab_status_badge_font<\/code>.<\/li>\n<\/ul>\n\n<h4>1.3.2<\/h4>\n\n<ul>\n<li>New: the opening hours widget \u2014 <code>[qsab_hours]<\/code> shortcode and a widget in Gutenberg, Elementor, Bricks, Breakdance and Oxygen. Weekly hours with today highlighted and breaks shown \u2014 in a compact box or at full width, \"Open now \u00b7 until 17:00\" \/ \"Opens tomorrow at 09:00\", and a notice for coming days off. It carries the next two weeks with it, so a page served from a cache still shows the right status.<\/li>\n<li>The table names a day off only within the current week; one coming next week is announced by the notice above it, so a passed weekday never looks as if its day off were already over.<\/li>\n<li>New: a days-off range can have a name visitors see (\"Vacation\"), and the Days off card shows where each range stands (going on now, in 5 days, over) with one click to clear the ones that are over. Names and reworded emails are translatable with WPML and Polylang.<\/li>\n<li>Accessibility (WCAG 2.2 AA): the booking form moves focus to each new step, announces loading and results, ties errors to their fields, marks the selected service, day and time for screen readers, names the calendar's buttons with the full date, and shows a clear focus ring whatever the theme does. Required fields say so in words. Text, field outlines and status labels meet contrast minimums, and motion follows the reduced-motion setting. In the admin, every schedule field has a name, and choosing whose hours to edit no longer reloads the page by itself.<\/li>\n<li>Right-to-left languages: the booking form, the widgets and the admin screens mirror correctly, and emails are written in the site's direction.<\/li>\n<li>The calendar starts the week on the day set under Settings \u2192 General.<\/li>\n<li>Fixed: two booking forms on one page shared their field ids, so a label could point into the other form and a preselected service applied to the wrong one.<\/li>\n<li>Fixed: on a page served from a cache for more than a day, the booking form failed with a bare \"Error\". It now fetches a fresh security token and tries again.<\/li>\n<li>Fixed: a cancellation form left open too long sent the customer to the home page; it now simply asks again.<\/li>\n<li>Fixed: theme styles (upper-case buttons, list bullets, field heights) leaked into the booking form.<\/li>\n<li>Changed: the \"Booking by Qaiyo\" link under the booking form is now off unless you switch it on.<\/li>\n<li>Security: a customer's note is capped at 2,000 characters, and an email address longer than the database holds is refused instead of being cut.<\/li>\n<li>For developers: the <code>qsab_hours_windows<\/code> filter, and the Settings screen is built from small templates in <code>templates\/admin\/<\/code>.<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>New: Add to calendar. Confirmation and reminder emails carry a calendar file (.ics) and an \"Add to Google Calendar\" link, and the booking form offers both on its success screen when a booking is confirmed there and then. The entry shows the service, its time and the staff member \u2014 never the customer, and never the cancel link. On by default; switch it off under Settings \u2192 Emails.<\/li>\n<li>New: the <code>{calendar_link}<\/code> email tag, already in the built-in confirmation and reminder wording.<\/li>\n<li>Fixed: saving the Emails settings stored every untouched built-in message as if it had been rewritten, so those sites stopped receiving wording improvements and translations. Built-in wording is recognised again, including on sites that already saved it.<\/li>\n<li>For developers: <code>qsab_calendar_enabled<\/code>, <code>qsab_calendar_event<\/code> (add a location), <code>qsab_calendar_rows<\/code>, <code>qsab_calendar_uid<\/code>, <code>qsab_calendar_google_args<\/code> and <code>qsab_calendar_emails<\/code>.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New: the \"Upcoming\" agenda card \u2014 <code>[qsab_upcoming]<\/code> shortcode and a widget in Gutenberg, Elementor, Bricks, Breakdance and Oxygen. Today's date and booking count, then the next bookings with their service colour and time; never who booked.<\/li>\n<li>Fixed: two customers submitting the same slot at the same moment could both get it. A booking is now re-checked the moment it is stored, and approvals, status changes and reminders are all compare-and-set, so a double click or two overlapping requests act exactly once.<\/li>\n<li>Fixed: following an Approve or Decline link from the admin email acted on the booking straight away \u2014 mail scanners that open every link could approve and then decline a request before anyone read it. The link now shows a confirmation screen, like the customer cancel link.<\/li>\n<li>Fixed: saving one Settings form (booking rules, say) switched off the options of the others, such as FluentCRM sync. Each form now only changes its own settings.<\/li>\n<li>Fixed: emails, the admin list and the customer screens showed the buffer around a booking as part of its time. They now show when the service itself runs.<\/li>\n<li>Fixed: an unpaid WooCommerce order held its time slot forever. It is now cancelled by the store's own \"hold stock\" timeout, which releases the slot; and a paid booking is re-checked against the calendar before it is confirmed.<\/li>\n<li>Fixed: FluentCRM re-subscribed customers who had unsubscribed when they booked again. An existing contact keeps its status.<\/li>\n<li>Fixed: the appointments list stopped at 200 bookings. It is now paged.<\/li>\n<li>Fixed: the availability calendar showed a day off as \"Fully booked\"; it now reads \"Closed\".<\/li>\n<li>Changed: the widgets sit in their own \"Qaiyo Smart Appointment\" group in Gutenberg, Elementor, Bricks, Breakdance and Oxygen (it used to read just \"Qaiyo\", and the blocks sat under Widgets).<\/li>\n<li>New: a per-connection limit on the booking form, on top of the spam trap.<\/li>\n<li>New: bookings are included in WordPress's Export \/ Erase Personal Data tools, with suggested privacy-policy text.<\/li>\n<li>Security: stricter output filtering for everything the page-builder widgets print, and error messages are no longer passed through the URL.<\/li>\n<li>Requires WordPress 6.2 or later.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>New: a \"Today's appointments\" card for the Qaiyo ecosystem dashboard widget, shown when the free Qaiyo Admin Booster plugin is also active. Shows today's booking count and the time of the next one; nothing appears if Admin Booster is not installed.<\/li>\n<li>New extension point: <code>qsab_ecosystem_card_body<\/code>, which the Pro add-on uses to replace that card's body with the next three bookings and a link to the calendar \u2014 see the Pro changelog.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Native page-builder widgets: the booking form and the availability calendar are now available as widgets in Elementor, Bricks, Breakdance and Oxygen (6.x), on top of the existing shortcodes. One shared definition feeds every builder, so a setting behaves identically everywhere and an add-on can contribute a control to all of them at once through the new <code>qsab_widget_fields<\/code> filter.<\/li>\n<li>Fixed: the Gutenberg block never actually worked \u2014 it was registered on the PHP side only, with no editor script, so it never appeared in the block inserter despite being documented. It now registers properly, with real inspector controls (built from the same shared definition as the other builders) and a live preview.<\/li>\n<li>A booking form can now be given its own layout per placement, overriding the site-wide default set in Settings.<\/li>\n<li>Hardened CSS output: branding values (accent colour, font) and per-service colour swatches are now validated for the CSS context specifically, rather than relying on HTML escaping, which cannot stop a value from breaking out of a stylesheet declaration.<\/li>\n<li>Tested up to WordPress 7.1.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<li>Fluid, gap-based slot engine, plus a fixed mode with classic back-to-back bands.<\/li>\n<li>Booking wizard (shortcode <code>[qsab_booking]<\/code> + block), with unlimited services, staff members and bookings.<\/li>\n<li>Working hours per staff member, including split shifts \u2014 a second block on a day makes the gap between them unbookable. Anyone without their own hours works the site-wide default.<\/li>\n<li>Soft hold: pending requests can leave the time slot open for everyone else until you approve one \u2014 first approval wins. Built for rental and enquiry-style bookings.<\/li>\n<li>One-click Approve \/ Decline buttons in the admin notification email, signed so no login is needed and nobody else can use them.<\/li>\n<li>Quote requests: a booking mode that reserves nothing. The customer names a preferred day and part of day, so an enquiry never blocks a real booking and two enquiries never collide.<\/li>\n<li>Per-service booking mode: any service can override the site-wide fluid\/fixed setting, so a consultation and an enquiry can behave differently on the same site.<\/li>\n<li>Editable emails: six messages (request received, confirmed, cancelled, completed, reminder, plus the admin alert), each with its own on\/off switch and its own subject and wording, written with merge tags. Blank fields fall back to the built-in text, so clearing a field restores it rather than sending an empty email.<\/li>\n<li>Appointment reminders: an hourly sweep emails every confirmed booking a configurable number of hours before it starts, flagging each row so a reminder can never go out twice however often WP-Cron fires.<\/li>\n<li>Public availability calendar: the <code>[qsab_availability]<\/code> shortcode and matching block show free, fully-booked and closed days without putting any customer detail on the page.<\/li>\n<li>Spam trap on the booking form \u2014 an off-screen field that only an automated submission would fill in.<\/li>\n<li>Customer cancellation links ask before they act: following one shows the booking and a confirm button, so a mail client or scanner prefetching the URL cannot cancel anything.<\/li>\n<li>Permanent delete for bookings, one at a time or in bulk, for clearing test data out before handing a site over.<\/li>\n<li>Online payments: a service can require payment before it is confirmed. The built-in provider is WooCommerce, which creates an order for the price and sends the customer to your checkout; paying it confirms the booking, and a cancelled or failed order releases the time slot.<\/li>\n<li>Uninstall keeps your data by default. Deleting the plugin only drops its tables and options when \"Delete all plugin data\" has been ticked under Settings first.<\/li>\n<li>Configurable currency symbol and position for displayed prices.<\/li>\n<li>Days off \/ vacation blocking, and settings export \/ import.<\/li>\n<li>FluentCRM sync, and 11 built-in languages.<\/li>\n<li>Native page-builder widgets: the booking form and the availability calendar are available as Gutenberg blocks and as native widgets in Elementor, Bricks, Breakdance and Oxygen, each with the same settings \u2014 which service to preselect, which staff member, how many days to show. One shared definition feeds every builder, so they cannot drift apart, and an add-on can contribute a setting to all of them at once through the <code>qsab_widget_fields<\/code> filter.<\/li>\n<li>A booking form can be given its own layout per placement rather than following the site-wide setting.<\/li>\n<li>Values reaching a stylesheet are validated for the CSS context rather than HTML-escaped, so a branding token from the <code>qsab_branding<\/code> filter cannot inject CSS.<\/li>\n<li>Extension points for add-ons: <code>qsab_booking_modes<\/code> \/ <code>qsab_mode_slots<\/code> register a booking mode, <code>qsab_service_form_fields<\/code> \/ <code>qsab_service_save_data<\/code> add its per-service settings, <code>qsab_booking_slot<\/code> finishes the booking off, <code>qsab_payment_providers<\/code> \/ <code>qsab_payment_url<\/code> register a payment provider, <code>qsab_email_types<\/code> registers a notification, and <code>qsab_appointment_deleted<\/code> lets an add-on clean up after a deletion. The booking form dispatches <code>qsab:slots-rendered<\/code>, <code>qsab:slot-selected<\/code>, <code>qsab:summary<\/code> and <code>qsab:collect<\/code> so an add-on can extend it without replacing any markup.<\/li>\n<\/ul>","raw_excerpt":"Smart appointment booking with fluid, gap-based slot allocation. Let clients book mixed durations that pack into the time you actually have free.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/350059","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=350059"}],"author":[{"embeddable":true,"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/qaiyo"}],"wp:attachment":[{"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=350059"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=350059"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=350059"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=350059"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=350059"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/sl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=350059"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}