Questions? Email [email protected] · All prices are one-time unless stated otherwise
D
Datapad Projects
Reference

Changelog

Release notes for every published CampaignCanvas version, newest first.

1.2.5

  • Fix — running out of Vouch credits mid-clean wrote off the addresses it never got to. When a Clean list run exhausted your credits partway through a batch, the addresses Vouch had accepted but never actually attempted were recorded as though they'd been checked and come back inconclusive. The run itself halted correctly and told you credits had run out — but topping up and re-running then skipped those very addresses, because they now counted as already-verified, leaving the opt-in "also re-verify previously-inconclusive addresses" checkbox as the only way to reach them. Addresses a credit-exhausted batch never attempted are now left unverified, so a re-run after a top-up carries on exactly where the last one stopped and every address in scope still gets a real verdict.

1.2.4

  • Trigger your own automations on contact activity, straight from Umbraco's Webhooks. CampaignCanvas now adds three events to Umbraco's built-in Settings → Webhooks picker — Contact Created, Contact Subscribed to List, and Contact Unsubscribed from List — so you can POST contact activity to Zapier, Make, a CRM, or your own endpoint with no code and no form to hang a workflow on. A subscribe fires the moment a contact becomes genuinely active — immediately on single-opt-in lists, or on the confirmation click for double-opt-in — and an unsubscribe carries the reason where one was given. Umbraco handles the delivery, retries, custom headers, and logging you already know.
  • Every subscribe and unsubscribe payload includes the contact's full list picture. Alongside the contact's details and the list that triggered the event, the payload carries a lists array of every mailing list with that contact's status on it — Subscribed, PendingConfirmation, Unsubscribed, Bounced, or None when they're not a member — so the receiving system can mirror the complete subscription state in a single call instead of asking back. Bulk imports and bulk list changes deliberately don't fire these per contact, so a 50,000-row import can't storm your endpoint.

1.2.3

  • Contact CSV export now records each address's verification status. The Export contacts to CSV download gains a VerificationStatus column, so every exported contact carries its latest Vouch verdict — Deliverable, Undeliverable, Risky, or Unknown for addresses not yet checked — right alongside the existing bounce columns. It makes list health easy to filter, report on, or hand to another system without opening the backoffice, and it's populated for suppressed contacts too so you keep the complete picture.

1.2.2

  • Re-verify addresses Vouch couldn't reach a verdict on. Some addresses come back inconclusive ("Unknown") from a clean — the mailbox server gave no clear answer, usually a temporary block, greylisting or timeout rather than a genuinely bad address. These are skipped on later cleans so you're never charged twice, but that left no way to try them again. The Clean list dialog now offers an opt-in "Also re-verify N previously-inconclusive addresses" checkbox: leave it unticked to verify only never-checked contacts as before, or tick it to re-check the inconclusive ones too. The estimated cost and credit check update to match your selection, so you always see the exact charge before starting — nothing is ever re-verified silently.

1.2.1

  • Fix — Clean list over-counted the contacts it would verify, and the credits it would cost. The pre-flight estimate counted your whole contact base instead of only the addresses still needing a check, so a mostly-clean list quoted a charge for everyone — a list of thousands could report thousands of credits (and warn you were short) when only a few hundred addresses were actually unverified. Already-verified contacts are now correctly skipped in both the estimate and the run itself, so the cost shown matches what you're charged, and re-running Clean list never re-verifies — or re-bills for — an address that was already checked on an earlier run.

