Release Notes
Changelog
Features, improvements, and fixes shipped across the SafariSync platform. Subscribe to the RSS feed to follow along.
September 2026
- Newvv1.11.0
Cost a safari before you quote it, and send a package that has no dates
**There is a new Costing sheet under Tours & Itineraries.** You build a safari up from what it actually costs you — park and concession fees, accommodation, the vehicle, the guide, permits — and it divides the shared costs across the group for you, so the vehicle and the guide are spread over the travellers rather than charged per head by hand. It tells you your margin before you send the quote, and it names what is missing instead of quietly costing it at zero. **The platform now knows what each country charges.** Park fees, concession fees and permits are modelled per country, including resident, citizen and non-resident rates, so a Tanzanian resident is no longer priced as a foreign visitor. The figures are a starting structure — check them against your own supplier rates before you rely on them. **Costs in another currency are converted, or refused.** If you enter a supplier cost in a currency your quote is not in, it is converted at the rate you have set and the rate is locked onto the quote, so a quote you sent last month still adds up the same today. Where no rate exists the system says so rather than mixing currencies and pretending the total is right. **A generic package no longer asks for travel dates.** When you switch a client itinerary to "Generic package — not a specific client", it now asks how many days the package runs instead of a start and end date. A reusable package has a length, not a departure. Before this, you had to invent a departure date to get past the form, and that invented date was then printed on the client's copy, the share card and the PDF as though it had been agreed. Those now read Day 1 to Day 7 and show the length instead. **The day count in the title now follows the real trip.** Typing a number into "Days" before you had picked your dates used to lock it there — set a seven and then pick dates ten days apart, and the itinerary went out titled "7-Day" over a ten-day plan. The real length now wins, and the field tells you where its number is coming from. The nights box also fills in whichever date you choose second, not only the end date. **Three quoting problems worth checking your own records for.** A saved quote never recorded what it cost you, only what you charged, so its margin sat blank until the quote was repriced — new quotes record both. A quote turned into an invoice recalculated its tax from a settings table nothing writes to, so a quote raised at 18% VAT could invoice at 0%: worth checking any invoice you raised from a quote, including ones already sent. And a tax rule you scoped to one country was applied everywhere, so if you run trips in both Tanzania and Kenya, both VAT rates could land on the same invoice. **Nothing about your existing itineraries has changed.** Every dated itinerary keeps its dates and reads exactly as it did; only a package you mark as generic is stored without them.
costingquotesitinerariespark feescurrency - Fixedvv1.10.2
A booking you confirmed can no longer be cancelled by its own hold
**If a booking was on a provisional hold and you confirmed it with the "Mark as CONFIRMED" button at the top of the booking, the hold stayed running underneath.** When that hold later ran out, the booking could be marked expired — or, if your organisation has automatic cancellation on expiry switched on, cancelled outright, with the room released and a cancellation email sent to the guest. You had confirmed it; the system had not been told to stop counting. The "Confirm Booking" button inside the amber hold banner always did this correctly. Both buttons now do. A booking that is confirmed, checked in, checked out or completed is also no longer eligible to be expired at all, so nothing already in your book can be undone this way. **Any confirmed booking that was showing an active or expired hold has been repaired for you.** We could not leave that to you to fix: on those bookings the "Confirm Booking" button could not work either, because the system refuses to confirm a booking whose hold has already lapsed. This release clears the stale hold on every affected booking directly, so the red "Hold Expired" marker disappears from stays that were confirmed all along. The booking, its dates and its money are untouched. **Cancelling from the booking page now records the refund you owe.** Cancelling a booking with payments against it is supposed to leave a "REFUND REQUIRED" note with the amount, and to tell the guest a refund is coming. That happened when a booking was cancelled from some screens but not when it was cancelled from the booking page itself — even though the confirmation box there tells you payments "will need to be manually refunded". Both routes now leave the same record. **Saving guest details works on bookings with no email address.** On a booking that arrived without a guest email — common on partner and phone-only bookings — pressing Save Changes did nothing at all: no error, no warning, no save. The screen now saves normally, or tells you what is missing. Where there is no email on file, the booking says so plainly instead of showing an empty contact line, and Message Guest is disabled with an explanation rather than opening a conversation that could never reach anyone. **The property map no longer covers the top of the page.** On booking details the map could paint itself over the header and breadcrumbs once it finished loading. Also in this release: the message history on a partner booking at your own property is now readable, instead of appearing empty; a booking that has already been invoiced will no longer let you add or remove an extra behind the invoice's back; you can mark a guest as a no-show from the booking page, and a no-show booking now reads as one; and pressing resend on a confirmation email now tells you if the send failed instead of always reporting success. **Nothing about how you take or price a booking has changed.**
bookingsprovisional holdscancellationsrefunds - Fixedvv1.10.1
Your operator email no longer hits a dead end on the traveller sign-in page
**If you ever pressed "Continue with Google" on safarisync.com using your operator email, you were told "Sign-in was denied. Please try again."** Trying again could never have worked. Operator accounts and traveller accounts are deliberately kept apart, so one email address is not allowed to become both. That rule is correct and has not changed. What was wrong is that the screen never said so, and never pointed you anywhere — it read like a temporary glitch when it was in fact a permanent answer. That screen now tells you the address has an operator account and sends you to app.safarisync.com, where your dashboard actually is. **Nothing about how you sign in to your dashboard has changed.** Your email and password, your two-factor code, and your team's access all work exactly as before. The rest of this release sits on the traveller side of the site and is not visible yet. Traveller sign-in was rebuilt so it can offer more than one provider, but a provider only ever appears once its credentials are in place — so the traveller sign-in page today shows exactly what it showed yesterday.
sign-inaccountserror messages - Newvv1.10.0
Property owners can now pay for a plan, and a lost payment confirmation no longer strands you
If you run properties rather than tours, choosing a paid plan used to end at a message telling you direct payment was required, with nothing to click. That was not an oversight in the wording — there genuinely was no way to pay. Tour operators pay from a wallet they top up; a property owner has no wallet, because you owe a commission on confirmed bookings rather than a balance per lead. So the one thing the screen asked you to do could not be done. **You can now pay for your plan on Settings -> Subscription.** Choose the plan and billing cycle, and you are taken to PesaPal to pay by card or mobile money. When the payment confirms, the plan activates and any past-due state on the account is cleared. If your account is showing Payment Past Due, that banner now takes you to payment instead of to a wallet you do not have. **If a payment confirmation goes missing, we now find it.** The gateway tells us the moment a payment succeeds, and that message can be lost — a brief outage on our side, a dropped request. Until now a lost message meant a subscription payment that never landed: you would have been charged, left on your old plan, with leads and bookings still paused, and nothing in the system would ever have corrected it. Every unconfirmed payment is now re-checked directly against the gateway every hour, and the plan is activated if the money did in fact arrive. Wallet top-ups, design template purchases and module purchases are re-checked on the same schedule, which previously ran once a day. A checkout you start and abandon is closed after seven days instead of being retried indefinitely. Nothing about how tour operators pay has changed, and no existing plan, wallet balance or billing date was altered by this release.
subscriptionbillingpaymentsproperty owners - Securityvv1.9.1
Team permissions now mean what they say, and two quiet pricing errors are fixed
Three fixes, all of which were wrong quietly rather than loudly. **We would ask you to look at the first one.** **Owning a module was granting its permissions to everyone in your team.** SafariSync separates two questions: does your business have a feature, and may this particular person use it. The second question was not being asked. If your organisation had a module, every member of your team effectively held every permission that module carries — regardless of what you had set in Settings → Team. For most modules that meant little. For Partnership & Channels, which is free and which almost every operator has, it meant anyone on your team could mark a partner settlement as paid, raise or counter a dispute, and upload payment proof. Worse, you could not take it away: the access never came from Settings → Team, so nothing you changed there had any effect on it. That is fixed. A module now only decides whether your business has the feature; who may act is Settings → Team alone, as it always should have been. **Nobody lost access in this release.** Before the change took effect we wrote what each person already had onto their team record, so today's access is unchanged. The difference is that it is now listed in Settings → Team, where you can see it and change it. **Please take a moment to review your team's permissions** — you may find people holding things you never intended to give them, and you can now remove them. **Quotes will no longer add two currencies together.** If a supplier rate was stored in one currency and your quote was in another, the total was simply added up — a lodge rate in dollars plus a transfer in shillings produced a figure that was not money in any currency, and it went onto the quote, the client's copy, and the invoice. Quotes now stop and tell you which line is in which currency instead of showing you a number we cannot stand behind. If you price in more than one currency today, you will see this — set the quote's currency to match, or enter that line in the quote's currency. We would rather interrupt you than let a client see a wrong price. Automatic conversion is deliberately not part of this: doing it properly needs a rate, a rate date and a decision about who absorbs the difference, and we are not going to guess those inside a total. **Park fees now use the resident and citizen rates you entered.** You have long been able to record non-resident, EAC resident and citizen rates against each park. The calculation only ever read the non-resident ones, so every East African guest was quoted the tourist rate — often several times what they actually pay. There is now a residency selector beside Auto-Calculate on both the new-quote and quote-detail screens. Pick Non-resident, EAC resident or Citizen and the correct rates are used. If you have not entered a rate for that band, the quote falls back to the non-resident rate and says so on the line, so you can see it rather than discovering it at the gate. A rate you have deliberately set to zero is treated as a real rate — some parks admit citizens free. Vehicle entry fees are unchanged: those are charged on the vehicle, not on who is sitting in it.
permissionsteamquotespark feespricing - Newvv1.9.0
WhatsApp in your inbox, a sales pipeline, and documents in your client's language
Three things landed together this release. **WhatsApp now works, and it lives in your inbox.** Guest messages arrive in the same list as your email, and you reply from the same place. Photos, documents and voice notes come through. Threads can be assigned to a colleague, marked done, and linked to a lead or a booking like any other conversation. You connect your own WhatsApp Business number under **WhatsApp setup**. The number, the access token and the business verification belong to your Meta account, not to ours — so nobody can send as you, and you keep the number if you ever leave. The setup screen hands you the two values to paste into Meta, then tells you plainly whether messages are actually arriving rather than just claiming to be connected. One WhatsApp rule worth knowing, because we show it rather than hide it: WhatsApp only allows a free-form reply within 24 hours of the guest's last message. Once that window closes, the reply box is replaced by an explanation — instead of letting you write a careful answer that would silently fail to send. **Your leads now have a pipeline.** A new **Pipeline** tab on the Leads page gives you a board with stages you name yourself — New, Qualifying, Quoted, Negotiating, or whatever matches how you actually sell. Drag a lead between them, give it a next action with a date, and see at a glance what has gone past due. You can also mark a lead lost with a reason, which was never possible before for a lead you had already accepted; those enquiries simply stayed open forever. Two columns fill themselves and cannot be dragged into. A lead reaches **Won** when it genuinely becomes a booking, and **Lost** when it is declined, expires, or you mark it lost. The board reports what happened — it cannot be arranged to show a deal you have not closed. **Proposals, quotes, vouchers and itinerary PDFs can be read in your client's language.** Seventeen languages besides English — German, French, Italian, Spanish, Dutch, Portuguese, Polish, Swedish, Danish, Russian, Chinese, Japanese, Korean, Arabic, Hebrew, Turkish and Swahili — chosen on the document itself. Your client picks it; you write once. Your own words are translated. Your prices are not. Totals, deposits, line items, dates, quote numbers, voucher codes and QR codes print exactly as you entered them, in the currency you quoted, in every language. Where a translation would have changed a figure, it is discarded and your original wording is shown instead — a document a guest may pay against should never quietly restate a number. Nothing here changes on its own. WhatsApp does nothing until you connect a number, the pipeline is a new tab on a page you already use, and every document still opens in English by default.
whatsappinboxleadspipelineproposals - Improvedvv1.8.1
Your operator and lodge listings are now visible to search engines
Three fixes that change how much of SafariSync search engines and AI assistants can actually see. **The public operator directory's country filter was returning almost nothing.** Organisation country was stored inconsistently — some records held a full country name ("Kenya"), others an ISO code ("KE") — while every filter matched the text exactly. Filtering the directory by Kenya returned 0 of 3 Kenyan operators; Tanzania returned 1 of 6. Country matching now understands both forms, and new records are normalised as they are saved. If your profile was missing from a country filter, it is there now. **The operator and property-owner directories linked to none of their own listings.** Both pages fetched their list in the browser, so the HTML a crawler receives contained no link to any profile at all — invisible to anything that does not run JavaScript, which includes the AI assistants our robots.txt explicitly invites. Both directories now render their first page on the server. **Destination lodge pages can now be indexed.** The /lodges/{destination} pages already listed real, verified properties, but were marked noindex because they carried only a one-line description — below the content threshold that decides whether a page is worth indexing at all. Eight pages now carry full editorial and have entered the sitemap: Serengeti, Ngorongoro Crater, Tarangire, Central Serengeti, Arusha National Park and Kilimanjaro, plus the Tanzania and Kenya tour-operator hubs. Also in this release — the lodge pages were rebuilt with a proper hero, a real breadcrumb trail, sortable listings, guest capacity and operator attribution on each card, and structured data describing the listing itself. Duplicate destination records for Ngorongoro Crater now resolve to a single canonical URL. The site name no longer appears twice in the page title on 14 pages. We also removed marketing claims the platform could not support: inventory counts and star ratings that were not backed by real data.
seodirectoryoperatorslistings
August 2026
- Newvv1.8.0
Concession fees: configurable, automated, and now fully wired in
Concession fees (park, conservation, and authority fees) can now be configured per property and are automatically calculated and applied to bookings. - **Property setup** — set whether a property charges a concession fee, who's responsible for it (property, tour operator, agent, or guest), and how it's calculated (per adult/child/night, per stay, flat amount, or a percentage of the accommodation rate). Rates support child age bands and effective-dated versions, so past bookings always keep the rate that applied at the time. - **Shown as its own line item** — a concession fee is always broken out separately from the accommodation rate, clearly marked as included or excluded, wherever a rate is shown — quotes, previews, confirmations, and emails. - **Works across every booking channel** — staff-created bookings, agent bookings, API/integration bookings, and guest self-service bookings all price and charge concession fees the same way. - **Automated reminders** — if a concession fee is still unpaid as check-in approaches, an escalating reminder schedule now nudges the responsible party automatically. - **Contract-specific terms** — property owners can negotiate different concession terms with individual tour operator partnerships (who pays, and how it's handled) that override the property's default. - **Manual corrections** — staff can now correct the amount or responsible party on a specific booking's concession fee (with a required reason), fully logged for audit purposes.
concessionfeesbookingspartnerships - Fixedvv1.7.0
Fixed near-invisible text across 14 Admin pages
Several Admin pages (Tenant View, API Keys, Promotions, Scheduled Tasks, Newsletter, SLA Monitor, and others) wrapped content in a dark card but used text colors meant for the light theme - stat numbers, table cells, and form input text were effectively invisible. Fixed 14 pages after verifying each one live; several similar-looking usages elsewhere (active tab states, badges, buttons) were already correct and left untouched.
adminui - Improvedvv1.6.2
Changelog now shows full release notes, not a 2-line preview
Admin > Changelog entries render their full content inline instead of being clamped to two lines, and the top-bar version badge links straight there.
admin - Improvedvv1.6.1
Admin top bar shows the deployed version
The Admin top bar now shows which version is currently deployed (e.g. "v1.6.1 · Aug 2026"), so it's obvious at a glance whether you're looking at the latest release. Click it to see the full changelog.
admindeployment - Newvv1.6.0
Booking Operations enabled platform-wide
Both Booking Operations feature flags introduced in v1.5.0 are now live for every organization: - **booking-operations** (read) — dashboards, per-booking Operations/Readiness/Timeline tabs, and the cross-booking Operations Board. - **booking-operations-mutations** (write) — item lifecycle, supplier availability requests (real email), cost confirmation, readiness overrides. Verifying this rollout surfaced and fixed a real gap: creating a `BookingOperation` record blocks hard-deleting its parent booking or organization. No production code path does that (bookings are soft-deleted; organizations are never hard-deleted), but a few test helpers did — fixed their cleanup order.
booking-operations - Newvv1.5.0
Booking Operations, resource planning, and a month of catch-up work
Catch-up release covering ~1 month of work merged to `main` without a version tag. **Major features:** - Booking Operations and Readiness subsystem — supplier availability, service confirmation, immutable confirmed costs, readiness blockers, and booking history. Six new tables, tenant-safe API, a new Operations Board. Shipped behind two feature flags, disabled by default. - Vehicle/driver/guide resource-planning system, plus property operations safety fixes and server-side booking pricing integrity. - Email Inbox (shared org inbox via SES inbound). - TO<->PO peer-to-peer partner network (offers/RFQs, symmetric invites). - Support-access / privileged-pages security hardening. - Luxe suite: tour, client itinerary, and proposal redesign; property detail + fact sheet luxury redesign. - Organization mini-site. - SEO: destination/property schema consolidation, sitemap/guides canonicalization, llms.txt, www->apex redirect. - Hetzner + Admin Deployment Center runbook. **Fixed while cutting this release:** a dependency security advisory (nanoid), a migration that crashed the CI test suite on SQLite, and a CI step-ordering bug that broke any test rendering a real page.
booking-operationsvehiclesseodeployment