Docs
Changelog
Release history and platform updates for Seedly CRM.
Last updated
A record of major updates, new features, and improvements to Seedly CRM. The most recent changes appear first.
v5.9.6 (October 2026) - Engagement rules are exact everywhere, plus email and text fixes#
Some rules change the moment you deploy, and there is one command to run after you update.
Before you update. Smart lists with engagement rules, "Submitted Form equals" a chosen form, recurring segment workflows with Pipeline Stage or engagement rules, and power dialer queues built from a saved filter used to match everyone or no one. As soon as the new code is live they match the right people, so the people they reach can change a lot. Look at every recurring segment workflow, smart list and workflow Condition or If/Else step that uses Opened Email, Clicked Link, Submitted Form, Booked Appointment or Last Contacted, and pause a workflow first if you are not sure: a recurring segment workflow enrolls everyone who matches on its next run.
Action required after you update. After
npx convex deployhas finished, preview withnpx convex run --prod contactEngagement:backfillContactEngagement, then apply it withnpx convex run --prod contactEngagement:backfillContactEngagement '{"apply":true}'. It keeps working in the background; it is done whennpx convex run --prod contactEngagement:backfillStatusshows"status": "done". It fills in the engagement summary for the contacts you already have and never changes any other data. If you skip it, nothing breaks, but contacts it has not reached are checked the old, slower way with the old limits.
Changed#
- Engagement rules are answered from a summary on each contact, so segments, smart lists, workflows, the power dialer and the contacts table all give the same exact answer, with no more "about N" for these rules.
- Email Do Not Disturb stops marketing email only. Transactional email, such as review requests and form auto-responders, now reaches the contact.
- Campaigns on a Transactional list send as transactional, with no unsubscribe link, as the list's setting says.
- Filter by Tags means any of the tags. Check any scheduled campaign with two or more filter tags before it goes out.
Fixed#
- Smart lists, "Submitted Form equals" and power dialer queues now pick the right people, and booking form answers count as Submitted Form.
- Recurring segment workflows run for exactly the contacts the segment page shows.
- The enroll-in-campaign workflow step follows the campaign's filter tags.
- HIPAA mode blocks every send to Google Analytics 4, including the test event and webhooks to Google Analytics addresses.
- System texts send from the account's own number and wait for 9 AM instead of being dropped in quiet hours. CANCEL, STOPALL, OPT OUT and REVOKE now stop all texts like STOP.
v5.9.5 (October 2026) - Ad tracking matches the agency setup#
No commands to run: update the code, redeploy, and you are done.
Added#
- Hidden form fields can save a link value to a custom field. Use "Save to CRM" on a hidden field, label it with the link parameter and leave its Default empty.
- Google Ads conversions from another system's webhook. Put the click ID at the top level of an Inbound Webhook body, plus a
conversionDedupKeyper payment or request so a resent webhook counts once.
Changed#
- Form opportunities take their Source from the ad, for example "adwords" instead of "form". If you filter or score on Source "form", add your ad sources.
Fixed#
- Won sales from tracked calls now report to Google Ads and Meta. Opportunities opened by a workflow's Create Opportunity step keep the caller's ad click.
v5.9.4 (October 2026) - Call tracking fixes and real tag usage counts#
No commands to run: update the code, redeploy, and you are done.
Fixed#
- Call tracking works when only a tracking pool has an Original Number. With "Default phone number on website" empty, the script on your site did nothing, so no visitors were recorded. It now runs whenever an active pool has an Original Number, and the pool's "Get embed code" no longer hands you the legacy snippet.
- A default website number saved in an older format now gets swapped. A number saved like (512) 555-0000 was never found on your pages. It is now read as +1 and 10 digits, so those sites start swapping once you update, with nothing to re-save.
- Settings > Tags shows real usage counts. Counts were never kept up to date, so tags showed 0 and could be deleted with no warning. They now fill in when you open the page.
- Renaming, deleting or merging a tag now updates your deals too, without restarting a deal's stale timer.
v5.9.3 (October 2026) - Tags added by automation show up in every tag picker#
One command to run after you update.
Fixed#
- Tags added by automation now show up in every tag picker. A tag applied by the REST API, a workflow, a chatbot, an inbound webhook, a new Messenger or Instagram contact, an import or client onboarding was saved on the contact but missing from Settings > Tags, so you could not filter a campaign, contacts or a segment by it. New tags are added to the list as they are applied. Run
npx convex run --prod migrations/backfillTagRegistry:start '{"dryRun":false}'once after you update (preview first with'{"dryRun":true}') to add the ones already on your contacts.
v5.9.2 (October 2026) - Paid Ads ROAS credits calls to their campaign, and the map shows real streets again#
No commands to run: update the code, redeploy, and you are done.
Added#
- Phone calls from your ads now count toward their own campaign's ROAS. When a tracked call comes in, the campaign the caller arrived from is copied onto their contact, and a nightly job fills in the campaign for recent leads that have a Google click id but no campaign name.
- The headline ROAS leaves Google Local Services out of both the spend and the won value, and is labelled ROAS excl. LSA. Local Services keeps its own row.
Fixed#
- Analytics > Maps shows real streets again. The map now uses free OpenStreetMap tiles with no account or key.
- A campaign recorded as an unfilled placeholder such as
{campaignname}no longer counts as a campaign name, and campaign rows that differ only in capitalisation are added together.
v5.9.1 (October 2026) - Security update: the preference centre no longer reveals who your contacts are#
Security update. No commands to run: update the code, redeploy, and you are done.
Fixed#
- The email preference centre no longer reveals whether an address belongs to one of your contacts. Typing an address without the link from an email now shows nothing, for a contact and a stranger alike. The link in your emails works as before.
v5.9.0 (October 2026) - Security update: closes cross-client record access, plus Amazon SES and HIPAA mode#
Security update: install this update. This release closes a set of problems where one client, brand or agency could reach another's records, adds Amazon SES as a third email provider, and adds an optional HIPAA mode. Three changes you will notice: a contact who opted out of marketing email now gets transactional email only, workflow Send Email steps with no list now send as marketing (with an unsubscribe link, skipping contacts who opted out) unless every trigger in the workflow is something the contact did or is owed, and Gmail is personal to each user, so you send only from your own connected Gmail. On a tracking pool, the Whisper Message now plays to whoever answers the call instead of to the caller, so your callers no longer hear it. Sender settings now apply only to the agency, brand or client they belong to. Alongside that: a Google Local Services lead assistant, new record scope options on roles, a "Require 2FA" switch that works, voicemail that no longer asks for a second message, and missed calls on numbers nobody is set to ring now notify the account's owners and admins.
Action required after you update. Run the commands below after
npx convex deployhas finished, in this order. Some of them keep working in the background after the command returns; where a step says so, open Convex dashboard > Logs and wait for the line it names before you move on. The release notes inside your download explain what each one reports, whether it changes your data and what goes wrong if you skip it.1. Everyone. Run
npx convex run --prod migrations/backfillStorageOwners:start '{}'and wait until Convex dashboard > Logs shows[backfillStorageOwners] done. Then previewnpx convex run --prod migrations/backfillStorageOwners:finalizePendingDeletes '{"dryRun":true}'and apply it with'{"dryRun":false}'. If that returns acursorthat is notnull, run it again with that cursor, and repeat untilcursorisnull. It records who owns each uploaded file. If you skip it, reusing an upload older than 24 hours in a new place fails, and files that should have been deleted stay in storage.2. Everyone. Preview
npx convex run --prod migrations/pruneBaOrgMembersOutsideReach:prune '{"limit":500}'page by page, passing the returnedcontinueCursorascursoruntilisDoneis true. Then start again from the first page with"dryRun":falseadded, each time passing thecontinueCursorthat run returned, and finish with a full preview pass that showswouldRemove: 0on every page. It removes leftover sign-in records for people who no longer reach that brand or client, such as a team member you removed. If you skip it, those leftover rows stay; nothing else breaks.3. Everyone who sends email. Preview
npx convex run --prod emailSendScreen:backfillEmailMarketingOptOutandnpx convex run --prod workflowHelpers:backfillSendEmailMessageType, then apply each by running it again with'{"apply":true}'. Both keep going in the background, so before the next command wait for itsdoneline in Convex dashboard > Logs. They mark contacts who already opted out of marketing email and give existing Send Email steps a message type. If you skip them, people who used the old one-click unsubscribe before this update are not treated as opted out of marketing email.4. Only if anyone has connected Gmail. Run
npx convex run --prod conversations:backfillGmailMessageMailboxes '{}'. It records which mailbox each stored Gmail message came from. If you skip it, older Gmail messages show as private to everyone, including the person whose mailbox they came from.5. Only if you use Postmark. Run
npx convex run --prod _helpers:backfillPostmarkWebhookTokens. It keeps going in the background: wait until Convex dashboard > Logs shows a[postmark-tokens] backfill channelConfigsline and no new[postmark-tokens]lines follow it. Then previewnpx convex run --prod actions/postmarkProvisioning:repairPostmarkWebhooksand apply it with'{"apply":true}'. Then change the inbound webhook URL on every Postmark server you receive replies on to the form in SETUP Chapter 9, Step 3. Until you do, email replies through Postmark are refused. The repair changes your webhook settings in Postmark. If you skip these, Postmark webhooks signed with a saved token are refused and unsubscribes made in Postmark do not reach the CRM.6. Only if you use SendGrid. Preview
npx convex run --prod actions/sendgridProvisioning:repairSendGridEventWebhooks, then apply it with'{"apply":true}'. If you skip it, unsubscribes made through SendGrid's own links do not reach the CRM.7. Everyone with sending domains. Run
npx convex run --prod emailDomains:auditDuplicateDomainNamesInternal. It is read only and lists any domain name saved more than once, which you can then archive. If you skip it, replies sent to a domain saved more than once keep going to whichever verified copy is found first.
Security#
- One client, brand or agency can no longer reach another's records. Many paths let a client's user, a brand admin or another agency read or change records that were not theirs: email domains and sender settings; SMS, voice and social webhooks; users with several memberships acting with the wrong role; messaging and telephony; calendars, forms, documents and stored files; workflow steps and the REST API; agency-wide settings and Google connections; Stripe refunds and webhooks; and CRM records and pipelines. All are closed. Run command 2 above.
- Uploaded files are deleted or reused only by the client that owns them. Files uploaded before this update need their owner recorded once. Run command 1 above.
Added#
- Amazon SES as an email provider, alongside Postmark and SendGrid. Connect it with an IAM access key at the agency, brand or sub-account level; the CRM sets up sending, bounce and complaint tracking in your AWS account and can receive email replies. Each email can carry about 21.9 MB of files; a larger one is refused before it is sent, with a message that says so. Setup:
SETUP/reference/amazon-ses.mdand Chapter 9. - HIPAA mode (Settings > Compliance), off by default. When the agency owner turns it on: every member needs two-step sign-in, idle members are signed out, opening contacts, conversations, transcripts, forms and documents is recorded in the Audit Log, audit logs are kept longer, notifications that leave the app carry no patient details, and integrations that cannot sign a Business Associate Agreement (BAA) are blocked. It does not make your CRM HIPAA compliant. Meeting HIPAA's requirements is entirely your responsibility; read
SETUP/reference/hipaa.md. - Record scope options on roles: Own + Unassigned and Team + Unassigned for contacts, conversations, deals and calendars.
- Google Local Services lead assistant. A new tracking pool source, Google Local Services (LSA). Recorded calls on that pool are transcribed, AI pulls out the caller, the job, the location and whether it was booked, and the people you pick get one email per call saying what to do in the Google Ads lead inbox: mark it Booked with the job type, or rate the lead and give the reason. New callers on that pool are saved with the contact source Local Services Ads, and the Paid Ads tab shows a return on ad spend (ROAS) for your Local Services campaign. To set it up, go to Settings > Integrations > Configure Telephony, open the Tracking tab and switch on Enable Call Tracking if it is off, create a tracking pool with the source Google Local Services (LSA) and set its number as the business phone in your Local Services profile, then turn on Local Services lead assistant below your tracking pools and click Save. It needs call recording on that pool and AI set up the same way as for AI Call Grading; once recording is on, callers hear the recording disclosure. A pool's whisper and greeting only play when the number's inbound routing is Forward to number.
- Community emails can be sent and replied to inside the CRM inbox.
- An optional
SESSION_EXPIRES_IN_HOURSenv var to end sign-ins after a set time (SETUP/reference/env-vars.md).
Changed#
- Email opt-outs: a contact who opted out of marketing email gets transactional email only. An inbox reply still goes if they wrote to that conversation in the last 30 days. Each recipient (To, Cc, Bcc) is checked on its own. Run command 3 above.
- Workflow Send Email steps with no list used to always send as transactional. They now send as transactional only when every trigger in the workflow is something the contact did or is owed (an appointment, invoice, estimate, document, review, subscription, plan purchase, form, reply or missed call). Otherwise they send as marketing: they carry an unsubscribe link and skip contacts who opted out. You can set the type yourself on the step.
- Sender settings apply only where they belong. A From address saved for one client with a brand attached by mistake could be used for every client under that brand. Each sender setting is now used only for the agency, brand or client it belongs to. If a client now sends from a From address you did not expect, set the one you want in that client's (or its brand's) sender settings.
- Gmail is personal: you send only from your own connected Gmail. Teammates see that a Gmail message exists in a conversation, not its content. Run command 4 above.
- Tracking pool whisper and greeting (behaviour change for existing pools). On a number set to Forward to number, a pool's Whisper Message now plays to whoever answers the call, as the pool form always said; it used to play to the caller. The Greeting Message, which was saved but never played, now plays to the caller. If you have a whisper set on a pool, your callers no longer hear it; move any words meant for callers into the Greeting Message.
- Postmark webhooks are checked against the server token saved in the CRM, and unsubscribes made in Postmark reach the CRM. Run command 5 above.
- Sending rules save the moment you pick them, with a "Sending rule saved" confirmation.
- The "Require 2FA" switch now works, and a member who needs two-step sign-in is sent to set it up instead of being locked out.
- Record scope now applies everywhere a record can be reached (search, exports, the dialer, invoices, workflows), not only in lists.
- Re-inviting an email that already has an account no longer changes that account's password; the invite tells them to sign in with what they have.
Fixed#
- Voicemail no longer asks for a second message. A caller who paused while leaving a voicemail used to hear the greeting again; the recording now keeps going through up to 20 seconds of silence, then the call hangs up.
- A missed call on a number nobody is set to ring now notifies someone: the account's own owners and admins, falling back to the agency's admins when the account has none. It used to notify no one.
- Pipeline permission settings (No Access, View Only) now take effect.
- Server logs no longer print contact names, email addresses or phone numbers.
- Unsubscribes made through SendGrid's own links reach the CRM. Run command 6 above.
- The default email footer shows the business name with the address.
- Large file uploads retry when the connection drops, and the error says what happened.
- Calendar-only Google connections refresh correctly, and reconnecting Google clears an old sync error.
- Send Email steps added from the workflow template gallery no longer send a blank email.
v5.8.17 (September 2026) - Critical fixes: encrypted workflow credentials, texting consent, and pipeline rules that run#
Critical fixes: install this update. This release closes security and texting-consent problems and repairs features that were quietly not working. Workflow step credentials, webhook headers and Zapier hook URLs are now stored encrypted and never shown again, Google Calendar sync can no longer change an appointment in another sub-account, and preview deployments are really turned off. Contacts added from now on need a marketing "yes" before they get marketing texts, a contact marked "Opted out" stops getting booking texts, the email preference center works again, and "Unsubscribe from this campaign only" no longer unsubscribes people from everything. Six of the eight pipeline rule triggers now fire, If/Else on Pipeline Stage matches, the calendar shows the current month on accounts with more than 1,000 appointments, and a campaign where every send failed shows "Failed" instead of "Sent". Alongside that: pictures texted in to you show in the conversation, tables sort by column, conversations read as speech bubbles, and a long list of pipeline, calendar, campaign, workflow, task and form fixes.
Action required after you update. This release has critical fixes. Every critical item in the release notes inside your download starts with [Critical], and so does each command those fixes need. If you only want the critical fixes, ask Claude Code to install only the [Critical] items from this update. Run the commands below after
npx convex deployhas finished, in this order. The release notes inside your download explain what each one reports, whether it changes your data and what goes wrong if you skip it.1. Everyone whose workflows send texts, right after you deploy. Preview
npx convex run --prod workflowHelpers:backfillSendSmsMessageType, then apply it by running it again with'{"apply":true}'. It gives every Send SMS step with no List and no Message type a type from its workflow's trigger. If you skip it, reminder and review texts from those steps skip every new contact without marketing consent.2. [Critical] Everyone who sends marketing texts, right after you deploy. Run
npx convex run --prod smsHelpers:backfillMarketingSmsOptInCutoffonce. It records the moment the new marketing opt-in rule starts for your account. If you skip it, contacts added between the update and your first marketing text keep getting marketing texts without having said yes.3. [Critical] Everyone with a Slack, Webhook or Zapier workflow step. Preview
npx convex run --prod workflows:encryptLegacyNodeSecrets '{"dryRun":true}', then apply it withnpx convex run --prod workflows:encryptLegacyNodeSecrets '{}'. It encrypts the credentials saved before you updated. If you skip it, those credentials stay readable in plain text by anyone who can open the workflow's data, its version history or its old run logs.4. [Critical] Everyone who sends campaigns. Run
npx convex run --prod campaigns:backfillAllRecipientCountsonce. It counts the recipients of campaigns sent before you updated. If you skip it, those campaigns keep their old figures in the campaigns list until the daily cleanup counts them, a few at a time.5. Only if you receive social DMs. Run
npx convex run --prod late:backfillUnknownSocialContactNamesonce. It renames the social DM contacts called "Unknown" to something you can tell apart, such as "Instagram user @handle".6. Only if you have opened a form in the form builder. Preview
npx convex run --prod migrations/restoreFormSuccessCopy:restoreFormSuccessCopy, then apply it with'{"apply":true}'. It puts back your own success message on forms the builder had saved with its generic wording.7. Only if you receive picture texts (MMS). Preview
npx convex run --prod actions/mmsMediaClone:backfillMmsMedia '{"dryRun":true}', then apply it with'{"dryRun":false}'. It saves pictures that arrived before you updated, looking back 30 days by default.
Security#
- [Critical] Workflow step credentials are stored encrypted and never shown again. The Slack bot token and the Webhook bearer token, password and API key were saved as plain text inside the workflow, where anyone who could view it could read them. Webhook header values and the Zapier hook URL are now treated the same way, and the values in a webhook URL's query string are hidden when the workflow is viewed and in run logs. Changing the address a Webhook step sends to clears its saved credentials. Run command 3 above.
- [Critical] A Webhook step that sends credentials must have a fixed address. A merge field in the scheme or host, such as
https://{{contact.website}}/hook, is now refused when you save or publish, and a step saved before this update is refused when it runs. Merge fields in the path or query still work. - [Critical] Google Calendar sync stays inside its own sub-account. Pulling changes from Google could update or cancel an appointment in a different sub-account, or on a different calendar, when the same Google event appeared in both. Appointments imported from Google are now edited and cancelled in the CRM only.
- [Critical] Preview deployments are really turned off.
vercel.jsonsat at the top of the project, where Vercel does not read it, so every branch you pushed built a preview connected to your live database. It has moved toapps/web/vercel.json, so onlymainbuilds. Previews already built are not removed; you can delete them in Vercel under Deployments.
Texting consent#
- [Critical] Marketing texts need a marketing opt-in from new contacts. A contact added after you update needs a marketing "yes", from the marketing box on a form or from you choosing Opted In in the new "SMS mktg" setting on the contact. Contacts you already had keep the old rule. Run command 2 above.
- [Critical] Contacts marked "Opted out" stop getting booking texts, and marking SMS consent by hand on the contact card saves again.
- [Critical] The email preference center works again. It could never load or save on a live install.
- [Critical] Form consent boxes apply to returning contacts. A tick only counts when the phone entered matches the number on file, and a contact who replied STOP keeps their opt-out.
- [Critical] "Unsubscribe from this campaign" only unsubscribes from that campaign's List, instead of every marketing list.
Fixed#
- [Critical] Pipeline automation rules on more events now run. Rules on Estimate Accepted, Invoice Paid, Invoice Sent, Appointment Completed, Form Submitted and Tag Added could be saved but never ran.
- [Critical] Workflow If/Else checks on deal and activity fields work. Pipeline Stage never matched, and "Opened Email: no" matched everyone.
- [Critical] Every stage move counts as a stage change, whether a workflow, a pipeline rule or the API made it, and opportunities created by a workflow start filtered "Opportunity Created" workflows.
- [Critical] Bulk tagging only starts workflows for real changes, and a large bulk tag edit no longer fails completely.
- [Critical] Pipeline rules and workflows cannot loop forever. Rules only move open opportunities.
- [Critical] The calendar shows this month on busy accounts. Past 1,000 appointments, month, week and day views showed nothing for the current period.
- [Critical] Calendar notification variables fill in, and booking texts and emails show names as typed ("O'Brien", not
O'Brien). - [Critical] Campaigns no longer get stuck when a recipient is skipped.
- [Critical] A campaign where every recipient failed shows "Failed", and one where some failed shows "Sent · N failed".
- [Critical] The campaigns list and the campaign drawer show the same numbers. Each campaign keeps exact recipient counts. Run command 4 above.
- [Critical] Failed campaign texts reported by Twilio are recorded instead of being thrown away and retried.
- [Critical] Replying to social DMs works on busy installs, a reply to an archived conversation brings it back on every inbound channel, and an emoji can no longer make a message or form fail to save.
- Pictures texted in to you show in the conversation. The CRM now saves each one into its own storage. Run command 7 above for older pictures.
- The form builder no longer replaces your success message with generic wording. Run command 6 above for forms already saved that way.
- Social DM contacts are no longer all called "Unknown". Run command 5 above for existing ones.
- Pipelines and opportunities. The Automation tab no longer shows four "Built-in" switches that did nothing. Deleted deals leave the board straight away, automations leave opportunities in the trash alone, wins from workflows and pipeline rules do everything a win on the board does, Manage Pipelines shows real counts, and Opportunity Stale works in pipeline rules and fires once per stale spell.
- Calendar and booking. Editing a recurring series updates every session properly, deleting a contact, calendar or appointment type clears its Google Calendar events, booking emails show your own wording, calendar texts go through your A2P 10DLC registration, and only the reminders you set are sent.
- Workflows. "Restrict to business hours" workflows no longer fail before their first step, and your Business Hours now drive them and after-hours auto-replies. A workflow that has been failing this way starts sending again from its next trigger. Sender Defaults are used, the Internal Notification "Redirect Page" works, a form that creates a contact fires "Contact Created", and a CloseBot pause shows a banner with Resume AI.
- Campaigns. The Failed, Pending and Skipped tabs show the right people, a duplicated campaign no longer claims "All contacts", and recipient details are really cleared 180 days after a campaign finishes, with the totals kept.
- Social. Comments on a post work, retrying a partly published post no longer posts it twice, a post waiting for approval cannot be published around it, and deleting a live post says it stays up on the platforms.
- Tasks. The filter bar works on "All Projects", the Tag filter has tags to pick, the task email template dropdowns save and each task email sends the template you chose, and the board follows your Task Cards settings.
- Dashboard and reporting. The dashboard no longer crashes on busy accounts and opens for roles that cannot see Settings, each section loads on its own, and pages with a linked contact open for roles without Contacts access.
- Setup.
npx pnpm provisionno longer fails on your first deploy. If it did, update and re-runnpx pnpm provision --from=deploy. - Looks. Styling that never loaded now does, so icons in buttons are 16 pixels and divider lines appear. Phone numbers look the same everywhere, and warning badges are readable on the light theme.
Added#
- Send SMS steps have a Message type: Marketing or Transactional. Run command 1 above.
- More ways to record marketing text consent: an optional "SMS Marketing Consent" column in CSV import, an optional marketing checkbox on booking pages, and a new
GET /api/v1/contacts/{id}/messaging-statusendpoint. - Tables sort both ways by clicking a column header, and the Reviews table sorts on every column.
- Paid Ads shows your return on ad spend (ROAS), in total and per campaign, from the deals you won.
- More actions and post stats in the social post drawer: Publish, Go live now, Unschedule, View and Unpublish.
- A due-date range filter on Tasks, a "Sits on a dark background" switch for forms, and a "Send confirmation" checkbox on new appointments.
- Rename a pipeline and set the default from Manage Pipelines.
- A GitHub typecheck check (
.github/workflows/buyer-typecheck.yml) ships in your download, and rejected API keys now leave a record in the Audit Log.
Changed#
- A branch with no next step now ends the run. This changes how some live workflows behave: If/Else, Find Contact, Find Opportunity and Wait for Condition used to fall through into the other branch. Check any workflow where a branch of these steps is left unconnected.
- The workflow "Remove Opportunity" steps move opportunities to the trash instead of deleting them permanently.
- Actions that are hard to undo ask you to confirm first, and so does publishing a social post.
- Conversation messages read as speech bubbles, with the sender's avatar.
- Lists opens as a tab inside Contacts.
- On Workflows, select-all selects every loaded workflow, not just the first 20, so a bulk Delete after select-all deletes all of them.
v5.8.16 (September 2026) - Usage billed at its real price#
A billing release, and the most important one if you rebill usage to your clients. Every email, text, call minute, recording and AI call was being rounded up to a whole cent twice, once on the provider cost and again after your markup, so charges came out as much as 27 times the real price. Charges are now exact, the wallet takes whole cents and carries the fraction until it adds up to one, and your rate card matches what the wallet takes. Alongside that, three phone-rental faults are fixed and the rate card quotes the provider and number that actually send.
No action required after you update, but read this before you deploy. No migrations or backfills: update the code and redeploy. Two changes alter what your clients are charged, and one of them can start a charge that was not happening before. A client with a phone number but no plan will start paying monthly rent for it, at your cost. Check Sub-Accounts for clients with a number and no plan, and set them up the way you want them before you update.
Fixed#
- Usage was billed at up to 27 times its real price. Every email, text, call minute, recording and AI call was rounded up to a whole cent, twice. A SendGrid email that should cost $0.00075 cost $0.02, and a text cost $0.02 instead of $0.0104. Charges are now exact. If you rebill usage, your clients have been overcharged for as long as you have been doing it. Their wallet history shows every charge, so you can work out what each one is owed and credit it from the wallet page.
- The wallet carries fractions of a cent. It takes whole cents only and carries the remainder until it adds up to one, so nobody is charged for a cent they have not used and nothing is lost. Your clients will see usage lines that move their balance by nothing, followed by one that moves it a cent; the real cost of each line is shown beside it and in the CSV export.
- A phone number bought between the 1st of the month and your billing day is no longer charged twice, and a rental that could not be taken because the wallet was empty is retried instead of being written off for the month.
- A client with a phone number but no plan now pays monthly rent for it. They were charged when they bought the number and never again, while you kept paying for it every month.
- The rate card quotes the provider and the number that actually send. It quoted the Postmark price to everyone, even clients sending through SendGrid, and named the wrong phone number on a client with several.
- A client using their own SendGrid, Postmark, Twilio or Telnyx key is no longer billed by you for those sends. Their provider invoices them directly, so there was never a cost for you to pass on.
- A campaign set to an email provider the CRM does not recognise now fails loudly instead of sending through SendGrid and billing at a fallback rate about 16 times the real one.
v5.8.15 (September 2026) - Login screens never put a password in the address bar#
A security release. The login screens now always tell the browser to send what was typed in the body of the request, so pressing Enter before a login page has finished loading can no longer put an email address and password in the address bar.
No action required after you update. No migrations or backfills. Update the code, run the usual
npx pnpm install, commit thepnpm-lock.yamlit changes, and redeploy.
Security#
- Your login screens can no longer put a password in the address bar. The sign-in, password reset, two-factor and recovery-code screens come from the
@daveyplate/better-auth-uilibrary. On version 3.3.15 their forms did not say how to send what was typed, so pressing Enter before the page finished loading sent the fields in the address, where they stay in browser history and your hosting provider's request logs. Version 3.4.0 sends every form's fields in the body of the request instead. If the update helper kept your own copy ofapps/web/package.json, change the@daveyplate/better-auth-uiline to"^3.4.0"and runnpx pnpm install.
v5.8.14 (September 2026) - Automated texts join the contact's one conversation#
A conversations and correctness release. Automated texts now land in the contact's one conversation instead of opening a second thread beside it, and the conversation pane gains an "All channels" view that shows every message with a contact in one feed. The AI Auto-Reply bot books dispatch jobs only when you switch that on, and deleting the person who set it up no longer takes it down. A Google Business Profile location now belongs to one account at a time everywhere, not only in the review sync. Alongside that: the included Re-Engagement template runs once a day instead of every hour, adding a group of contacts to a workflow really runs it, a voicemail is recorded as a missed call again, and Retry on a failed review reply really re-sends it.
Action required after you update, depending on your install. Each command below applies only to some installs. The release notes inside your download list each one with what it reports and what to do next.
Only if the Re-Engagement template is in your gallery. Preview
npx convex run --prod migrations/fixReengagementHourlyCadence:fixReengagementHourlyCadence '{"dryRun":true}', then apply it by running it again with'{"dryRun":false}'. It puts the template and every untouched workflow built from it back to once a day, and lists any workflow it left alone because somebody had already changed its trigger. If you skip it, those workflows keep sending their win-back email and text every hour.Only if you have the Dispatch add-on and connected AI Auto-Reply with one-click setup. Run
npx convex run --prod closebot:backfillDispatchJobsGrantFromKeysright after you deploy. It sets each bot's new "Let the bot book jobs" switch to match what its key can already do, and never changes what a key can do. If you skip it, the switch reads off for bots that can still create jobs.Only if you are updating from 5.8.11, 5.8.12 or 5.8.13. Preview
npx convex run --prod migrations/mergePhoneThreads:mergePhoneThreads '{"dryRun":true}', then apply it with'{"dryRun":false}'. It joins up the extra conversations automated texts opened since 5.8.11. If you skip it, nothing is lost, but those contacts keep more than one conversation in your inbox.
Added#
- An "All channels" view in the conversation pane. A "This channel" / "All channels" switch on the thread lists every message with that contact, on every channel, in time order, each one labelled with the medium it arrived on. It opens on the single channel as before, and replying is unchanged.
- A "Let the bot book jobs" switch for AI Auto-Reply, under Automation, Livechat, AI Auto-Reply, on a CRM with the Dispatch add-on. Job creation is off unless you turn it on, and turning it off takes the access away immediately.
- A Failed Sends list under Settings, Integrations, Email: the last 14 days of automatic emails your provider did not accept, split into ones that definitely did not arrive and ones that may have arrived.
- Google Ads manager (MCC) logins find the client accounts underneath them. The Paid Ads picker looks inside a manager account and offers only the client accounts that return a real report.
Changed#
- A Google Business Profile location belongs to one account at a time, everywhere. Local posts, review replies, "leave a review" links and SEO insights now follow the same ownership rule the review sync already used. Connecting a location another account holds is refused at the point of saving, and a location stays with its account even while that account's Google access is broken.
- The AI Auto-Reply bot's API key passes to the agency owner when the person who set it up is removed, and the API Keys page labels that key and explains why it cannot be revoked there.
Fixed#
- Automated texts land in the contact's one conversation. Workflow texts, the missed-call auto-reply, bulk SMS, review requests, SMS campaigns and add-on job notifications no longer open a second thread beside a contact's calls. Email campaigns, email, social DM, live chat and form threads keep their own threads, as before.
- The included Re-Engagement template runs once a day, not every hour.
- Adding a group of contacts to a workflow at once really runs it, and respects the workflow's re-entry setting.
- A call that went to voicemail is recorded as a missed call again, so missed-call automations fire and call reporting, engagement scores and ad conversions stop counting it as answered.
- A social post no longer goes to the wrong account when both halves of a split platform are connected.
- A Condition step with "Dynamic Value" switched on compares against the value it works out at run time, including Conditions you have already saved.
- Retry on a failed review reply really re-sends it, a failed reply can be answered again, and a reply deleted on Google stops counting as a reply.
- A booking email that did not send no longer shows in the conversation as sent.
- Admin Analytics names the list it cut short, and keeps refreshing for the people who actually open it.
- The environment variable reference lists every variable the CRM reads, and the
mergePhoneThreadsusage note now shows the real-run command.
v5.8.13 (September 2026) - Workflows that start from several triggers, and edits that wait until you publish#
A workflows and performance release. A workflow can now start from more than one trigger, up to 20, with each entry point able to take its own path, and edits to a live workflow go live only when you publish them, so a live automation no longer changes under you while you are still editing it. Alongside that, a large performance and correctness pass: starting a workflow from an event does far less database work, each person now gets one daily task summary in place of an alert for every overdue and due task, Admin Analytics is built in the background and opens on saved numbers instead of counting everything while you wait, public form views no longer write to the form itself, and the Google Business Profile sync reads every page of reviews, stops overwriting another sub-account's reviews and stops reporting success when it can save nothing.
Action required after you update: two commands, both safe to preview first, and the second one has to run before anyone edits a workflow. If you connect Google Business Profile, there are two more to run straight after you deploy. The release notes inside your download list each one with what it reports and what to do next.
Workflows copied from a snapshot. This only matters if you have ever made a sub-account from a snapshot, but the preview writes nothing and reports
"sharedGroups": 0when there is nothing to fix, so run it if you are not sure. Preview it withnpx convex run --prod migrations/rotateSharedWorkflowWebhookSlugs:rotateSharedWorkflowWebhookSlugs '{"dryRun":true}', then apply it by running it again with'{"dryRun":false}'. It gives each workflow that shared a webhook URL its own, and the report names the workflows whose sender you then update. If you skip it, a webhook URL that two or more live workflows share answers "not found" and starts nothing.Trigger cards on older workflows. Preview
npx convex run --prod migrations/reconcileTriggerNodeConfig:reconcileTriggerNodeConfig '{"dryRun":true}', then apply it with'{"dryRun":false}', before anyone edits a workflow. It copies the trigger and filters saved on the workflow record onto its trigger card, so the builder shows what actually runs. Open every workflow the report lists asmismatchand check its trigger before you next publish it. For a draft that has never been published, check its trigger card afterwards too: if you had removed its filters, the command puts them back. If you skip it, those workflows keep running as they do now, but their trigger cards keep showing no filters, or no trigger at all.Only if you connect Google Business Profile. Run
npx convex run --prod googleBusinessHelpers:backfillGbpLocationClaims, thennpx convex run --prod googleBusinessHelpers:listGbpLocationConflicts, and untick each location the second one lists in every sub-account except theownerit names. If you skip them, nothing stops working, but for a short window after you deploy, a location two sub-accounts are connected to can be claimed by whichever of them the sync reaches first.
Added#
- A workflow can start from more than one trigger, up to 20. Add one with the Add Trigger button on the canvas or from the Triggers tab. When an event matches more than one, the contact is still enrolled once, from the matching trigger that was added first. A second schedule trigger, a second Inbound Webhook, a "Run once" trigger next to any other, or more than 20 are not allowed. Test and Enroll ask which trigger to start from when there is more than one, and the run log shows which trigger started each run.
- Each entry point can take its own path. A Condition or an If/Else can check "Trigger that started this run", so each trigger sends contacts down its own branch.
- A Publish changes button on a live workflow with edits that are not live yet, so you can put your edits live without turning the workflow off and on.
- One daily task summary for each person, in place of an email and bell alert for every overdue task and every task due soon. It arrives each morning in the sub-account's own time zone, lists what is due in the next 24 hours and what is overdue, and replaces the Task Overdue and Task Due Soon rows in notification settings with one Daily Task Summary row. Where you had switched off both old rows for a channel, the summary starts off for that channel too.
- A Google Business Profile location can be connected to one sub-account at a time. The location picker greys out a location another sub-account already has and says which one, and a location you already share is marked with a warning.
Changed#
- Edits to a live workflow go live only when you publish them. A workflow that has been published keeps the version you last published until you publish again. Publishing a change that removes every filter from a live trigger asks you to confirm first. Test runs use the version on screen, and trigger cards no longer offer Pause, which never stopped a trigger from starting runs.
- Starting a workflow from an event does far less work. The contact is loaded only when something uses it, the duplicate-run check reads far less of the run history, and skipped runs are saved without a copy of the contact and the workflow's steps. Which workflows start, and which runs are skipped, is unchanged.
- Skipped workflow runs are cleared sooner. A busy workflow records a lot of them, so they are now removed automatically after a shorter window than other runs. Runs that completed, failed or were cancelled are kept as before, and there is nothing for you to run.
- Admin Analytics is built in the background and opens straight away. The page reads saved numbers that count every record, honours the whole date range you pick (a range that starts before the saved history is trimmed, and the page says so), and shows when the numbers were last built with a Refresh button to rebuild them. The Campaigns and Client Health panels are labelled as the lifetime totals they have always been.
- Each notification email counts once against your daily sending limit. Staff alerts now go out even when the sub-account has no card on file; mail to a contact still needs one.
- Form views are counted away from the form itself, so a visitor opening your form no longer disturbs anyone working in the CRM. Your existing view totals carry over, a visit counts once per browser tab, and completion rate stops at 100%.
- Workflows started by a form, a deal, an invoice, an appointment or a call see the contact's new engagement score and lifecycle stage, because each of those events now updates the contact and starts the workflow in one step.
- The Google review sync reads every page of reviews, not only the first, and writes a review only when something about it changed. Reviews that already exist when you connect a location are imported quietly, without starting review workflows or notifying your team.
Fixed#
- Workflows copied from a snapshot no longer share one webhook URL and signing secret. A copy now starts with neither, and a URL that more than one live workflow shares is refused.
- An unfinished condition can no longer go live, and conditions built in the builder can be published. Typing a field on a Condition now saves the operator shown next to it, and If/Else Add Branch adds a simple branch. Activate on the workflow list runs the same checks as the builder.
- "Run once" workflows run at the time you picked, read in the sub-account's time zone instead of UTC, and once for each time you set.
- A tag's details panel lists every workflow that uses the tag, a Recurring Segment workflow whose segment was deleted enrolls no one, a workflow on a schedule trigger only starts on its schedule, and an Inbound Webhook trigger shows its Endpoint URL as soon as the workflow saves.
- Task Reminder workflows run at the offset you set, and a notification no longer goes missing when a sub-account's time zone is one the CRM cannot read.
- The email switches in Task Settings take effect. Switching off Task Assigned, Mention, Submission Approved or Submission Rejected now stops that email.
- The form builder keeps your unsaved changes when a visitor opens the live form, a submission comes in or the form is renamed.
- The Response Rate on the Reputation page counts replies you wrote on Google, and a reply that could not be posted is marked as failed, with the reason, instead of "Posted to Google".
- A Google Business Profile connection reports trouble instead of a healthy sync. Signing in to Google again no longer stops the background refresh of a working connection, and a sync that could save nothing because the reviews belong to another sub-account now says so on the card.
- An answered call adds its engagement points to the contact once, and scoring and lifecycle updates leave deleted contacts alone.
- The call recording announcement box tells the truth about calls going out. On a call coming in, an empty box still plays a standard disclosure. On a call going out, the CRM plays exactly what you typed and nothing else, so an empty box records with no announcement, and on Telnyx a call going out never plays one. Nothing about how calls are recorded changed; if you rely on the announcement for consent on calls going out, type your disclosure into the box.
- A kill switch you set to
truenow works. The operator switches that turn a feature off accept1ortrue.
v5.8.12 (September 2026) - The Custom Domain card shows the records your hosting asks for#
The Custom Domain card now shows the DNS record your hosting actually recommends for your project, including every A record a root domain needs. When your hosting has to confirm a client's domain first, the card shows the extra record, checks it again while it is open and when you click Verify, and names any older record that is blocking it. Domains your clients already connected keep working, and there is nothing to run after updating.
Added#
- A Having trouble connecting? section on the Custom Domain card, for your team only. It explains where to look in Vercel when a domain will not connect: a domain still attached to another project, a domain Vercel wants you to verify, and a Cloudflare record that has to be set to DNS only. Your clients' own admins do not see it.
Fixed#
- The card shows the record Vercel recommends for your project. It was always showing the older
cname.vercel-dns.com(or76.76.21.21). Those still work, so nothing already connected needs to change, but new connections get the value Vercel recommends, and a root domain lists every A record to add. - A client domain your hosting needs to confirm no longer gets stuck on Waiting for DNS. The card now shows the
_vercelTXT record Vercel asks for, checks it again once it is live, and names an older record of that kind left by the domain's previous account so your client can delete it.
v5.8.11 (September 2026) - A contact's calls and texts are one conversation#
Replying by text to a missed call no longer opens a second conversation beside it: a contact's calls and texts now share one thread. Texts are also threaded against the number you actually send from, which matters if you have more than one. Two browser tabs no longer flip each other's workspace back and forth, and if another tab or device takes the workspace over, the app now says so instead of quietly showing you the other one's records.
Action required after you update: two commands, both safe to preview first. The first joins up history that already exists: every contact with two or more text or call conversations has them folded into one, including earlier SMS conversations and SMS campaign conversations. Conversations in the trash are left alone. Preview it with
npx convex run --prod migrations/mergePhoneThreads:mergePhoneThreads '{"dryRun":true}'and read the list of merges it prints, then apply it with'{"dryRun":false}'. If you send texts from more than one number, run the second one after the merge to repoint existing conversations at your sending number: previewnpx convex run --prod migrations/restampPhoneThreads:restampPhoneThreads '{"dryRun":true}', then apply it with'{"dryRun":false}'. It never takes a thread identifier another conversation already holds, and reports those instead so you can look at them.Each run handles one batch and returns a
nextCursor. While it is not null, run the same command again with'{"dryRun":false,"cursor":"<nextCursor>"}', pasting in the value it returned, untilnextCursorcomes back null. Keep"dryRun":falsein every one of those runs: both commands default to a preview, so a run without it writes nothing. If any merge run reported"needsAnotherPass": true, a long conversation was only partly moved, so run the merge again from the start until no run reports it.
Changed#
- A contact's calls and texts are one conversation, in time order, with each call still shown as a call card. Email, Facebook, Instagram, live chat and form submissions keep their own threads. A conversation holding both calls and texts is now listed under the SMS channel filter.
- Texts are threaded against the number you actually send from, the one at the top of your Numbers list, leaving out numbers that can only take calls. This only affects sub-accounts with more than one phone number.
Fixed#
- Two browser tabs no longer fight over the active workspace. On a workspace page the address bar wins, and a second workspace opened in a background tab takes over only when you switch to it. There is still one active workspace per login.
- If another tab or device takes your workspace, you are told. A message offers to use this workspace here or leave the page, and leaves whatever you had open underneath alone.
v5.8.10 (September 2026) - Your clients' admins can add and update their own card#
An admin you invited into a client sub-account had no Billing tab, so your client could never add a card, and clients who signed up through a checkout link could see billing but still could not add one. A client's admin can now add and replace their own card, edit billing details and switch auto-recharge on or off, while plan changes and anything that applies to your whole agency stay with you. Along the way, client roles that held billing permissions are stopped from changing agency-wide billing settings.
Action required after you update: admins who already exist in your client sub-accounts still have no Billing tab until you run one command. After you redeploy, preview it with
npx convex run --prod migrations/grantSubAccountAdminBilling:grantSubAccountAdminBilling, read the list of sub-accounts it names, then apply it by adding'{"confirm":true}'. It ticks View on the Billing line of each client sub-account's built-in Admin role where every Billing box is still unticked, and nothing else. Also check that your Stripe customer portal allows customers to update payment methods. If you skip the command, admins added after the update are fine, but the ones you already have still cannot see billing or add a card.
Added#
- A client's admin can add and update the card on file for their own sub-account. They see the Billing tab, can add a card, replace it through Stripe, edit their billing details and switch auto-recharge on or off. They still cannot change or cancel the plan, add wallet balance, buy phone numbers or change anything that applies to your whole agency. When they replace their card, Stripe shows them only the payment method screen. You, your agency admins and anyone you gave billing permissions keep the full Stripe portal.
- Billing Details has an Add Payment Method button whenever no card is on file. This includes sub-accounts where you cover the usage yourself, which had no way to add a card at all before.
Fixed#
- Admins you invite into a client sub-account can see billing. The Admin role created with a new client sub-account had every Billing box unticked, and clients who signed up through a checkout link could see billing but not add a card. Both now work the same way.
- A card added from the billing page is now the card Stripe charges. It was saved to the account but never made the default, so a client who replaced a removed card could still have their renewal fail.
- Client roles can no longer change billing settings for your whole agency. A role inside a client sub-account that held billing permissions could change your agency's plan defaults, dashboard colors and custom CSS, any brand's colors and your billing schedule, read the cost and markup behind every plan, create a brand, and add balance to its own wallet without paying. Each of these now needs agency-level access, and brand admins can no longer change another brand's colors.
- Auto-recharge amounts stay within the choices on the Wallet card, a $10 to $200 recharge when the balance drops below $5 to $50.
v5.8.9 (September 2026) - Your AI setter stops booking the wrong time#
Three separate faults were letting an assistant confirm one time with a customer and put a different one on the calendar. Availability was returning the whole day and leaving the filtering to the model, which offered morning times for afternoon requests even when told in plain words not to. Open times came back written only in your calendar's timezone, so an assistant talking to someone in another state had to convert them itself, and got it wrong. And the assistant could not always save what it learned back to the contact. All three are fixed, there is no migration, and nothing you have already built changes.
Added#
- Booking availability answers for a part of the day, on the customer's clock.
GET /api/v1/calendars/availabilitynow takespartOfDay, which ismorning,afternoonorevening, andcustomerTimezone. The window is worked out on the customer's clock when you send their timezone, and every open time comes back with acustomerLabelwritten in it beside your own calendar's label. A customer in Chicago asking for an afternoon visit was being offered 11am their time, and one in Los Angeles 9, 10 and 11am theirs, because those hours are the afternoon where the shop is. An unknown word, or a timezone that is not a real one, is refused rather than quietly widened back to the whole day. Both new fields are empty when you do not send a customer timezone. - Chat bots can update a contact without putting the contact ID in the web address. There is a new endpoint,
PUT /api/v1/contacts/bot-update, that takes the contact ID inside the request body instead. The existing route still works exactly as before. This exists because some bot builders, CloseBot included, substitute their contact ID correctly into a request body or a query string but corrupt it when it is dropped into the middle of a web address, which left the bot unable to save anything to a contact. Both routes share the same authentication, permission, rate limit, and account separation, and the contact ID still comes from the platform rather than from anything the visitor types.
Fixed#
- One-click CloseBot setup builds your assistant from the current Seedly Starter template. Setup was building from a copy of the flow frozen into the CRM's own code when that version was packaged, so if the template had been improved since, you got the older flow with nothing on screen to tell you why. Setup now asks CloseBot for its own current copy. Assistants you already connected are unaffected, and so is "Use an existing bot".
- A browser tab left open during an update can no longer set up the wrong assistant. A tab that was already open when you updated keeps running the older page code, and that older page asked for the packaged copy by name, so setup quietly built the out-of-date assistant and reported success. Both requests now build from the current template.
- The packaged copy of the assistant is current again. The frozen copy that remains as a fallback had fallen behind: its tools did not send the date and time the customer actually picked, or the timezone that time was said in. It has been replaced with the current flow, and the release gate now checks that it still speaks the current booking contract so it cannot silently fall behind again.
v5.8.8 (September 2026) - A forms and pipelines polish release#
Dropdowns on your forms were showing their placeholder in full strength dark text while the boxes next to them were correctly greyed, so a dropdown looked like it had already been answered. Separately, the Input section in a form field's Styles panel had eight settings that had never done anything, on either the published form or the builder canvas. On the pipelines side, board cards were labelling opportunity custom fields with their internal key instead of the name you gave them. There is no migration and nothing to run.
Added#
- You can put one specific opportunity custom field on your board cards. Opportunity Card Display in Pipeline Settings only offered "Custom Fields", which shows the first three on the record and gives you no say in which. Every card position now also lists your own opportunity custom fields individually, under their own heading, so you can pick the one you care about and put it exactly where you want it. It shows with the field name on the left and the answer on the right, and a card with no answer for that field leaves the row out rather than showing a blank one. The old all-at-once choice is still there, now named "All Custom Fields".
Fixed#
- Dropdowns on your forms show their placeholder in grey, like every other field. This applies to every dropdown in the CRM, not only the ones on public forms.
- The Input styles on a single form field now do something. A field's Styles panel has an Input section with eight settings: font, size, text colour, background, radius, border, border colour and placeholder colour. None of them had any effect, so setting one looked like a bug in the form rather than a setting that was never read. All eight now apply to that one field and override whatever the form's overall Input style says.
- A per field Border or Radius of 0 sticks. Dragging either slider to 0, to square one field's corners or take its border off, was treated as "not set", so the field quietly went back to the form's own setting and the slider jumped back to its old position.
- The builder canvas shows the placeholder colour you picked, and a placeholder colour that came in from a brand style is no longer dropped.
- Custom fields on a board card show the name you gave them, rather than the internal key.
v5.8.7 (September 2026) - Google Business posts publish directly, and your bot can update contacts#
Posting to Google Business used to route through the social connector, which silently dropped the post type and the call-to-action button - an offer with a Book button published as plain text. Posts now go straight to Google through the Google account you already connected, so no connector account is needed for Google Business at all, and everything the composer collects reaches the listing: post types (update, event, offer), call-to-action buttons, event dates, offer coupons and terms, photos, and a per-location checklist when one connection manages several locations. Alongside that, your CloseBot assistant can now write back to a contact rather than only read one.
Action required after you update - only if you already connected CloseBot: the API key created for your assistant when you connected does not carry permission to update contacts, so the new update-contact tool would be refused with a permission error. After you redeploy, run once:
npx convex run --prod closebot:backfillManagedKeyContactsWrite- it grants the permission on that key and nothing else. Fresh CloseBot connections made on v5.8.7 or later need nothing; if you never connected CloseBot, there is nothing to do.
Added#
- Google Business posts publish directly, and stop losing their buttons. Post type, call to action and link, event title and dates, offer coupon, redeem link and terms, and photos all reach the listing. One exception is Google's own rule: it ignores a call to action on an offer post, so the composer no longer offers one there. You can pick which of your locations a post goes to, duplicate a published post to make a variant, and publish immediately rather than only scheduling. Other platforms keep publishing through Zernio exactly as before.
- Your CloseBot assistant can update a contact, not just read one. The contacts endpoint now accepts an update - standard fields, custom fields, and the contact's timezone - and one-click CloseBot setup grants the permission it needs. There is also a simpler request shape for chatbot builders that can only fill in single values: one instruction at a time, with tags merged for you. Note the permission also allows creating and deleting contacts, because API permissions are not per-endpoint.
Fixed#
- Photos that Google would reject are caught before the post is sent. Google requires post photos to be at least 10 KB and 400x300 pixels and accepts only JPG and PNG, but reports a violation as a generic server error after the post has already failed. You now get a clear message naming the actual size or dimensions, both when you attach the photo and on every scheduled or retried send.
- Also in this release: phone numbers bought through the platform now answer inbound calls out of the box (with a repair for existing numbers), inbound calls connect on isolated Twilio sub-accounts, you get warned when Google Ads rejects conversion uploads (with the real rejection reason recorded), ad-click tracking survives hand-edited form embeds, and the social composer gained media previews, an approvals-aware footer, and a working Edit button on the History tab.
v5.8.6 (September 2026) - A privacy cleanup in comments and test data#
Not a feature release. A handful of code comments and test fixtures described real production incidents using the names of real businesses that run on the CRM. The incidents stay documented and the same regression tests still guard them, but the businesses are now anonymous and the fixtures use clearly fictional names. Nothing about how the CRM behaves changes, there is no migration, and if you skip this release nothing breaks.
Changed#
- Real business names were removed from code comments and test data. Some comments and test fixtures explained past production bugs by naming the actual businesses the bugs were found at. That was our mistake to ship, not yours to fix: the technical content is unchanged and the fixtures now use clearly fictional names. The release gate that scans the download for identity leaks now checks for these names too, so they cannot come back.
v5.8.5 (September 2026) - One-click CloseBot setup, a GoHighLevel import, and the waiver that renamed a parent after their child#
The release that connects an AI booking bot to your CRM in one click, and brings your GoHighLevel deal history with you. One-click CloseBot setup turns six manual copy-paste steps across two browser tabs into a single click, and can build and personalize the booking assistant for you. Alongside that, a family of signed-form fixes worth reading if you take waivers: a child's waiver could rename the parent's contact after the child, a family signing several waivers from one phone could be silently refused, and a repair command puts the renamed contacts right. Plus two daylight-saving booking faults, sender pairings your email provider would silently refuse, and pipeline columns that finally put today's leads on top.
Action required after you update: one command, and only for operators using signed forms (waivers) where a guardian has ever signed for a minor. Earlier versions could rename that guardian's CRM contact after the child. Update and redeploy as usual, then run
npx convex run --prod migrations/repairGuardianContacts:repairGuardianContactsonce. It restores those contacts' name and date of birth to the guardian's own details, rebuilt from the stored submissions; nothing else is touched, and the signed submissions themselves are never modified. It reports what it changed and is safe to run even if nothing needs fixing. If you skip it, nothing breaks, but any contact a child's waiver renamed stays wrong until you run it. If you do not use signed forms, there is nothing to do.
Added#
- One-click CloseBot setup. Under AI Auto-Reply (CloseBot) on the Livechat settings page, paste your CloseBot agency API key, pick a bot and the channels it may answer on, and the CRM creates the CloseBot Source, wires both webhooks, attaches the bot and sends a test event to confirm the whole path answers. Six manual copy-paste steps across two browser tabs become one click, and the key is used for that one setup and never stored. If setup fails partway, the message names exactly what was created in CloseBot so you can remove it before retrying.
- Import your opportunities from GoHighLevel. A guided import brings a GoHighLevel opportunities export into the CRM with pipeline, stage, value and history intact, matched to your existing contacts. The import fires no automations (a back catalogue must never look like hundreds of new leads arriving at once), keeps the original created and updated dates, never subscribes anyone to email on its own, and a half-finished run is safe to finish by simply running it again. The import script in your download,
scripts/import-ghl-opportunities.mjs, carries the run instructions.
Changed#
- The packaged CloseBot assistant was refreshed from the latest flow. Clearer tool names and descriptions, and its connection variables are now named base_url and key, the exact names setup fills and the names to use if you ever add them to a bot by hand. A stray space in one tool's authorization header, which broke that tool's API calls, was fixed during the refresh.
- The Bot ID field says what actually works. The helper text implied only the listed bots could be connected; it now says any bot in the connected CloseBot account works, even one imported after the key was checked, with the found bots kept as a copy-paste aid.
- Connecting an existing CloseBot bot takes a Bot ID. The "Use an existing bot" option now asks for the bot's ID directly instead of offering a fixed list, so you can connect any bot, including one whose flow you imported yourself for a different use case. The bots found on your account are still shown beside the field for easy copying.
- One-click CloseBot setup can now build the assistant for you. The default choice imports a packaged booking assistant into CloseBot, publishes it, and personalizes it with the sub-account's business details; its booking tools are wired automatically through the filled source variables. Connecting an existing bot stays one radio button away. If creating the assistant fails partway, the message names exactly what was created in CloseBot so you can remove it before retrying.
- Bot replies answer to the operator's rules on the reply API. A reply sent with a connection's own key now respects a human taking over: once a teammate answers in a thread, the bot's late replies to that thread are refused instead of barging in, while ordinary integration keys are unaffected. Replies are also held to channels the API can really deliver, a reply that would target the CRM's own address is refused so two bots can never answer each other in a loop, live chat replies show as sent immediately, and community direct messages route through the community sender instead of failing quietly.
- One-click CloseBot setup is shorter and labels itself. New connections are named "CRM - your sub-account's name" in CloseBot, so an agency running many connections can tell them apart at a glance. Setup now also fills the bot's own tool variables (the API address and key its tools call your CRM with) automatically, so a bot flow built on those variables works without pasting anything by hand; variables it does not recognize are left alone and named to you. The channel checklist is gone (every channel is allowed by default) and a fresh connection always lands with forwarding switched off, so you flip it on once you have verified the bot.
- The bot's key can quote and book appointments, and nothing more. The key created during setup now carries the verified booking scopes, so a booking bot can read availability, list service types and book through the API. Booking uses proof-of-ownership routes only; the key never receives the stronger appointment scopes that allow reading the full customer roster or touching arbitrary appointments.
- One-click CloseBot setup now wires the bot's replies end to end. Setup configures CloseBot in its modern templates mode: the bot fetches live contact details from your CRM before answering, and its replies come back through a CRM API key created just for that connection. The key can only read contacts and send replies, nothing else; disconnecting the bot deletes the key in the same step. Setup also verifies its own work by reading the configuration back from CloseBot before finishing, so a half-applied connection fails loudly instead of sitting silently broken.
- The reply API meets chatbots where they are.
POST /api/v1/conversations/{id}/messagesnow also accepts a contact id in the path and delivers to that contact's active conversation; the channel field became optional (it falls back to the conversation's own channel) and the destination address falls back to the contact's phone or email. Existing requests behave exactly as before. A reply aimed at a thread a human has taken over is refused rather than barging in. - The manual CloseBot form now lives in a collapsed Advanced section. One-click setup is the prominent path; the hand-wiring form stays one click away, open by default only for accounts that configured it by hand. Connecting also honors the master Forward toggle, an A2P 10DLC reminder shows when SMS is selected, and disconnect vs pause copy says plainly which one deletes the connection.
- One-click setup creates CloseBot sources the way CloseBot requires. Source creation sends the category CloseBot enforces at runtime, and the bot attach uses the source's own channel vocabulary so the connection can never end up silently muted behind unknown channel names.
- One-click setup talks to CloseBot the way its API expects. The management API is authenticated with CloseBot's key header; a bearer header was rejected.
- CloseBot events now carry the conversation and channel by name. Each forwarded message includes conversationId and channel as their own fields, so CloseBot message templates can map them directly. Every event, connection probes included, also carries the same value as channel_id, the snake_case field CloseBot's channel matching and native integration expect.
Fixed#
- The public checkout page never shows internal error labels. A prospect on a sale-link page who hit a refusal (like asking for a billing cycle the plan does not offer) could see a raw internal label such as PLAN_PRICE_NOT_AVAILABLE. The page now uses the strict public error handling: the known refusals (an unavailable billing option, a dead or retired sale link, a seller whose payments or email are not set up yet, and the retry limit) show plain-English guidance written for the buyer, and everything else shows a safe generic message.
- API usage records are written reliably. Each API request's usage row was written on a best-effort basis and could be dropped right after the response went out, exactly the record an operator checks when diagnosing an integration. The write is now completed before the response, and a failure to write it is logged without ever affecting the API call itself.
- A form visitor is told which field was wrong. When a submission is refused by a field's validation, the public form used to show only "Submission failed. Please try again." for every cause. It now shows the field's own message ("Email: invalid email", or an add-on field's reason), so the visitor can fix the right thing. Only per-field validation messages are shown; every other error still gets the generic message so nothing internal can ever reach a visitor.
- A broken voice add-on cannot drop a call either. Completing the call-routing protections: a module that crashes while deciding whether to take a call is now treated as declining it, so the next handler or your normal phone routing takes over; before, a crash there would have ended the call with an error message once a voice add-on was wired up.
- Call audio from a future voice add-on can only go where it should. The seam that lets an installed module answer inbound calls now has the platform itself, not the module, decide whether the module's audio destination is acceptable: it must be a bounded, secure websocket address, and anything else is treated as the module declining the call, so your normal phone routing takes over instead of a call being dropped or its audio sent somewhere unencrypted. No add-on uses this seam yet; this closes the gap before one does.
- The bundled TypeScript client can name every grantable permission. The Node.js client's Scope type had fallen behind and covered only 7 of the API's permissions, so a typed booking integration could not spell the very scopes it needs without unsafe casts. The type now lists every permission an operator can grant, including the whole booking family, and a build check keeps it in step whenever a new permission ships.
- Every way an opportunity's Source can be written now follows the same rules. Creating or editing an opportunity by hand, through the API, or via the GoHighLevel import now trims the Source, ignores a blank instead of erasing the recorded source or creating an empty slice in the source report, and caps its length, matching what web forms and workflow steps already did.
- The key CloseBot replies with can no longer be deleted out from under the bot. One-click CloseBot setup creates an API key the bot's replies depend on, and that key showed up on the API Keys page like any other, where revoking, deleting or editing its permissions silently broke the bot. Those actions now refuse with a message pointing at the AI Auto-Reply section, where disconnecting cleans up the key properly. Renaming the key stays allowed, and a disconnected connection's leftover key can still be deleted normally.
- Automation subscribers are no longer told an opportunity's Source changed when it did not. Sending the same Source with extra spaces through the API used to fire the opportunity-updated automation with a false "source changed" flag while writing nothing new; the comparison now happens after tidying, and a blank Source that is ignored is no longer reported as a change either.
- "Create the assistant for me" no longer claims success with dead tools. CloseBot's flow import does not carry variable definitions, so a freshly imported assistant could arrive with no base_url/key slots; its tools then cannot reach the CRM at all, but setup still said "Connected". Setup now fails that case with instructions: add the two variables to the bot in CloseBot, then reconnect using "Use an existing bot" with that bot's ID. Connecting an arbitrary existing bot with no variables is still fine.
- The protected CloseBot key now explains itself when you try to remove it. Deleting or revoking the auto-created CloseBot key from the API Keys page is refused on purpose (the bot replies with it), but the refusal showed as a noisy technical error. It now says plainly: disconnect CloseBot first, and the key is revoked automatically. Other API-key errors on that page also show their real reason instead of raw technical text.
- Editing the CloseBot key's name works again, and a replaced connection frees its old key. The guard protecting the bot's key fired on every edit from the API Keys page because the edit dialog always sends the permission list, so even a pure rename was refused; it now refuses only a real permission change. And when a one-click connection is replaced by hand-wired settings, the old key it minted can be revoked from the keys page again instead of only by disconnecting the working connection.
- The sender pairing rule now holds everywhere a sender can come from. The earlier fix refused a from address that is not on its paired domain when saving sender settings, but three other doors still produced the same broken pairing: a domain's own Default From Email field (which is copied into every sender setting that uses the domain), the automatic sender setup that runs when a domain verifies, and the last-resort fallback that picks any verified domain. All three now follow the same rule, so a send that the provider would refuse can no longer be configured or silently selected; when nothing valid exists the CRM says "no sender configured" instead of failing invisibly.
- A sender setup the email provider would refuse is now caught when you save it. Pairing a from address with a sending domain the address is not on (say [email protected] with the authenticated t.example.com entry) used to save fine and then have the provider silently refuse every send; notification email simply stopped arriving. The save now refuses that pairing and names the address and domain, and if an older broken pairing already exists, sending skips past it to the next configured sender level instead of dying, with the broken one named in the logs.
- Newest leads sit at the top of every pipeline column. Stage columns used to list oldest first, which buried today's leads at the bottom of a long backlog. Columns now rest newest first; dragging cards between stages works exactly as before.
- Opportunities created by a form are named after the person. A form's auto-created opportunity used to be titled "Form Name - email", which filled boards with hundreds of identical-looking cards. The card now carries the contact's name, falling back to their email.
- The clocks-change fix now holds on every surface and both window edges. A second copy of the old time conversion still shipped to the dashboard, so a staff-edited appointment or a manually scheduled social post at a time skipped by the clocks change could save two hours away from where the booking page offered it; every surface now shares the one fixed converter. And an availability window whose closing time falls in the skipped hour no longer stretches past it, on the calendar booking doors and the services booking door alike, so a slot can never be offered after the hours the calendar states.
- No more 1:00 AM booking slots on the spring-forward Sunday. On the day clocks jump forward, a calendar window opening at a wall-clock time that does not exist (like 2:00 AM when clocks jump 2:00 to 3:00) used to offer its first slot an hour BEFORE the window, a bookable 1:00 AM slot the business never opened. A time that does not exist now resolves forward to the first moment that does, so that window's first slot is 3:00 AM, on the public booking page and the availability API alike. The same rule keeps "start of day" inside the right day for timezones whose clocks change at midnight.
- The Billing settings page checks the right permission. A team member with general Settings access but no Billing permission used to reach the sub-account's Billing page and hit a raw "Access denied" error there. The page and its tab now require the Billing permission up front: the tab is hidden and the direct link shows the normal permission screen.
- Form attribution can no longer be corrupted from a visitor's address bar. UTM values and ad click IDs arriving with a form submission are now trimmed and length-capped before being saved, and junk that is not text is ignored instead of breaking the visitor's submission. A workflow step whose source value comes out empty also no longer wipes an opportunity's recorded source or creates an empty bucket in the source report.
- The CloseBot Forward toggle sticks when you flip it. Turning message forwarding on or off from the AI Auto-Reply header saves immediately; before, the switch could snap back on the next page load. The highlight around the Advanced Connection section also stays inside its card instead of bleeding over the rounded corners.
- The live chat widget loads on other websites again. The widget's loader script was served without the cross-origin header modern browsers require, so any third-party site embedding your chat widget silently got nothing. The script now declares itself safe to embed.
- Wide logos fit in the settings preview. The business logo preview no longer implies a square: a wide mark shows at its real shape instead of being cropped or letterboxed.
- Closed deals show in your pipeline's end stages. A stage marked terminal (like "Closed") used to render empty because the board hides closed deals everywhere; end stages now show their won and lost work. The board also says plainly when a very large pipeline is showing a capped subset instead of silently truncating.
- A repair command restores contacts a minor's waiver overwrote. See the action note at the top of this release: contacts that took a child's name or date of birth can be restored to the guardian's own details from the stored submissions.
- The repair command's report no longer depends on batch size. Its changed-or-not verdict is now computed per contact, so running it with any batch setting gives the same answer.
- A refused signed form now says so instead of pretending it worked. The abuse limiter treats devices, not people, so a family signing several waivers from one phone could trip it. Signed forms are now exempt from the device fingerprint cap, and when the per-form hourly cap does refuse one, the signer sees a clear "try again shortly" message instead of a fake thank-you while the waiver was silently discarded.
- Signed forms no longer block a returning signer or a second family member. A signed submission used to be limited to one per person per form, forever. Because a child usually signs under a parent's email address, a parent could not sign for a second child, and a returning guest was refused with a retry message that could never work. The one-per-person rule is now an opt-in setting on the form, retries are safe, and when a guardian signs for a minor the CRM contact keeps the guardian's own name and details instead of being renamed after the child.
Documentation#
- The customer-appointment endpoints are now in the API reference. They shipped across the last few releases and worked, but the API spec and the integration guide never described them, so the only way to find them was to be told they existed. Both now cover looking up a caller's own appointments, the shorter read that returns only what they can still act on, cancelling and rescheduling. Each one says which permission it needs, how a caller proves who it is speaking for, and why every refusal deliberately reads the same. No behaviour change, documentation only.
v5.8.4 (September 2026) - A shorter answer for booking assistants, so they stop offering a cancelled appointment#
One addition, and only relevant if you point an AI assistant at your CRM. There is now a shorter appointment read that returns just the bookings a customer can still act on, so an assistant stops offering to cancel one that was cancelled months ago. Nothing changes unless you point something at it, and the lookup you already use is untouched.
No action required after you update. Take the build and redeploy. There is no new permission and no migration. If you run a booking assistant, point it at the new read once you have updated.
Added#
- A second appointment read that returns only what a customer can still act on. The existing lookup returns a customer's whole verified history, which is right when somebody asks what they have booked, and turned out to be the wrong thing to hand an assistant that is about to move or cancel something. Given seven records, six of them cancelled and one upcoming, an assistant told the customer the correct upcoming time, tried to cancel one of the old ones, was refused by the CRM exactly as it should be, and then relayed that refusal to the customer as "your appointment cannot be moved", which was not true; every part behaved correctly on the way to telling a customer something false. The new read leaves out cancelled appointments, ones already in the past, and repeating bookings, because those are the ones the CRM would refuse anyway, and when exactly one appointment qualifies it is handed back on its own, so there is nothing to choose between and nothing to pick wrongly. The original lookup still returns the full history, the customer still has to present two matching details before anything comes back at all, and the new read can only ever return less than the one you already have.
v5.8.3 (September 2026) - A customer with a booking could be told they had none#
One fix, and it is worth taking if anything books or checks appointments through your API. A customer who genuinely had an appointment could be told they had none, whenever your CRM held more than one contact record for them sharing a phone number or an email address. That is an ordinary state for a CRM to be in, so the fault was more common than it looks.
No action required after you update. Take the build and redeploy. Nothing about how a caller proves who they are changes, and no migration or backfill is needed.
Fixed#
- The appointment lookup now finds a customer who has more than one contact record. Duplicate records are normal: somebody fills in a form and a row already exists from an import, or from an inbound call saved as a bare phone number before anyone put a name to it, and those rows share a phone number or an email address. The lookup checked the email against one record and the phone against another, saw it was looking at two different rows, and gave up instead of looking for the record that matched both, so the more complete your history for a customer, the more likely they were to be told they had nothing booked. Their booking was never lost, moved, or filed against the wrong person; it simply could not be found through that one endpoint. How a caller proves who they are has not changed: two matching details are still required and must both belong to the same record, so somebody who knows one customer's email address and a different customer's phone number still gets nothing back, and a record that matched only one of the two details stays invisible. One improvement comes with it: a customer who does have several records now gets their appointments returned together, rather than only the ones attached to whichever record happened to be found first.
v5.8.2 (September 2026) - A booking service without your customer list, and time that never came back#
One new ability and two fixes, all about appointments. A booking service can now handle a single caller's own appointment without being trusted with your whole schedule, which until now was the only way to give it that. The two fixes are both about time that never came back: cancelling an appointment through the editor, and moving one, each left the old slot looking busy in Google Calendar.
Action required after you update: one step, and only if you issue API keys. Two grantable permissions arrive with this release, and they are additive: every key you have already issued keeps working exactly as it did. After you redeploy, tick the new permissions on any key that should have the new ability. No migration or backfill is needed.
Added#
- Two permissions that let a booking service handle one caller's appointment without seeing your whole schedule. Until now, the only way an outside integration could see what somebody had booked was the permission that returns your appointment roster, which carries every customer's name, email address and phone number and needs no date range, so handing a booking service enough access to cancel one visit meant handing it your customer list. "Customer appointments - Read" returns one caller's own appointments, and "Customer appointments - Write" cancels or moves that same caller's appointment; neither can reach anybody else, and neither can list anything. The caller proves who it is with either the contact id your CRM issued, or two matching details: an email and a phone number, or either of those together with a last name, and a last name on its own is never enough. Every wrong combination gets the same refusal deliberately, whether it is a wrong detail, a mismatched pair, a customer who does not exist or one with nothing booked, so an outsider cannot confirm one of your customers' email addresses one request at a time. A repeating booking is refused and your admins get a notification naming the customer, the visit and what they asked for, so a person decides rather than an assistant guessing whether "cancel my appointment" meant this Thursday or the whole arrangement. Leave the appointment-roster permission switched off unless something genuinely needs your whole schedule.
Fixed#
- Cancelling or moving an appointment now frees the time it was holding. If you have a Google Calendar connected, the CRM works out what is free from two places, its own appointments and what your connected calendar has on it, and two paths left a slot looking busy after the appointment on it was gone. Changing an appointment's status to cancelled in the editor removed it from your list but asked Google to update the event rather than remove it, so the slot stayed blocked; moving an appointment had the same shape, with the booking going to its new time while the old one went on reading as busy. Both now release the time properly. This stops new ones: a slot that was already stuck stays stuck until the leftover event is deleted in Google, because the CRM treats what is on your calendar as the truth.
v5.8.1 (September 2026) - API key permissions renamed, and a cancelled appointment gives its time back#
Two things that landed after the first 5.8.0 downloads were served, which is why this carries its own version number rather than replacing that one quietly. If you downloaded 5.8.0 in its first day, take this build. If you have not updated to 5.8.0 yet, read that entry first and treat the two as one move.
Action required after you update: one step, and only if you issue API keys. The permission names changed and the old names no longer exist, so a key still holding an old name stops being accepted after you redeploy, with a refusal that names the permission to add. Go to Settings, then Integrations, then API Keys, edit the permissions on each key and tick the new names. The key value itself does not change, so whatever is using that key does not need a new secret. There is no migration and no backfill; the update adds one database index that applies itself on deploy.
Changed#
- API key permissions now say what they cover. Permissions moved to a
resource:actionshape:calendars:readis nowappointments:read,calendars:writeis nowappointments:write, andbooking-availability:readis nowavailability:read, and the old names no longer exist. This is breaking: a key that still holds an old name stops being accepted after you update, and the refusal names the permission to add, so it reads as a permission problem rather than an outage. The part worth having is that listing calendars moved off the roster permission: it used to require the same permission as reading the appointment roster, which carries every customer name, email address and phone number on the schedule, and it now sits underavailability:read, so a booking agent can ask what is free and book a slot without ever being able to read who else is on the schedule. If you run a booking agent or a third-party integration, give itavailability:read,appointments:write,service-types:readandbooking-estimates:read, and leaveappointments:readoff; that is the roster, and almost nothing needs it.
Fixed#
- Cancelling an appointment now frees the time Google Calendar was holding. The CRM works out what is free from two places, its own appointments and a cache of what your connected Google Calendar has on it, and cancelling only ever cleared the first one: the cached Google event stayed behind, on some routes the CRM never asked Google to delete the event either, and since availability reads both, the slot stayed blocked with nothing anywhere reporting a problem, so a customer trying to rebook saw the time as taken. Every way an appointment can be cancelled now frees the time: from the dashboard, through the API, from the link a customer uses to cancel their own booking, a whole recurring series, a checkout that fails, a payment that expires, and the sweep that clears unpaid holds. An appointment you cancelled before this update may still have its event sitting in your Google Calendar, and while it is there the CRM will keep treating that time as busy; deleting it in Google frees the slot.
v5.8.0 (August 2026) - Backend guidance for your coding agent, and groundwork for outside integrations#
A documentation release. Nothing in the CRM behaves differently, there is no migration, and you do not need to redeploy for it to take effect.
No action required after you update. Take the new file and carry on. It changes what the coding agent working on your CRM knows, not what your CRM does.
Added#
- The backend folder now has its own instructions for your coding agent. Your download already ships
CLAUDE.mdat the root, plus notes for the front end and several individual screens. The backend folder,convex/, had none, and that is where almost 1,800 files and every piece of business logic live. There is now aconvex/CLAUDE.md, which your agent reads automatically whenever it works in that folder. It covers the layout, which folders hold what, and the rules that are easy to get wrong, such as never hand-editing the generated files and what the extension registries are actually for. - A warning your agent needed and did not have. The backend has two test suites with two separate configuration files, and the ordinary
pnpm testruns only the first of them. So an agent that ran the tests and told you they passed may not have run the 161 security tests at all. The second suite has its own command,pnpm test:security, and the new file says so plainly.
v5.7.1 (August 2026) - The CRM takes add-on modules, and two billing faults that were costing you money#
The release where the platform stops being one fixed product. An add-on module installs into the CRM you already run and contributes into the builders you already use, rather than arriving as a separate app to keep in sync. Alongside that, two money faults worth reading about before you update: a wallet that read as topped up and never charged the card, and automations that could hand two live invoices the same number.
Action required after you update: two steps, and both are decisions only you can make, because both are about billing that was quietly landing on you. First, check for sub-accounts whose auto-recharge switch is on but was never configured; after this update those cards genuinely start being charged. Second, decide what happens to sub-accounts that have never had usage billing chosen for them. The
CHANGELOG.mdinside your download gives the exact commands, including a dry run that prints what it would change before anything is written. Nothing is migrated or rewritten by updating itself, and if you skip both, nothing breaks and no data is lost.
Added#
- The CRM now takes add-on modules. A module can put ready-made workflows into your template gallery, attach its own context to a trigger you already fire so your existing automations can branch on information that did not exist before, add its own action nodes, add its own field types to your forms, and publish the wording of its own messages into your System Defaults catalog. A module declares the shape of a thing and the CRM still draws it, so theming, layout and keyboard behaviour stay yours.
- An add-on can be sold as part of a plan. Plan features were a fixed list of the CRM's own modules, so there was no way to switch a purchased add-on on for one tier and off for another. Contributed toggles now appear in the plan editor grouped under Add-ons, so you can see which parts of a tier come from an add-on rather than the base product.
- Automations now run when a customer accepts or declines an estimate on the page you sent them. They always ran when you marked an estimate accepted inside the CRM, but the customer clicking Accept, which is how most estimates are actually accepted, quietly triggered nothing. If you already have automations on estimate accepted or declined, expect them to start firing. That is the fix working, so review them before customers start receiving anything they send.
- A deposit paid by card now creates the balance invoice, which previously only happened when you recorded the deposit by hand. You can also now request a deposit from a draft invoice and split it, which the backend supported all along with no button anywhere.
- You can lift the SMS quiet hours for one location. Texts are refused outside 9 AM to 8 PM in the recipient's local time, which is right for anyone messaging consumers. A location whose customers are buildings has a legitimate after-hours message, so the floor can now be lifted per location, behind a typed confirmation, with a record of who lifted it.
- Invoice and estimate templates can carry a service-type tag, which an add-on uses to suggest the right template on a job. Optional, and hidden until an add-on writes it.
- Your download records the exact code it was built from, so two downloads of the same version are no longer impossible to tell apart.
Fixed#
- Auto-recharge read as ON, never charged the card, and left you paying for the client's usage. Turning the switch on saved the switch but not the two settings beside it, so the wallet stored no top-up amount and no threshold. The Wallet card still displayed "$20 when balance drops below $5", because that screen filled those in for display only. The charge never fired, the low-balance send block was skipped, and the sub-account's messaging costs stayed with you. Read the action required note above before you update.
- An invoice created by an automation could be given a number another invoice already had. The workflow steps numbered a new document by counting the ones already there, and a count goes back down when you delete something, so deleting one draft and creating the next left two live invoices carrying the same number. That is the number your customer quotes when they pay. Automations now take their number from the same sequence as the rest of the CRM. Existing numbers are not changed, so it is worth a look at anything your automations raised.
- Google Sheets and Drive steps let you pick the file instead of pasting an ID. Click "Choose from Google Drive" and select the spreadsheet or folder. The step then shows the file name and the account that authorised it. This also narrows what the CRM can reach: Google grants access only to the files you pick, rather than to every spreadsheet in your account. Open each existing Sheets or Drive step once and choose its file again, or that step will report that the CRM has not been given access. The workflow editor flags the ones that need it, and steps writing to a sheet the CRM created keep working untouched.
- A cluster of workflow faults. Google Sheets, Drive and Calendar steps failed with "No Google account connected" while the Google card said Connected the whole time, because the engine renewed access the wrong way. A step that failed was recorded as completed with the reason thrown away. Workflow settings could not be saved at all, for any setting or any workflow. Testing a workflow used up the contact's one real run, and the switch that would have released them could not be saved because of that same bug. The step list vanished every time you added a step. And palette steps could only be dragged, which a keyboard cannot do at all.
- The Google connection card offered Gmail while Gmail was switched off, which matters beyond the broken button: Google's reviewers compare what your product shows against what it asks for, and a mismatch there can cost you an approval.
- X could never be connected or posted to, because the CRM and the publishing service spell two platforms differently and the CRM sent its own spelling on every call. Social analytics skipped X and Google Business posts for the same reason. The connect popup now closes and returns you to the CRM instead of stranding you on the publishing service's dashboard, it works when you sign in on a branded domain, and error messages no longer name the publishing vendor to your clients.
- The Time report showed only your own hours, so a manager opening it saw their own work and concluded the team had logged nothing.
- A code editor was adding 1,300 pixels of blank page below itself, on any page carrying one.
- Installing an add-on turned your own test suite and typecheck red, and sent every user to the add-on's first screen at sign in instead of their dashboard. Nothing was wrong with your CRM or the add-on.
- Several billing corrections. Usage rebilling required a plan, so a sub-account without one was never rebilled. The Rates card understated two of its own prices. "My agency covers this client's usage" had a hidden third state. And a sub-account sending from your agency's fallback domain was still refused.
v5.7.0 (August 2026) - Write your emails in HTML, and a footer that was quietly missing#
The release that opens up email. Campaigns can now be written as HTML in a proper three panel editor, every code box in the CRM became a real code editor, and campaign links go through your own tracking domain instead of a shared one. Alongside that, a footer fault that had been silently dropping your business address from invoices, receipts and password resets, a Send Now that could destroy an email you had written, and Google Ads reporting that had stopped working entirely.
Action required after you update: no commands are required this release. The
CHANGELOG.mdinside your download carries two optional repair tools, for a sending domain that was set up wrong. Most instances will never need either. If you are updating an existing copy rather than installing fresh, that same section lists five retired files to delete by hand, because the update helper never deletes anything.
Added#
- Write a campaign email as HTML, in a three panel editor. Your code on one side, a live preview on the other, and a divider you can drag. You choose blocks or HTML when you create the campaign and it stays fixed, so a finished body can never be overwritten by an empty canvas. A step inside an automated sequence can be written in HTML too.
- Every code box in the CRM is now a real code editor. The HTML block, the email layout editor and the custom CSS box get syntax colouring, bracket matching, line numbers and wrapping, in colours that follow your palette in light and dark.
- Campaign links go through your own tracking domain. Click tracking rewrites every link through a tracking domain, and until now that was your provider's shared default. Setting up a sending domain now sets up a branded one alongside it.
- Email layouts you build once and reuse, plus creating, sending and scheduling campaigns straight from the API.
Fixed#
- Zoom meetings scheduled from a booking now show the correct wall-clock time. A booking on a Zoom-linked calendar created the meeting fine, but the time shown on Zoom's own screens (the pre-join lobby, the Zoom-side confirmation, the Zoom Meetings app) came out shifted by the difference between UTC and the calendar's timezone. A noon booking in Eastern showed as four in the afternoon. The customer's calendar invite from the CRM was correct all along, so this only affected what the customer saw when they opened the Zoom link, but that is where most people look, and the wrong time reads like a scheduling mistake on your end. Zoom's own API accepts a meeting time in two formats that must never be mixed, and the bridge was sending both. It now sends only one, so Zoom has one definitive answer instead of two. Existing Zoom meetings on your calendar are not touched; rescheduling one in the CRM is the fastest recovery for a wrong-time meeting already booked before this fix.
- Your business address was missing from invoices, receipts and password resets. The two buttons that fill in the Global Email Footer wrote it in a shape that transactional mail silently discards, so those emails went out with no address block at all. Every footer configured before this release is affected, so open the field and check it after updating.
- Google Ads reporting had stopped completely, and reconnecting did not help. Google retired the API version the CRM was calling, and a manager account cannot serve figures at all. Both are fixed, and a daily check now warns before a retirement takes reporting down again.
- Send Now could destroy an email you wrote as HTML and send a blank one in its place. Save already refused to overwrite it. Send Now did not.
- Editing the Terms and Conditions block could destroy your text, collapsing a multi paragraph block into one run the first time you typed in it.
- A cancelled recurring invoice still said it was generating invoices, because the screen read the settings saved on the invoice rather than the series that is actually running.
- Several ways an unsubscribe could be lost or ignored, including merging two contacts, a drip that kept sending after someone opted out, and a preference centre that unsubscribed people who only pressed Save.
- The public checkout pages were unreadable under a dark palette, on the two screens your customer sees while paying.
- Content in an email block could reach your recipient as working code, and a preview pane could run without the protection every other preview uses.
- You now get told when Google Ads conversion tracking has quietly stopped, rather than seeing the numbers go flat and reading it as a slow month.
- The Google card said Connected while your Google connection was dead. It reported whether a connection existed rather than whether it still worked, so Analytics, Ads reporting, Business Profile and Search Console could all be returning nothing behind a green tick. It now says Reconnect needed, tells you what Google actually said (an expired sign in is fixed by reconnecting, a switched off API or a billing problem is not), and warns you on the dashboard instead of only on the settings screen.
v5.6.1 (August 2026) - Selling plans, and getting paid for them#
Every purchase through a public sale link was failing before it reached Stripe, assigning a plan by hand could never create a subscription, and a client who did get through could not sign in because their welcome email never sent. All three are fixed. Alongside them, renewals that had quietly stopped are chasing payments again, subscriptions can be designed in the invoice builder, estimates can be signed in person and paid on the spot, and sticky notes work again.
Action required after you update: this release needs commands run against your live database. The exact commands, in order, with what each does and what goes wrong if you skip it, are in the
CHANGELOG.mdinside your download under 5.6.1. Read that section before you update, not after.
Fixed#
- Selling a plan through a public sale link returned an error. If you sell plans with a sale link, no purchase could complete. The checkout failed before the customer ever reached Stripe's payment page. Assigning a plan from the admin side failed separately, for its own reason, so neither route into a subscription worked.
- A client who bought a plan could never sign in. The purchase went through and the money arrived, but the welcome email carrying their sign-in link never sent, so the account they had just paid for was unreachable.
- Renewals and failed payment chasers stop after a Stripe version change. Subscriptions stopped renewing and failed payments stopped being chased, with nothing to indicate it had happened.
- Every way a workspace gets created now sets it up the same. A workspace made through one route could come out configured differently from one made through another, so behaviour depended on how it happened to be created.
- A paused campaign could be marked Sent without sending anything. Pausing a campaign at the wrong moment left it recorded as sent while no message went out.
- Sticky notes on the automation canvas broke four ways at once.
- Accepting an estimate could zero it out.
- Refreshing a workspace page no longer bounces you to the dashboard.
Added#
- Subscriptions you can design in the invoice builder, plus fixes to five separate scheduling faults.
- Estimates can be signed in person and paid on the spot, rather than only by sending them.
- The foundations add-on modules plug into. Nothing changes today. It ships now because the seams have to exist in the version you are running before an add-on can install into it.
v5.6.0 (August 2026) - Ad conversions that actually arrive, and a delete that really deletes#
Your Meta and Google ad conversions were being discarded before they ever reached the ad platform, and now they arrive. Deactivating or deleting a client account finally takes its public pages offline, and there is a permanent delete that really deletes. Alongside that: priced service bookings collect the money, you can cover a client's usage costs yourself, and a scale pass aimed at sub-accounts with 200 or more users, plus a long correctness sweep across Stripe, invoices, e-signing, forms, and ad tracking.
Action required after you update: this release needs commands run against your live database. Two of them change what past months report, two work through your records in batches and have to be re-run until they finish, and one treats a dry run as the default. The exact commands, in order, with what each does and what goes wrong if you skip it, are in the
CHANGELOG.mdinside your download under 5.6.0. Read that section before you update, not after.
Added#
-
You can permanently delete a client account, and it really deletes. Delete only ever deactivated. Deleting is now two deliberate steps: deactivate, which is reversible, then a separate permanent delete that shows you how many records it will destroy, asks you to type the account name, and removes the account row last.
-
Groundwork so add-on modules can install into a running CRM. Nothing changes today. With no module installed every connection point is empty. It ships now because the seams have to exist in the version you are running before an add-on can install into it.
-
Paid service bookings actually take payment. Before this, a service with a price on it booked like a free one and nobody was ever charged. A priced service now sends the customer to checkout, holds the slot while a bank payment (ACH, SEPA, Bacs) settles, releases it immediately if that payment fails, and closes the payment page when a booking is cancelled. A free booking still confirms the way it always did.
-
Cover a client's usage costs yourself, per client. A new per-sub-account setting in Admin lets your agency absorb a client's usage instead of billing it through, so you can run a client on an all-in retainer without them ever seeing a usage line.
-
Ad tracking credits the ad that produced each payment. Revenue is now attributed at the deal level rather than to whatever touch happened last, conversions are dated when the money moved rather than when the automation ran, and the amount that reaches Google Ads and Meta is the real one. Conversions also fire from forms you embed on your own site, and dynamic number insertion can be switched on without help.
-
Your web forms collect text-message consent the way carriers require. Marketing consent is captured separately from transactional consent, declining the marketing box actually stops marketing, and what the person agreed to is recorded as a structured record you can produce later.
-
Raise your own workspace send limits. The sending caps, the per-workflow daily execution cap, and the per-user hourly composer limit are all adjustable from settings now instead of being fixed.
-
Bulk team invites, and an honest "email not sent" state. Invite several people at once, and when an invitation email cannot be delivered you are told, rather than the invite sitting there looking sent.
-
Searchable team-member pickers. Assign-to, @mention, and member pickers are searchable and no longer silently drop people once a workspace gets large.
-
Archiving an email sending domain is reversible. Archive one by mistake and you can bring it back instead of re-verifying from scratch.
-
Form notification emails name the submitter and link the signed copy. The email you get when a form comes in now tells you who filled it in and links straight to their signed record.
-
The Stripe Connect panel tells you what Stripe is still waiting for. Instead of a bare "not ready", the panel names the outstanding requirement, adds a Refresh status button, and passes the client's email to Stripe so your dashboard shows who each connected account belongs to.
-
An optional replay-protected webhook signature. Outbound webhooks can now carry
X-Webhook-Signature-V2alongside the existing header. It is additive, so nothing you have built breaks; see the webhooks guide for how to verify it and when to move over. -
The invoice and estimate editors explain the opportunity link. The editors now say what linking a deal actually does for reporting instead of leaving it to guesswork.
Changed#
- Transactional email is no longer blocked by a marketing unsubscribe. Someone who opts out of your marketing still receives their receipts, booking confirmations, and document links.
- Marketing email sends on the marketing sender and stream, and bulk sends carry the required commercial-email footer.
- Scheduled social posts use the client's timezone, not whatever timezone your browser happens to be in, both when scheduling and when reading the time back.
- Sequence active hours use the sub-account's timezone as well.
- Disconnecting Stripe now asks you to type DISCONNECT, connecting or disconnecting a client's Stripe requires your second factor, and both are written to the audit log.
- Stripe's own error messages now reach you. The Connect buttons used to replace a specific Stripe error with a generic failure.
- Service prices are stored in whole currency units. Imported prices in yen, won, and other whole-unit currencies were 100 times too low.
Fixed#
- Your Meta ad conversions were being thrown away. Meta requires a page address on any conversion that says it came from a website, and silently drops the ones that arrive without it. It does not return an error: it replies success and reports the event as received, so from the CRM side everything looked healthy while nothing arrived. Form conversions and the revenue conversions from the Customer Paid workflow are both fixed. Conversions discarded before you update cannot be recovered, so expect your Meta numbers to step up from the update rather than fill in backwards.
- Deactivating a client account now takes its public pages offline. A deactivated account kept serving its forms, booking pages, documents and estimates to anyone holding the link. Deactivating looked like an off switch and was not one. Unsubscribe and preference-centre pages deliberately keep working, because recording an opt-out must never be blocked.
- Meta conversion tracking can be set up without connecting a Facebook Page. The setting used to hang off a Page connection that could not be completed, so the card looked available and was not. Disconnecting a Page also no longer throws your conversion settings away with it.
- The Meta test event proves itself. It sent no customer information, which Meta rejects, and reported success on any reply rather than on Meta accepting the event. It also has to describe itself as a website event or it never appears in Meta's Test Events tab at all. You can now edit the Pixel ID and test event code without re-pasting your access token.
- Google Ads conversions carry the event source, and click IDs stop breaking uploads. Attaching hashed customer identity to a conversion that already had a click ID turned a working upload into a rejection on accounts that have not signed the enhanced conversions terms, so the better-known lead failed while the anonymous one succeeded.
Bookings and payments
- A booking whose payment page could not be created no longer strands the customer on a spinner.
- The customer is no longer told two opposite things about the same booking.
- A bank payment that landed after the slot was released no longer takes the money anyway.
- Cancelled bookings no longer clog the payment sweeper.
- A free service booking used to send the customer nothing at all.
- Card payments were being recorded as failures by a routing mistake.
Invoices and revenue
- Invoices could end up fully paid and never marked Paid, silently.
- "Mark as paid" now records the payment in the payments ledger, so cash, cheque, and bank-transfer revenue stops being invisible to reporting.
- Refunding part of an invoice no longer erases the rest of it from your revenue.
- A lost chargeback now updates the invoice instead of leaving it reading Paid.
- A paid hosted Stripe invoice now marks the CRM invoice paid.
- A payment against a voided invoice no longer un-voids it.
- A percentage late fee could go negative on an over-paid invoice; a late fee on a partly-paid invoice could break its pay link.
- The pay link is cleared when a checkout expires or is partly paid, so a customer cannot be charged an old total.
- Editing a sent estimate's amount now returns it to draft, so the client cannot accept the old figure.
Forms, documents, and e-signing
- Public form submissions no longer fail under load on a busy or embedded form.
- Signing a form by drawing your signature works again.
- Long blocks of text on a form keep their paragraphs, and embedded forms follow the width you set and survive a WordPress save.
- Signed documents are more complete and harder to tamper with: each signer's own signature image is kept, views are logged to the certificate, a declined document is guarded, and the certificate hash is real.
- A paid "collect on sign" document now records its payment instead of stranding the signature.
Large teams
- The inbox list and its search now scale to a full conversation history rather than only what had been loaded.
- The unread badge is accurate again on large teams.
- The audit log pages properly and reaches your full history.
- Large inbound ring groups no longer silently drop the caller.
- The outbound caller-ID picker is scoped to your own sub-account.
- Task-submission and workflow "notify everyone" alerts no longer write to the database once per person.
- Busy workspaces no longer slow to a crawl from internal usage counters.
API
- By-id and sub-resource routes under the API work again; they had been unroutable.
- The
totalcount in a response is the real total, not the size of the page you asked for.
Calendar, integrations, and messaging
- Outlook calendar sync now works when you connect Outlook per user, at parity with Google.
- Saving one integration no longer wipes another on the Admin integrations screen.
- A dead Facebook or Instagram page token now flips the connection to "needs reconnecting" instead of failing quietly, and inbound Meta messages reach the right client with working read receipts.
- Deleting a scheduled social post removes it at the provider too, and a partial publish is reported instead of silently half-succeeding.
- A failed outbound email in Conversations now tells you why it failed.
- Soft-bounced email retries actually re-send.
- Three workflow wait-and-resume timing defects are closed.
- Deleting a team member no longer leaves their calendar availability behind.
Texting registration
- Brand registration sends your business details in the format the carriers expect, the campaign step registers instead of failing on the opt-in wording, a campaign rejected by a carrier can be re-submitted, and your privacy policy, terms, and consent wording are sent with the campaign.
- A web-form business no longer declares a text-keyword opt-in it does not use.
Setup and safety
- The guided setup companion walks you through putting your site online, writes your web address to the backend so sign-in works, and no longer creates two different values for one shared secret.
- The setup guide picks up five corrections buyers reported, and now says that Stripe needs two webhook destinations rather than one, and exactly which events each needs.
- The test suite that ships in your download no longer fails on a fresh copy.
- Deleting a sub-account now cleans up its Stripe artifacts, in the right Stripe account, even when a restricted account would previously have blocked it.
- You can no longer create a plan before connecting Stripe.
Security#
- Every known security advisory in the packages Seedly is built on is cleared, including the sign-in system (closing ten published advisories) and the image-processing library.
- A client sub-account with no Stripe of its own could read and write to the agency's Stripe; that boundary is now enforced on every webhook payment and refund event.
- One client could connect or disconnect another client's Stripe.
- Three Stripe screens could be pointed at an outside address; that redirect is now constrained.
- Names and titles typed by other people were being dropped into emails without escaping.
v5.5.6 (July 2026) - Client domains, signed forms, and phone notifications#
Point each client's own domain at their public pages and email links, turn any form into a signed legal record, and get real push notifications on your phone. Plus brand fonts, form SLA tracking, and the largest correctness sweep in the product's history.
Action required after you update: this release needs four commands run against your live database, or five if you connected Gmail or Google Calendar before this version. They fill in new lookup columns on data you already have. Skipping them does not crash anything, which is what makes it easy to miss: social DM threads, company contact counts, daily cost charts, and Stripe charge history simply read as empty or stale for older data. The exact commands are in the
CHANGELOG.mdinside your download under 5.5.6.
Added#
- Give each client their own domain for public pages and email links. Point a client's domain, or a subdomain like
go.theirbusiness.com, at their sub-account and every public link for that client rides it instead of your platform address: forms, booking pages, invoices, estimates, documents, the client portal, QR codes, review requests, and the unsubscribe and preference links in their marketing email. Aligning the unsubscribe link with the sending domain is also something inbox providers reward. A domain stays inert until it is verified, so a typo cannot break a live link, and a client's own admin can set theirs up without any access to your hosting account. - Turn any form into a signed legal record. Switch on Signed Submissions, add a signature field, and each submission becomes a proper signed record: the person sees the terms and signs by drawing or typing, an exact copy of what they agreed to is frozen at that moment, and the record carries a tamper-evidence code plus an audit certificate of who signed, when, and from where. The signer gets a permanent link to their own copy, and signed records are protected from data-retention cleanup so an old waiver is never quietly aged out. Deleting a form that holds signed records now makes you type DELETE to confirm.
- Get phone notifications for incoming messages. Real push notifications on phones and desktops for new texts, email, Facebook, Instagram, and live-chat messages, with the browser closed and the phone locked. Each person enables it for themselves and quiet hours are respected. An assigned conversation notifies the assignee; an unassigned one notifies the sub-account's members, so a new lead is not left sitting because nobody had claimed it yet. iPhone requires adding the site to the Home Screen first.
- Add your own brand fonts, and use them everywhere. Add up to four Google Fonts by name and they appear at the top of every font picker across the account, render on the builder canvas as you design, and load on everything you publish: email, live form embeds, and your booking, document, invoice, and estimate pages, which previously did not load custom fonts at all.
- Form submissions count toward your SLA response targets. A new form lead starts the same response clock as an inbound text or email, with its own target under Conversations, Tracking. A human reply on any channel stops the clock; auto-responders do not.
- Share a review as a picture, not just text. Sharing a review to social now builds a branded review card image to go with it.
- Create a new contact right from the new-message screen, prefilled from what you typed, without leaving to Contacts and back.
- Send a bulk text or email to a whole smart list, not just the page of contacts you can see.
- Make any form full width with one switch, which is what you want when the form sits in a full-width band on your site.
- Rotate the Closebot callback address yourself if it ever leaks.
- Reset a client's Outlook calendar connection from the agency side.
- Add a spam check to your review-request feedback widget.
Changed#
- Connecting Google no longer starts syncing your inbox automatically. Gmail sync now starts off and you turn it on yourself, with a confirmation that explains what will happen. Connecting Google just for calendar conflict checking no longer pulls your whole inbox in as a side effect.
- Two-factor authentication moved into the Security box on the account screen.
- The Conversations inbox opens on All instead of Mine.
- Google connections clearly show when they need reconnecting.
- The per-line Tax field is gone from the estimate builder, which was a source of confusion against invoice-level tax.
- Split-test steps are checked before a workflow goes live, so branch percentages that do not total 100 are caught at publish instead of quietly rebalanced at send time. Branching steps also gained an "On disable" choice.
- Heads-up for SendGrid users: your event webhook now has to be signed, or delivery tracking reads 0%.
- Call-transcription cost updated for the newest transcription model.
Fixed#
This release closed a very large correctness and isolation sweep. The themes:
- Account isolation. Pending invitations no longer show across the wrong client accounts, a brand manager stays inside their own brand (including for provider settings), automations only touch records in their own client account, Facebook and Instagram messages always reach the right client, and public pages and endpoints are better protected.
- Money. Refund and invoice math stays exact, per-line discounts on an estimate actually come off the total, discounts carry through, estimates and recurring invoices bill the right amount, billing math is exact in non-US currencies, and refunds, late fees, and pay links are handled more carefully.
- Reporting. Reports no longer drop the last day of the range you pick or undercount recent activity on busy accounts, trends and exports show real numbers, revenue and engagement totals count correctly, contact list counts and daily digests are exact, and the busiest-hours chart in Conversations reporting shows again.
- Workflows. Sequences advance past the first step, sending windows that cross midnight work, splits that wait and rejoin no longer send twice, steps that can fail let you route the failure, a deal moved to a new stage lands in the right position, and a test run stays a test instead of firing real automations.
- Messaging and calls. Texts respect quiet hours, spending limits, and consent; calls, recordings, and AI call grading are accurate; missed CallRail calls and voicemails notify your team; calls answered on a cell phone show up in reports; and phone numbers move cleanly between clients.
- Forms. Content is cleaned on the server rather than only in the browser, embedded forms show up on WordPress and stop flashing a tall empty box, side-by-side fields stack neatly on phones, the builder canvas shows the form at its real width, and signing on a phone puts the ink where your finger is.
- Data handling. Contact import, export, and erasure requests are handled safely, deleting data cleans up every stored file that came with it, and old notifications are cleaned up without starving reminders.
- Scale. The CRM stays fast and never hits a size limit as an account grows, calendar conflict checks and booking pages stay fast on large accounts, and one-time setup and import jobs finish.
v5.5.5 (July 2026) - Connect your website to your CRM#
Wire an outside website's forms and purchases straight into the CRM, plus a batch of forms and email-sending fixes. If you use inbound webhooks, the webhook fixes here are worth applying.
Added#
- Prefill a public form from the link. A new per-form switch (off by default) lets a link fill in a form's visible fields on arrival, so a known contact lands with their name and email already filled. They still review and submit.
- Send a workflow notification as an email. The Internal Notification action gained an "Also send as email" toggle, so a "notify me" step can land in your inbox, not just in-app.
- Redirect people after a double opt-in confirmation. A confirmation form can send someone to a page you choose after they confirm, for example your email-preferences page.
- See the last requests an inbound webhook received. The Inbound Webhook trigger now shows the most recent payloads it got, with each field as a copyable path, so you can build the workflow against a real request instead of guessing field names.
- Grandfathered plan pricing. A plan can keep older Stripe products and prices alongside its current one, so clients still billed on an older price still match the plan.
- An alert when a payment matches no plan. A plan-sized payment that does not match any plan now raises a notification instead of being skipped silently, so nothing goes unfulfilled.
- Edit a client's recurring task checklist from the Tasks screen. Open a client's project and add, edit, remove, and reorder the checklist that runs each billing cycle.
- Duplicate a recurring task to copy its content, assignees, and schedule.
Changed#
- The API no longer creates duplicate contacts. Posting a contact with an email that already exists now updates that contact instead of adding a second one.
- Plan tasks fire for subscriptions created outside the checkout link (for example one you assign directly in billing), not just the public sale link.
- Recurring task editing opens in a roomier side panel with a proper assignee picker.
- Share a brand's verified sending domains with its sub-accounts from the Sending Rules screen.
- The Sender Fallback panel shows the full stack - the domain actually sending, plus the inherited brand or agency fallbacks.
- A new email domain's purpose auto-fills from its name (a "t." subdomain for transactional, "m." for marketing), with an override.
- Form submissions show up in the Conversations inbox as a new message, so leads land in the same place as your calls, texts, and email.
- Checkbox fields have a separate "Checkbox Text" for the sentence next to the box, apart from the short label used in reports.
Fixed#
- Each inbound webhook now triggers only its own workflow. Every inbound-webhook workflow has its own URL, but sending to one URL used to run every inbound-webhook workflow, which could produce empty duplicate notifications. Now one URL runs one workflow.
- Inbound webhook trigger URLs now actually work. The URL shown in the builder was returning a "not found" before, and correctly signed requests were being rejected. Both fixed.
- Inbound webhooks find the contact by email, so a webhook carrying an email creates or updates that contact and the workflow's tag, task, and notify steps have someone to act on.
- Consent submitted on a form is now recorded on the contact.
- Archived brands no longer appear in the account switcher (still in Admin if you need to restore one).
- A field moved below the submit button no longer shows twice on a public form.
- Client forms and notifications send on your agency's verified domain even on a sub-account that has not set up its own, so they no longer silently fail to send.
- A verified domain can send both transactional and marketing email - the purpose is a preference now, not a hard block.
- Embedded forms redirect the whole page after submit, not just the little form frame.
- Form dropdowns use your brand color for the hovered and selected option.
v5.5.4 (July 2026) - Sell plans and auto-create client tasks#
The biggest update in a while. Nothing here is required for an existing install, but a couple of the fixes are worth applying.
Added#
- Sell a plan from a public checkout link that collects your buyer's business details (name, contact, email, phone, website, address) before they pay, so the new workspace is created already filled in instead of just the card email.
- Client tasks are created automatically when a plan is paid: the first payment runs a one-time onboarding checklist and sets up a recurring checklist, and every renewal re-creates that checklist with due dates based on the actual payment date. You build the whole flow visually with a new "Plan Purchased" trigger and an "Apply Task Template Set" action.
Changed#
- Plan upgrades and downgrades now take effect at the end of the billing period instead of switching mid-cycle with a prorated charge. The billing screen shows the queued change and lets you cancel it before it applies.
Fixed#
- A limited-access role (like a "Tasks Only" role) no longer crashes the dashboard.
- The Admin Plans page no longer hides itself behind an empty category when you create your first category.
- The Invite User role dropdown now lists a sub-account's custom roles.
- The Create Role and Settings and Access tab bars no longer stretch full-width.
v5.5.3 (June 2026) - Mobile follow-up#
Nothing here is required for an existing install.
Fixed#
- On a phone, the green "Voice Calling" button now sits in the bottom-right corner instead of the top bar, so it is easy to reach with your thumb. Desktop is unchanged.
v5.5.2 (June 2026) - Mobile polish#
A couple of small mobile fixes. Nothing here is required for an existing install.
Fixed#
- On a phone, the floating call dialer now stays pinned to the bottom-right corner. If you had dragged it somewhere on a desktop, that saved position could previously leave it off-screen on a small screen, and on very narrow screens it could run past the edge. It now sits neatly in the corner and sizes itself to fit.
- The "Privacy blur" button is now hidden on phones. It is a desktop tool for screen-sharing, so it no longer crowds the top bar on small screens.
v5.5.1 (June 2026) - A spam-call blocker for your phone numbers#
Adds a strong new spam-call blocker, plus a few fixes. Nothing here is required for an existing install.
Added#
- "Require key press to connect" on a phone number (Settings, Integrations, Telephony, Numbers). When it is on, any caller who is not already a saved contact has to press a short code on their keypad before the call connects, which stops robodialers cold. Saved contacts ring straight through. It is free (no paid add-on), and you can leave the older spam-screening toggle off when you use it.
Fixed#
- The inbound spam gate is now more forgiving and more reliable: the keypad challenge gives callers a longer window and a few tries before going to voicemail, a caller who passes is no longer occasionally hung up on, and a caller whose contact was moved to trash is correctly treated as unknown at the gate.
- The three-dot "Move to Trash" on a contact row now works. It previously did nothing; only the multi-select checkbox delete worked.
- Settings, Access: the Users / Roles / Teams / Notifications tab bar now hugs its tabs instead of stretching a border across the page, and the Pending Invitations list has a bit more breathing room above it.
v5.5.0 (June 2026) - Sprout: a friendly guided setup#
Setup tooling for new installs. Free for everyone who owns Seedly.
Standing up your own copy of Seedly is now a guided experience instead of a checklist of manual steps.
Guided setup#
- Meet Sprout, a friendly setup companion. Run one command and Sprout walks you from a fresh download to a live CRM: it checks your prerequisites, helps you create your accounts and provision the backend, walks you through picking and connecting your providers, points your domain, and gets you through A2P registration. You stay in one place the whole way, and you connect providers in the dashboard rather than pasting secrets into a terminal.
- One command to create your first admin. A single bootstrap command deploys your backend, generates and sets your secrets, and creates your first agency and admin account. There is no more toggling a sign-up gate on and off to sneak the first account in. It is safe to re-run and will not touch an install that already exists.
- A setup doctor checks your install. Run one command to confirm your environment is configured correctly: the right values are set on both your test and live backends, secrets are in the correct format, and your deployment is reachable. It tells you what to fix and never prints your secret values.
- A secret generator. One command prints the exact set of secrets Seedly needs, in the right formats, with separate values for your test and live environments.
- Smoother updates. Pulling in a Seedly update no longer drops you into confusing merge conflicts on auto-generated files.
v5.4.0 (June 2026) - Forms, tracking, messaging, and a broad fixes wave#
Free for everyone who owns Seedly.
A wide release of new capabilities and fixes across forms, tracking, messaging, telephony, and white-label.
Forms and analytics#
- Form analytics now show a real average completion time, measured from how long people actually take, instead of a placeholder.
- Send your form leads to your ad platforms automatically. Form submissions can now fire Google Analytics 4 conversions and Meta conversions, so your ad reporting and optimization see your leads.
- The Rating field's "Numbers" style now shows real number cells in the builder, matching the live form, defaulting to a 0-5 scale, with a left or center alignment option.
- Clearer wording on the Google Ads form-tracking setting so it is obvious conversions only send when you have the toggle on.
Tasks#
- Export your task time tracking to CSV from Tasks for reporting and payroll.
Messaging and campaigns#
- SMS sequence campaigns now send. Drip SMS steps that previously did nothing now deliver as intended.
- Smart (filter-based) lists now reach the right people, with accurate member counts shown on the list. A Smart list that used to quietly send to nobody now resolves to its real audience.
- Accurate filter counts on Conversations and Appointments.
Telephony and integrations#
- Telnyx A2P brand import and real Telnyx phone-number pricing, so you can register and buy numbers with correct, live pricing.
- The Google Sheets workflow step now maps your column headers to the right cells when it appends a row.
Contacts and calendar#
- Pick an appointment template right in the create-contact dialog.
- The Outlook calendar connection stores each event's ID in its own field so events sync back and forth reliably.
- Stronger privacy compliance: erasing a contact now also clears five additional places their personal data was stored, so a delete really removes everything.
White-label and branding#
- Public invoice, estimate, document, review, and customer-portal links now show your brand in the browser tab, not Seedly's.
- Prebuilt email templates now use safe placeholder links instead of example.com sample URLs, so a template you forget to edit will not point customers at a dummy address.
- A clean, neutral white-label sign-in screen.
List pages and search#
- Removed the dead "Search…" boxes on the Reputation, Invoices, Subscriptions, Users, Roles, and Teams pages. Those pages have no text search behind them, so the boxes never did anything; with them gone, you see only the filter dropdowns that actually work.
Permissions and cleanup#
- Staff accounts created during sign-up now get Dialer, Tasks, and Call Reports access out of the box, instead of those core features appearing locked.
- Removed a Wallet "Refresh" button that did nothing, since the balance already updates on its own.
- Renamed the agency privacy toggle from "Demo mode" to "Privacy blur" so its purpose is clear: it blurs personal data on screen for demos and screenshares.
v5.3.0 (June 2026) - AI call grading, calling reliability, and accurate rebilling#
Free for everyone who owns Seedly.
AI#
- Connect your own OpenAI, Anthropic, and AssemblyAI keys. AI now runs on whichever provider you configure, so you are not locked to one, and each provider's usage is billed correctly.
- AI call grading and coaching: recorded sales calls can be transcribed with the speakers separated, then scored against a rubric you set, so reps get a grade and coaching notes. Choose to grade outbound calls, inbound calls, or both; voicemails are never graded.
Automation & Workflows#
- The Invoice Paid trigger can now fire for specific products only: pick one or more products and the workflow runs just for purchases that include them, alongside the existing tag and amount filters. Leave it blank to keep firing on every paid invoice.
- A trigger's type is now locked in once you drop it on the canvas. The settings panel shows the type read-only instead of an editable dropdown, so a placed trigger can no longer be accidentally switched to a different type (which would have quietly dropped its filters). To use a different trigger, delete the node and drag in the one you want.
Reputation#
- Replies you have already posted to your Google reviews now import when reputation syncs, and the reviews list shows whether each review has been replied to.
- Connecting reputation lists every Business Profile location with its address so you can pick the right one, and reviews now load correctly for profiles that were previously failing.
- You can connect multiple Google Business Profile locations to one account. Each location syncs and tracks its own reviews, and you can choose which connected business a review request points to from the Smart Gate, the Send Review Request dialog, and the dashboard's location filter.
- Review request links now come from your connected Business Profile directly, so a service-area business (which does not appear in a map search) gets its own correct review link instead of a similarly named business. Re-selecting a location refreshes its link.
- A new switch lets you turn the Smart Gate off. Leave it on to route feedback through the gate, or turn it off to send customers straight to your chosen review page.
- Clean up reviews from the wrong profile: disconnecting a location offers to delete the reviews it brought in, and a per-location list lets you remove any left over from a profile you already disconnected.
- Embed the Smart Gate on your own website with a Copy embed code button, so you can collect and route feedback from your site, not just from review requests you send.
- Share a review as a social post: it opens the social planner with the review content prefilled instead of an empty composer.
Email & deliverability#
- SendGrid open, click, and bounce events record correctly again. A signature mismatch had been causing every event to be rejected, which left email analytics blank. The email domain settings also now warn you when event tracking is switched off on SendGrid's side.
- Heading blocks in the email builder render as clean text instead of showing raw HTML.
Voice#
- Inbound numbers can screen callers to cut down on spam and robocalls, asking an unknown caller to confirm before the call rings your team. Turn it on per number.
- Browser calling is more reliable: each deployment now runs its own calling app (fixing a case where a shared setup could break live calls), and a caller-ID number is freed the instant a call fails instead of staying stuck as "in use".
- Call tracking is more accurate: conversions only count a genuine answered call, and only once; rep credit is consistent between the leaderboard and call grading; and an inbound call answered on a rep's cell or desk phone is now credited to them.
- The Call Report lets you click any row for the full call detail (transcript, recording playback, and the grade breakdown), and the Date and Rep columns now display correctly.
- When you own more than one number, drag to reorder them; the one at the top is your primary number for outbound texts.
Billing & rebilling#
- Every channel now bills at its true cost: inbound calls and texts cost less than outbound, recordings bill at the lower storage rate, and each passes through at your markup. Voice and AI markups now apply correctly.
- Inbound billing is now included in each provider's Rebill toggle instead of separate switches, so turning on Rebill for a provider covers its inbound usage too.
- You are no longer charged for inbound email received on SendGrid, which is free to receive; inbound email on Postmark still bills.
- Telnyx now bills at its own cheaper rates instead of Twilio's, across direct sends, booking and reminder notifications, and campaigns, and inherits your Voice and SMS markup.
- The customer billing tab shows only the final rate a customer pays, with a clear label for each charge. Your underlying cost and markup are never shown to them.
- Inbound spam screening now bills through your plan, and a brand admin controls who can turn on the paid screening.
- Billing data is strictly isolated per account, so one sub-account can never read or change another's usage, rates, or wallet.
Campaigns#
- Broadcasts now respect their Active Hours window: a send scheduled outside the window waits and shows a Deferred status instead of firing late or being skipped.
Conversations#
- A failed SMS now shows a plain-language reason instead of failing silently, and the composer warns you before sending a text that would land inside the recipient's quiet hours.
Forms#
- Form submission notification emails now include every field the contact submitted.
General#
- Lists with checkboxes support Shift+Click to select a range of rows for bulk actions.
- Demo mode now hides customer personal information across many more screens, including integrations, billing, the dialer, reputation, account and admin, and the message composers, for safer screen-sharing and recording.
- The app's browser tab title and favicon are neutral out of the box, so you can white-label your instance with your own brand.
v5.1.0 (June 2026) - Social module restored, follower growth, contacts polish#
Free for everyone who owns Seedly.
Social#
- Scheduling and analytics now work again after our social provider rebranded its API (the change had quietly stopped scheduled posts from publishing and left the analytics dashboard blank)
- Scheduled posts publish reliably, posts with images keep their image, and editing or rescheduling a post now takes effect
- The analytics dashboard, Best Time to Post, and Followers count all populate again
- New follower-growth chart backed by a daily follower snapshot, so you can see how each account grows over time
Contacts#
- Bulk Add Tag: select multiple contacts and tag them in one step, with the option to create a new tag inline
- Auto-created guest contacts (placeholders for unknown inbound callers and texters) are now tinted so they are easy to spot and tidy up
v5.0.2 (June 2026) - Inbound calling, fixed end to end#
A patch release. Free for everyone who owns Seedly.
Fixes#
- Calls from a number that is not yet a contact now ring through instead of being rejected as busy. New callers are saved as a contact automatically.
- Voicemail now works end to end: when no one answers, the caller hears your greeting and can leave a message, and that message is recorded, transcribed, saved to the contact's conversation, and announced with a New Voicemail notification.
- Call recordings are now saved and play back inside Conversations. (Previously the phone provider captured them but they were never pulled into the CRM.)
- A call that only reaches a cell phone's voicemail is now logged as missed instead of answered, so your call stats are accurate.
New#
- Voicemail email forwarding: turn it on in Settings and new voicemails are emailed to your team with the transcript and a link to listen.
- A one-time import is available to pull recordings from earlier calls into the CRM (see the Developer changelog for the command).
v5.0.1 (June 2026) - Inbound calling fix#
A patch release. Free for everyone who owns Seedly.
Fixes#
- Inbound calling: calls to your number now ring the in-app phone instead of hanging up the moment they arrive. (In v5.0.0, inbound calls were dropped before they could reach a rep.)
v5.0.0 (June 2026) - Calling, QR codes, booking, paid ads & conversion tracking#
The biggest release yet. Anyone who owns Seedly gets v5.0 free.
Calling#
- Built-in phone: place and receive calls right in your browser with a keypad, mute, hold, and one-click voicemail drop
- Power Dialer: build a calling queue from a list, segment, or pipeline stage and work down it one contact at a time with auto-advance
- Click to call any contact, matched automatically to their record
- Call recordings, written transcripts, and outcome tags on every call
- Calls now thread into the Conversations inbox alongside texts and emails
- Built-in calling compliance: a voice Do-Not-Call list, calling-window and no-call-day enforcement in the contact's local time, and required call outcomes before moving on
- Per-rep caller ID and flexible routing: give each rep their own number, and ring inbound calls to a rep's browser, desk phone, or cell
- Call quality tools: device selection, a pre-call connection test, and per-call quality scoring
- Call Report: total calls, connect rate, talk time, outcomes, dispositions, and a rep leaderboard for any date range
QR Codes#
- Dynamic QR codes you can re-point at any time without reprinting
- Brand color customization, live preview, PNG download, and a copyable short link
- Organize codes into folders
- Scan analytics: total scans, scans over time per code, and side-by-side comparison
Conversion Tracking#
- Send offline conversions back to Google Ads and Meta so your ad platforms optimize toward real customers, not just clicks
- Fire conversions from a form, a workflow, or a qualifying tracked call
- Recommended Lead and Customer Paid funnel so bidding can target actual revenue
- More accurate matching using your customers' protected contact details, in addition to the ad click
- Export conversions to a file for manual upload any time
Calendar & Booking#
- GoHighLevel-style booking page: side-by-side date and time selection (responsive), optional redirect-on-success, and a smoother pre-theme load
- Branded booking emails: confirmation, reminder, cancellation, and reschedule messages render as branded HTML matching your transactional templates
- Auto-branding from your default Style: new calendars and their emails inherit your brand color (plus optional email header color and global footer) automatically; the setup wizard now walks you through setting it once
- Cancel/reschedule cutoff: block client-side changes within a set window of the appointment (for example, up to the day before)
- Pick which Google calendar bookings sync into
- Customer booking emails are recorded in the Conversations inbox
- Paid bookings now reliably create the Zoom meeting and calendar events after payment
Forms#
- Double opt-in: per-form confirmation flow with a branded confirmation email
- Auto-create an opportunity in a chosen pipeline from leads on submission (optionally ad-sourced leads only)
- HTML content block with a code editor and safe rendering; the builder canvas now matches the live form exactly; embedded forms auto-resize to fit their container
Paid Ads & Analytics#
- Paid Ads dashboard now runs on live Google Ads data (campaigns, spend, clicks, conversions); the placeholder sample data is gone
- Campaign drill-down: ad groups, top keywords, and the actual leads each campaign produced
- Organic (GA4) tab shows real Google Analytics data when a property is connected, with a connect-prompt otherwise
Reliability & Fixes#
- More accurate reporting: first-response time counted once per conversation, with consistent date-range boundaries
- Workflow reliability: parallel branches are no longer dropped when one branch is waiting; split steps route by their configured weights; a paused branching step follows a single path
- Campaign sequences: correct follow-up timing, overnight send windows, and an unbiased A/B split
- Billing accuracy: per-line tax is applied correctly, payment links and synced invoices charge the full total including tips and fees, and revenue reports count what was actually collected
- Pipelines and conversations: cleaner bulk stage moves, accurate win-rate counting, and exact response-time tracking
- Time zones: booking and invoice emails, quiet hours, and appointment edits now use the business time zone consistently
- Continued security hardening: stricter cross-account and cross-brand data isolation, tighter permission checks, and more reliable webhook processing that retries instead of dropping events
- Merge fields no longer expose internal record identifiers to recipients
- Fixed a crash that could affect public form pages
- Dark mode polish across the remaining public and in-app screens
- Privacy: customer message content is kept out of internal logs
v4.1.0 (May 2026) - Tasks module packaging fix#
A patch release. Free for everyone who owns Seedly.
Fixes#
- Packaging fix so the Tasks module installs cleanly on a fresh setup. The previous build left out a few Tasks files, which could stall a brand-new install part-way through. Same features as v4.0.0; this release just makes sure everything you need ships in the download.
v4.0.0 (May 2026) - Security audit, billing UI, and builder polish#
A major release following a platform-wide security audit. Free for everyone who owns Seedly.
Security & reliability#
- Platform-wide security audit hardening across messaging, forms, login branding, webhooks, and permissions
- Tighter permission checks so each user only sees and acts on the data their role allows
- Public form redirects are validated, so a redirect can no longer be used to slip a malicious link past your form
- Contact data in operator-sent messages can never inject code into the message you send
- More reliable webhook processing: a transient failure now retries instead of dropping the event, so a delivered email or text event is never silently lost
- Automatic cleanup of old activity, automation, and notification history so your data does not grow without bound (the windows are yours to set)
Payments & invoicing#
- Single-business Stripe: if you run one business on infrastructure you control, you can take payments on your own Stripe account directly, with no extra connected account to wire up
- Stripe payments received automatically now fire the same automations as a manual "mark paid": workflow triggers, contact scoring, and lifecycle changes all run, so a paid invoice no longer skips your follow-up
- Fixed a case where heavy public traffic could lock customers out of viewing their own invoice, estimate, or document
- Estimates flip to a "Viewed" status when the customer opens them, matching invoices
- Draft invoices and estimates can be previewed immediately, no send required, including a phone-frame preview of the real customer view
- Long invoices and estimates flow onto new pages automatically as content grows, and Processing Fee, Late Fee, and Tip now appear as their own line items
Billing & wallet#
- Reworked billing screens: a clear rate card beside your wallet balance, a single Plan & Payments tab, and a separate Transactions view
- Corrected usage pricing so messaging and calling bill at sensible, near-cost rates
Email & templates#
- Branded transactional emails: invoice, estimate, and document emails carry your logo and a consistent layout
- Template pickers across Payments, Documents, Forms, and Calendar so you choose which email sends for each event, with a live preview
Documents & forms#
- Document signing hardening: signers can only fill their own fields, multi-signer documents use per-recipient links, and signature drawing now lines up with the cursor at any screen size
- Collect a payment at signing: once everyone has signed, the customer is taken straight to checkout
- Mobile-friendly document viewer
- Form submission protection: a per-address cooldown on auto-responder emails stops your form being used to spam someone, optional submission-retention windows, and an alert when a form is being hammered
Automation, conversations & UI#
- Sequence engagement gate: automatically exit or reroute contacts who stop opening your emails after a set number of steps
- Calendar Enable reuses an existing Google connection instead of forcing another sign-in
- Invoice, estimate, and document emails now thread into the contact's Conversations inbox, with a backfill for past sends
- Two-way community-platform DM sync: community direct messages arrive in your inbox and your replies send back out
- Privacy blur (demo mode): one toggle blurs contact names, emails, and phone numbers across the whole dashboard for safe screen-sharing
- Builder polish: a roomier condition editor, a cleaner contact picker, and adding an element no longer jumps you to the Styles tab
v3.0.0 (May 2026) - Tasks module, Social, and compliance-grade messaging#
A major release. Free for everyone who owns Seedly.
Tasks (Projects)#
- New Tasks module: a full project and task manager with projects, tasks, subtasks, dependencies, time tracking, templates, recurring tasks, and both kanban and list views
- Client intake: a public request form and a floating "Submit Request" widget feed a brand-level review queue, and a product purchase can auto-create a project from a template
Social#
- Social module overhaul: a cleaner analytics layout, Best Time to Post suggestions right in the scheduling dialog, and drafts that open straight in the planner
- Multi-tenant social credentials so each sub-account connects its own accounts, with a rebuilt Connections screen
- Social DM bridge: direct messages flow into Conversations, can trigger auto-responses and workflows, and can be answered by AI auto-reply
Messaging compliance & deliverability#
- Built-in text-message compliance: quiet-hours enforcement in the recipient's local time, a per-message consent trail, and a content check that flags missing brand identification or opt-out language before you send
- Broadcasts and sequences honor per-list opt-out and STOP, and a broadcast can no longer fall back to blasting your entire contact list
- Email deliverability analytics group recipients by their mailbox provider, and connecting a sending provider registers its tracking automatically
- Email builder and sending overhaul: a font and color toolbar, separate mobile styling, and send presets with staggering, throttling, and warmup-aware pacing
Reputation & calendar#
- Event-driven review requests with per-channel reminder toggles
- Calendar hardening: text reminders respect consent, double-booking across calendars is prevented, daylight-saving edge cases are handled, and new appointment events are available to your automations
Contacts & reporting#
- CSV import smart-splits a single Full Name column and auto-creates any new tags as it goes
- Audience growth chart backed by daily subscriber snapshots that survive bulk imports
- A Google Analytics (GA4) dashboard that paints instantly when you return to the tab
Security & reliability#
- Multiple security audit sweeps: cross-account isolation, least-privilege permission checks, hardened token handling, and request size limits across Conversations, Invoices, Workflows, and Forms
- Forms fail closed on CAPTCHA, protect spreadsheet exports from formula injection, and enforce conditionally-required fields on the server
- Accessibility: a WCAG AA contrast pass and normalized design tokens
v2.1.0 (May 2026) - Calling, billing, telephony, and AI auto-reply#
The release that brought usage billing, telephony, and payments together. Free for everyone who owns Seedly.
Telephony#
- Optional per-customer telephony isolation: give each sub-account its own isolated phone-provider account so billing, data, and credentials are separated per customer
- A2P 10DLC registration flow, with the option to import a brand and campaign you already registered directly with your provider
- More reliable inbound and outbound texting: correct credential routing per sub-account, delivery-status callbacks, and a fix so every purchased number keeps its text and picture-message capability
- Caller ID name registration
Calling & recordings#
- Call recordings saved into the CRM with automatic transcription, a retention window, an optional provider-side purge, and a download from the Call Report
Billing & payments#
- Usage billing system: a per-sub-account wallet, metering for text segments and call minutes, opt-in inbound billing, A2P fees, and a markup pass-through so you can rebill your customers
- Stripe Connect for sub-account charges: each sub-account connects its own Stripe to take payments, with deterministic refund routing
- Per-business Stripe keys and payment-path hardening, including idempotent refunds and recharges
- Capture a card on file per sub-account, sync your product catalog from Stripe, and a resilient invoice send pipeline with a working public Pay button and Reset to Draft
Messaging & AI#
- AI auto-reply: connect an AI chatbot to answer across six channels (text, email, Gmail, Messenger, Instagram, and live chat), with automatic hand-off the moment a human replies
- Embeddable live-chat widget: a floating bubble that expands to a full chat panel, with an avatar uploader, that you can drop on any website
- Live-chat visitor messages auto-assign so they land in an operator's inbox
Sub-accounts & setup#
- Account templates: clone a designated sub-account's setup (templates, pipelines, lists, workflows, products, tags) into every new sub-account
- Encrypted provider credentials with a repair pass, and provider access that follows the brand and agency credential cascade
Reputation & documents#
- Reputation Smart Gate: route happy customers to your review page and surface unhappy feedback first, with a compliance-safe fallback so every customer can still reach your public review page, plus multiple destinations, brand theming, and a live preview
- Document and invoice canvas templates now render for customers (PDF and web), with create-from-template cloning and seeded starters
Dashboard & email#
- Redesigned multi-tab dashboard with Call Report, Pipeline, Audience, Organic, and Paid Ads views
- Email subsystem rework: a per-tier sender, a payment-method gate on sending, and DMARC verification
v2.0.0 (March 2026) - Public beta#
The first public release of Seedly CRM.
Seedly CRM entered public beta with the full platform in place:
- Contacts & Companies - custom fields, tags, smart lists, engagement scoring, CSV import/export, bulk actions, and linked company records
- Unified Inbox - one thread per contact across text, email, Gmail, Facebook Messenger, and Instagram, updating live
- Pipelines & Opportunities - visual kanban boards, opportunity scoring, stage gates, stale-deal detection, products and line items
- Campaigns - email broadcasts, multi-step sequences, and text campaigns with segment targeting and analytics
- Workflow Automation - a visual builder with 60+ action types, 40+ triggers, branching, A/B splits, delays, and execution logs
- Forms - a drag-and-drop builder with multiple field types, spam protection, public links, and embed codes
- Calendar & Booking - multiple calendar types, public booking pages, availability rules, and email and text reminders
- Invoices & Payments - invoicing with line items, Stripe collection, estimates, recurring invoices, and a product catalog
- Documents & E-Signatures - a block editor with signature fields, document flows, merge fields, and view tracking
- Reporting - report views across contacts, pipelines, conversations, campaigns, workflows, calendar, and agent performance
- Reputation - Google Business Profile review sync, review requests, and response management
- Social - scheduling and publishing across Facebook, Instagram, and LinkedIn with analytics
- Settings & Administration - sub-accounts, users, roles, permissions, integrations, custom fields, tags, audit log, and billing
- Multi-Tenancy - a three-tier Agency, Brand, and Sub-Account hierarchy with credential cascade and per-plan feature gating
- Real-time data across every connected client, and role-based access control with view, create, update, and delete scopes