1.2.0

  • New — know exactly who you're mailing, with email verification by Vouch. Every mailing list quietly rots — people change jobs, abandon inboxes, mistype their address on signup — and every dead address you keep mailing chips away at your sender reputation until real subscribers stop seeing you. CampaignCanvas now plugs straight into vouch.fast, which verifies addresses at the actual mailbox: a live SMTP conversation with Gmail, Outlook and the rest, not just a syntax pass. Setup is one paste — grab a vch_live_… key from the Vouch dashboard, drop it into Subscribers → Email verification, and it's validated and stored in your site's appsettings.json for you. Live instantly; no restart, no config-file surgery.
  • Clean your whole list in one click. The new Clean list action verifies your entire contact base (or a single mailing list) with live progress in the backoffice. Every subscriber gets a verdict — deliverable, undeliverable or risky — plus the reason (mailbox not found, no mail server, disposable domain, …), the grid filters by verdict, and definitively dead addresses go straight to the suppression list so every future send skips them automatically. Cleaner list, fewer bounces, better inbox placement for every campaign that follows.
  • Start with a free list health check. Every Vouch key includes one free, no-credit health check — a structural diagnosis of your whole contact base that tells you how bad the rot is before you spend anything ("18% of your subscribers look undeliverable or problematic"), broken down by cause. Percentages only — the full clean is what names names. It's the fastest way to see what Vouch can do: mint a free key at vouch.fast and run it today.
  • Fair, transparent credits. Verification runs on prepaid Vouch credits — roughly a cent per address, cheaper in volume, no subscription. CampaignCanvas shows the estimated cost against your live balance before a run starts and halts safely if credits run out. It's also deliberately cautious with your data: an ambiguous result never marks an address undeliverable, "risky" addresses are never removed automatically, and if Vouch is ever unreachable your signups and sends carry on untouched.
  • Dependency update — MailKit 4.15.1 → 4.17.0. Updates the SMTP delivery library to pick up the fix for a published security advisory.

