Skip to main content
Changelog

Every week, we ship.
Here's what.

Velora Marketing is built in the open. Every notable change — feature, fix, infrastructure tweak, design refinement — lands here within a week of merge. Subscribe via RSS or check back Mondays.

April 2026

Honest copy sweep + AI rate-limit + .env.example refresh

An out-of-band internal audit flagged that some marketing copy ran ahead of the code — specifically the OAuth claim for HubSpot/Salesforce (we accept pasted access tokens today; OAuth callback is on the roadmap) and the LinkedIn claim (the dispatcher returns skippedDispatch — the integration is in flight). The honest fix is to match the copy to the code, which is what shipped today.

Two backstop fixes also landed: (1) rate-limit middleware on /api/ai/* so a single user can't drain the AI budget, with a 60-call-per-minute per-user cap; (2) .env.example now lists every key actually consumed in the codebase, so a fresh clone gets a complete dev-environment template instead of guessing.

  • /integrations/{hubspot,salesforce,linkedin} copy now matches code reality (paste-token + in-flight LinkedIn)
  • Rate-limit on /api/ai/* — 60/min/user, 503 when over
  • .env.example expanded with all consumed env vars
  • DEMO_NOTICE admin pages get a persistent in-page banner

Trust + SEO + GEO surface — glossary, customers, resources, DSAR, RSS

A six-route grind closed the trust + SEO + GEO surface gaps. /glossary ships 50 plain-English benefits + outbound + brokerage terms (SBC, SPD, RFP, Form 5500, TCPA, ICHRA, etc.) with Schema.org DefinedTermSet for AI-search citation. /customers ships an empty-but-honest case-study template with status (3 pilots in flight, 0 signed off) and the editorial standards we'll hold every future story to. /resources lists 4 lead-magnet drafts in honest in-flight state — no fake-gated PDFs.

Privacy compliance closed too: /privacy now renders a real DSAR submission form posting to /api/dsar with 30-day-deadline computation and privacy@ + Slack notify on submit. /changelog/feed.xml is now a real RSS 2.0 feed (the link in the changelog hero used to 404). Three new /vs/{salesloft,lemlist,smartlead} entries drop into the existing template, bringing total competitor-comparison surface to 6.

  • /glossary — 50 broker terms + DefinedTermSet JSON-LD
  • /customers — anatomy template + editorial standards (no fabricated content)
  • /resources — 4 lead-magnet drafts (5500 cheat sheet, TCPA matrix, broker outbound playbook, RFP template)
  • /privacy — real DSAR submission form (Tier 4 #13 closed)
  • /changelog/feed.xml — RSS 2.0 with proper escaping + RFC 822 dates
  • /vs/{salesloft,lemlist,smartlead} — 3 more competitor versus pages

Persona landers + FAQ + author E-E-A-T page

Three ICP-shaped landing pages keyed on book size — /for/solo (under 25 groups), /for/agency (25–100), /for/enterprise (100+) — each running the same product through that persona's job-to-be-done lens. Single shared route layout driven by a PERSONAS record, generateStaticParams emits all three slugs.

/faq shipped with 35 questions across 7 categories and FAQPage JSON-LD for AI-search citation. /authors/josh-parise shipped with Person JSON-LD plus a written editorial-standards declaration — the E-E-A-T satisfaction we owe readers on YMYL benefits content. Sitemap, nav, and footer all wired to surface the new routes.

  • /for/{solo,agency,enterprise} — 3 personas, 1 shared layout, single CTA each
  • /faq — 35 Qs, 7 categories, FAQPage JSON-LD
  • /authors/josh-parise — Person JSON-LD + editorial standards
  • Top-line nav swaps the dead #tiles anchor for /for + adds FAQ
  • Build-fix on twitter-image (Turbopack route-segment-config) — npm run build was broken on main

Marketing surface + competitive gap pass

A 7-route grind closed the worst of the marketing-surface gaps benchmarked against HubSpot, Apollo, Outreach, Clay, Linear, Vercel, Attio, AgencyZoom, and Zywave. Real /security trust surface (encryption + access + audit + compliance posture in Shipped/In-flight/Planned bands; 7-vendor sub-processor table). Public /changelog with 12 backfill entries (this is one of them). Three competitor /vs pages (Apollo, AgencyZoom, Zywave) sharing one template — each with a 600-word body and a 17-row feature matrix and a 5-question FAQ feeding FAQPage JSON-LD.

Pipeline ROI calculator shipped as both a section on the home page and a standalone /calculator route. /integrations index + 9 detail pages (Atlas, HubSpot, Salesforce, Twilio, Retell, Resend, Slybroadcast, Vercel Blob, AI Engine) with real data-flow diagrams and setup steps. /blog rebuilt from a stale 5-post placeholder to an honest 'drafts queued up' state. Every dead #demo anchor (which only resolved on /) replaced with /contact across nav + pricing + platform pages + SBC showcase.

  • Net 17 new SEO surfaces in one round
  • FAQPage JSON-LD live on /vs and on the home pricing FAQ
  • Pipeline ROI calculator — 4 sliders, 3 outputs, calibrated against Q1 2026 pilot data
  • All commits pushed to main

Multi-tenant requireAgency() migration across 31 routes

Every authenticated route now resolves the agency through a single helper instead of reading the user header directly. Solo brokers fall back to their userId; invited teammates resolve through users.agencyId, so they see the same data the agency owner created.

Five core CRM tables — companies, deals, activities, notes, clients — gained agency_id columns with composite indexes. Templates and playbooks rebuilt their visibility filter so user-created rows are always agency-owned (the previous fallback path silently leaked them between tenants). The AI parse-sbc PATCH was tightened too — it used to fall back to a cross-tenant query when the auth header was missing.

  • 31 routes migrated across six commits
  • 5 schema tables extended with composite (agency_id, …) indexes
  • New /api/backfill/crm-agency-id endpoint covers all 5 tables idempotently
  • Tests held at 613/613 throughout the migration

Multi-user invitations with auto-promote

Solo brokers can now invite teammates from /admin/team. The first invite auto-promotes them to agency owner (sets users.agencyId = users.id), the public /accept-invite/[token] page collects the new user's name and password, and they're auto-signed-in to the same agency context.

Branded Resend email, idempotent invite endpoint, revoke flow, and pending-invite list. Honest scope caveat baked into the UI: full data sharing across teammates depends on each route adopting requireAgency() — that was the immediate follow-up shipped above.

Vercel Blob direct upload for voice-drop audio

The voice-drop audio library can now accept direct uploads instead of pasted URLs. POST /api/voice-audios/upload validates audio MIME (mp3/wav/ogg/m4a), enforces a 10MB cap, and stores files at agency/{agencyId}/audios/{id}-{filename}.

When BLOB_READ_WRITE_TOKEN isn't configured, the endpoint returns 503 with a hint and the UI auto-switches to the URL-paste tab with a toast. Old workflow keeps working — new workflow unblocks brokers without a CDN.

CSV export on /admin/contacts

Export button next to Bulk Import. Downloads the currently filtered list as contacts-YYYY-MM-DD.csv with headers that match the import shape — round-trip safe.

RFC 4180 cell escaping. Quoted-field aware. No loss on commas, quotes, or newlines inside cell content.

Census-to-contact linking

census_members rows now carry a linkedBrokerId FK that batch-matches employees to brokers at the same company at import time. The /admin/contacts/[id] overview surfaces a 'Census memberships (N)' card with one entry per linked group.

Backfill endpoint /api/census/backfill-broker-links runs the same join over existing rows. Single SQL UPDATE; idempotent; tenant-scoped.

Slack + email notifications on hot signals

Three signal paths now fire to both Slack and email when configured: ready_to_meet replies, deal-risk scores ≥ 70, and renewals at T-60 days. SLACK_WEBHOOK_URL and NOTIFY_EMAIL_TO are env-gated; unset = no-op.

Promise.allSettled wires both channels in parallel so a Slack outage doesn't drop the email and vice versa. Branded HTML email body with tone-colored stripe and HTML escape.

SBC parser bulk upload + per-field confidence + manual override

The SBC parser now accepts multiple PDFs at once, processes them sequentially with a queue UI showing per-file status, and asks the AI engine for a per-field confidence score (0–100) on every extracted value. Fields under 70 surface in a verification banner.

Click any extracted field to inline-edit. Numeric inputs parse dollars/percent into cents/bps automatically. Every override is recorded in fieldSources.__brokerOverrides as an audit trail — the AI's original citation is preserved alongside the manual fix.

Phase-2 measurement layer — full data architecture

Five new tables shipped with full CRUD + UI: marketing_costs (channel + kind + spend), attributions (per-deal touch lists with all 5 attribution models pre-computed), survey_responses (brand + customer + CSAT + cohort pulse), cost_allocations (versioned non-direct cost rules with auto-split), and account_landing_pages (1:1 + 1:Few ABM with published gating).

Live signal aggregation now powers /admin/abm/account-engagement: real signals from companies, brokers, lead_scores, activities, and events run through scoreAccount() and surface ranked. Full library integration — published landing pages from the DB shadow hardcoded samples and add to sitemap automatically.

Carrier Disruption Radar + Form 5500 Signal Engine UI

The two flagship moats now have admin pages. Disruption Radar surfaces carriers about to lose appointments based on rate-filing + network-MRF deltas. Signal Engine ranks Form 5500 events (BOR changes, premium jumps, carrier switches, late filings) by playbook-trigger eligibility.

Both are wired to the renewal-locked cadence engine — a flagged signal can fan out into a multi-step playbook automatically. No other broker outbound tool ships these because no other tool also operates the network-data infrastructure.

Atlas → Velora Marketing rebrand + standalone product

Velora Marketing is now positioned as a standalone product: outbound engine for benefit brokers, bolts onto Atlas / HubSpot / Salesforce or runs alone. Three pricing tiers shaped to research-backed positioning — contact us for pricing.

Full-site rebrand sweep: /admin chrome, marketing pages, email signatures, sitemap, OG image, all email-from addresses. The compare table refreshed against AgencyZoom (Vertafore), NextAgency, Zywave, and Apollo.

SBC PDF parser — closes the #1 competitive gap

Brokers spend ~45 minutes per plan transcribing carrier SBC documents into spreadsheets. The new /admin/sbc-parser ingests PDFs directly, extracts 22 plan-design fields with per-field source-page citations, and lets brokers verify before saving.

Native AI PDF support (no extra chunking step), plan_designs table with jsonb fieldSources for transparent AI, side-by-side compare view at /admin/sbc-parser/compare?ids=a,b,c with greenest-cell-wins highlighting and copy-as-markdown.

Auth + tenancy hardening

Login per-email lockout (5 fails / 15 min) + per-IP rate limit. Production session cookies use the __Host- prefix. /api/seed gated behind a dedicated SEED_TOKEN — no more ADMIN_PASSWORD fallback. Retell webhook now verifies HMAC-SHA256 signatures.

Killed all four agencyId='default' tenant-bleed fallbacks (now fail-closed). Database transactions (via neon-serverless WebSocket driver) wrap enrollment+steps, renewals trigger, onboarding clones, and lead-score upserts.