1.1.19

  • Fix — multi-choice fields showed System.String[] in submission emails and CSV exports. When a form had a checkbox-list or multi-select field (for example "which newsletters would you like?"), the new-submission notification email and the submissions CSV export printed the literal text System.String[] in that row instead of the options the person ticked — so you couldn't tell what they'd actually chosen. These fields now render as a comma-separated list of the selected values. Single-value fields are unchanged, and nothing was lost from existing data: every choice was already stored, so re-exporting an older submission now shows its values correctly too. (Notification emails already delivered can't be rewritten — the fix applies to submissions received from this version onward.)

1.1.18

  • Bounced addresses are now suppressed automatically, however the bounce is reported. When a mailbox permanently rejects a message, that address is counted against its hard-bounce tally and — once it crosses the threshold (3 by default) — added to the suppression list, so it's skipped on every future send. Previously this only happened when your provider rejected the message at the moment of sending; bounces reported a few minutes later over a provider webhook — the usual case for SendGrid, Mailgun, Postmark and Resend — appeared in analytics but never stopped the address being mailed again. Continuing to email dead addresses quietly erodes your sending reputation, so this protects deliverability for your whole domain.
  • Hard and soft bounces are now told apart for every provider. SendGrid and Resend reported all delivery failures as a single generic "bounce", mixing permanent failures (a bad address) with temporary ones (a full mailbox, a greylisting deferral). They're now classified the same way Mailgun and Postmark already were — only genuinely permanent failures count toward auto-suppression, and your per-campaign hard/soft bounce breakdown is accurate.

1.1.17

  • Unsubscribes are now counted against the campaign that drove them. Opting out via the unsubscribe link or the preferences page now registers on the originating mailing's "unsubscribed" figure. Previously a campaign only counted the opt-outs your email provider reported back, so unsubscribes through the built-in link and preferences form were invisible in per-campaign analytics. The opt-out link now carries the send it came from, and repeated one-click hits (mail-client prefetch plus the manual confirm) are de-duplicated so the count stays accurate.
  • Email a list owner when someone unsubscribes. Every mailing list can now hold one or more notification addresses (Mailing list editor → Notifications). When a contact unsubscribes through the public link, those addresses receive an email naming the contact, the list, and any reason given; leave the field blank to keep it off. The preferences form could already notify via its email-notification workflow — this brings the same alert to the direct unsubscribe link, which has no workflow to hang one on.

1.1.16

  • Marketplace listing refresh. The package description and README have been rewritten into clearer, benefit-led copy covering the full forms + newsletter platform, with extra discovery tags (newsletters, email-marketing, gdpr). No functional changes — this release exists to publish the updated listing.
  • Docs — corrected licence-key link. The Licence key section pointed at campaigncanvas.net for installation instructions; it now points at the Datapad customer portal (projects.datapad.nl/projects/campaigncanvas), matching the purchase and support links.

1.1.15

  • Fix — an expired trial could still display as "Active". The License page and banner decided "active" from a cached flag without re-checking the expiry date, so a lapsed trial could show "Active" next to "Expired". An expired trial now correctly reads as inactive — so the genuine licence state, and any activation issue behind it, is no longer hidden.
  • Clearer activation failures. Entering a licence key that can't be validated no longer silently reverts to the trial. The page now states the reason — and an unlicensed domain reads "Domain 'X' isn't on this license yet. Add it in the portal at projects.datapad.nl, then click Refresh." instead of a generic message.
  • Diagnostics. When a validation response is rejected as outside the freshness window, the log now records the response's issuedAt and this server's current time, so a clock / time-sync problem on the host is obvious at a glance.

1.1.14

  • Maintenance. Licensing reliability and internal housekeeping.
  • Backoffice. The CampaignCanvas dashboard now shows the installed package version, so it's easy to confirm which build a site is running.
  • Licensing. Licence validation now reports the running Umbraco and CampaignCanvas versions to the licensing service, so compatibility guidance stays accurate.

1.1.13

  • Fix — newsletter settings page on SQL Server. The migrations that add the preferences-link and subscription-pages columns to the newsletter settings row used ALTER TABLE ... ADD COLUMN ..., which is valid SQLite syntax but invalid on SQL Server (SQL Server's ALTER TABLE ADD does not accept the COLUMN keyword). On SQL Server installs upgrading from 1.1.11 or earlier, the migration silently failed inside the startup upgrader and the newsletter settings page then errored with Invalid column name 'includePreferencesLink' / 'preferencesPageUrl' / 'subscriptionPagesJson'. The migrations now emit the keyword-free ALTER TABLE T ADD col TYPE form, which is valid on both providers. Every other ADD COLUMN migration in the plan got the same correction so future upgrades from intermediate versions don't hit the same trap.

1.1.12

  • Preferences link in campaigns. Outbound campaigns can now carry a "manage your email preferences" link in the footer alongside the existing unsubscribe link. Enable it from Newsletter settings and point it at a content page that hosts a preferences form — the link is signed per-subscriber, so the destination form consumes the token and writes back to the right subscription record.
  • Mailing-list checkboxes form field. New field type that renders one checkbox per configured mailing list and stores the ticked ids on the submission. Paired with the existing "Add to mailing list" workflow so a single form can opt a submitter into several lists at once, with labels captured at edit-time so renames don't break public pages.
  • Resubscribe after unsubscribe. The unsubscribe-success page now offers a one-click resubscribe path back into the same list. The link is a signed, single-purpose token (separate from the unsubscribe token) so an accidental unsubscribe is reversible without re-confirming via double-opt-in.
  • Editable copy for lifecycle pages. Every subscriber-facing page served by the newsletter controller — confirm-success, unsubscribe form + success, resubscribe form + success, invalid-token — now has editable heading / body / button-label slots in Newsletter settings. Blank slots fall through to the built-in defaults so editors can override only the strings they care about. The {listName} placeholder is substituted at render time.
  • Fix — emails referencing https://localhost. Logos, unsubscribe, preferences, open-pixel, and click-redirect URLs in dispatched campaigns now resolve to your public host. The background send worker has no HTTP context to derive a base URL from, so the public URL builder now falls back to Umbraco's WebRouting:UmbracoApplicationUrl configuration. Configure Umbraco:CMS:WebRouting:UmbracoApplicationUrl in appsettings.json for this to take effect — see Configuration.

1.1.11

  • Licensing. Licence validation now talks to the Datapad Licensing service (projects.datapad.nl). All purchase, support, and "manage your licence" links route through the customer portal at projects.datapad.nl/projects/campaigncanvas.
  • Hardening. The on-disk licence cache stores the raw signed envelope and verifies its Ed25519 signature on every load. Tampered cache files are discarded; legacy plaintext caches are migrated transparently.
  • Backoffice. Swept deprecated Umbraco backoffice APIs (auth.getLatestToken(), UmbPropertyValueChangeEvent) so the package stays compatible with upcoming Umbraco releases.

1.1.10

  • Fix. Custom Block Grid components in newsletters now render in the spot you placed them. The newsletter dispatcher sets a CampaignCanvas.IsNewsletterRender ViewData flag so host partials can emit table-row markup (<tr><td>…</td></tr>) for the email's outer table while keeping their normal page markup elsewhere. Previously, partials that emitted non-table HTML were hoisted out of the email's outer <table> by the browser and appeared above the email card.

1.1.9

  • Fix. Trial countdown now persists across app restarts and the 24-hour licence-cache refresh, so the banner correctly ticks down from 14 days instead of re-anchoring to "now" on every refresh.
  • Hardening. The persisted trial-state file is HMAC-signed, so manual edits to the start date are detected and the trial falls back to unlicensed instead of silently extending.