Hub Campaign landing pages
Audience: Engagement Hub operators who run paid ads or QR-based lead capture.
Goal: Create a campaign with a unique Hub URL and QR code, collect leads on a branded form, and either auto-start engagement or tag leads for later. Campaign data and API live in Engagement Hub. The same campaigns can be managed from CRM Campaigns (UI kept; driven by Hub) when CRM is linked.
Related: CRM campaigns (Person attribution), Ad campaigns → engagement, Engagement Hub Start API.
Where to configure
- Open Engagement Hub Admin.
- In the left navigation, open Campaigns (
/phone/campaigns). - Use the list to search and open a campaign, or click New campaign.
- On New campaign / Edit, configure the same fields as CRM Campaigns (source label, interest options, landing appearance, engagement type/channel/cockpit action, instruction).
- On the detail page, Activate when ready. Use Edit, Copy link, Pause, or Delete (delete only when there are zero submissions).
Create / edit fields (Hub Admin)
| Section | Fields |
|---|---|
| Basics | Campaign name, headline, description, source label (Person source; blank → campaign name) |
| Interest question | Optional dropdown; label shown to visitor, value stored as lead intent |
| Landing appearance | Submit button label, intent question label, primary accent color |
| Post-submit | Tag only or Auto-start engagement |
| AUTO_ENGAGE | Engagement type, channel (phone/SMS; email when informational), notify-instead-of-bridge (conversational SMS), cockpit action type, instruction |
Industry templates remain available from CRM → Campaigns → New. Hub Admin creates a blank campaign with the same field set.
The Hub campaign detail page matches the CRM Campaigns detail layout:
| Section | Contents |
|---|---|
| Overview | Status, Campaign ID, headline, description, source label, visits / submissions / unique leads, last lead/visit, created/updated |
| Leads | Hub lead submissions (name, email, phone, intent, source, updated) |
| Landing page | Landing URL, form labels, primary color, QR code + download |
| Lead capture | After-submit action, intent options, and AUTO_ENGAGE settings when configured |
You can also manage the same campaigns from Aventora CRM → Campaigns when the workspace is linked to Hub (AVENTORA_API_KEY + AVENTORA_BASE_URL). CRM GraphQL campaign operations proxy to Hub.
CRM-optional UI in Hub
When the account has active CRM sync (crm_sync_provider=aventora_crm with API key and base URL):
- Hub shows a CRM connected banner on the campaign detail page (between Overview and Leads)
- The Leads table includes a CRM Person column when a Person ID is available
- New submits upsert CRM People with
campaignId/leadIntent/ marketing consent - TAG_ONLY still emits
CAMPAIGN_LEAD_SUBMITTEDin Sales Cockpit
When CRM is not linked, that banner and CRM column are hidden. Landing pages, Overview metrics, Hub lead list, Landing page QR, and AUTO_ENGAGE still work.
Architecture
| Layer | Owner |
|---|---|
| Campaign config, tokens, visit/submit metrics, Hub lead rows | Engagement Hub |
| Public landing HTML | Hub /campaign/{token} |
| AUTO_ENGAGE | Hub Start engagement |
| Person upsert + CRM Leads table + Campaign Leads view + Cockpit signal | CRM (when linked), via authenticated POST /rest/aventora/campaign-leads (CRM detail Leads lists People by campaignId) |
| CRM Campaigns screens | Stay in CRM; read/write Hub |
Migrating existing CRM campaigns
Ops-triggered (not automatic on deploy). Migration is per Hub account and uses that account’s CRM sync settings (twenty_base_url + twenty_api_key from domain-chatbot account settings)—not the global Hub .env CRM URL/key.
# One account
python scripts/migrate_crm_campaigns_to_hub.py --dry-run --account-id <hub-account-uuid>
python scripts/migrate_crm_campaigns_to_hub.py --apply --account-id <hub-account-uuid>
# All accounts that have Aventora CRM sync configured
python scripts/migrate_crm_campaigns_to_hub.py --dry-run --all-linked
python scripts/migrate_crm_campaigns_to_hub.py --apply --all-linked
Migration preserves campaign id and publicToken so existing ads/QR and Person campaignId values keep working.
The script reads CRM via GET /rest/aventora/campaigns/local-export (local core.aventoraCampaign only). It must not use GraphQL aventoraCampaigns, which proxies to Hub after cutover and would report zero campaigns.
After validating Hub-only landing, set CRM AVENTORA_CAMPAIGNS_PUBLIC_DISABLED=true to retire CRM public REST. CRM Campaigns UI remains.
| Env | Purpose |
|---|---|
AVENTORA_CAMPAIGNS_USE_HUB | CRM server: when not false (default), Campaigns GraphQL proxies to Hub |
AVENTORA_CAMPAIGNS_PUBLIC_DISABLED | CRM server: when true, public /rest/aventora/campaigns/public/* returns 410 |
AVENTORA_PUBLIC_BASE_URL / PUBLIC_BASE_URL | Hub: preferred base for absolute landing URLs in API responses |
ENGAGEMENT_HUB_PUBLIC_URL, A_HUB_PUBLIC_URL, HUB_SERVER_URL, SERVER_URL, PUBLIC_URL, BASE_URL | Hub: fallbacks when campaign-specific public base is unset (same order) |
Without any of these, Hub returns a path-only landingUrl (/campaign/{token}). Admin and CRM UI absolutize that using the Hub base URL when possible; set a public Hub URL in production so Copy link / QR codes work for external sharing.
Connect campaign (auto-seeded business card)
When a Hub billing account is created (POST /accounts/register), Engagement Hub automatically creates and activates a campaign named Connect (presetKey: connect). It is a contact-collection business card:
| Setting | Default |
|---|---|
| Status | ACTIVE |
| Intent options | None (name + phone + marketing consent only) |
| Post-submit | AUTO_ENGAGE |
| Engagement | Informational SMS (SEND_FOLLOW_UP) thanking the visitor for joining the owner’s contact list |
| Landing copy | Personalized with the account owner display name when available |
The domain-chatbot welcome credentials email (sent after Hub register) includes the Connect landing URL and an embedded QR code when Hub returns them. Operators can edit or pause Connect later like any other campaign in Engagement Hub Admin → Campaigns or CRM → Campaigns.
Twilio SMS is not required to create or activate Connect. Until SMS is configured for the domain, the landing form still collects Hub leads; the thank-you SMS starts when outbound SMS is available.
Backfill existing accounts
Ops-triggered (idempotent; skips accounts that already have preset_key = connect). Does not send emails.
python scripts/backfill_connect_campaigns.py --dry-run
python scripts/backfill_connect_campaigns.py --apply
python scripts/backfill_connect_campaigns.py --apply --account-id <hub-account-uuid>
Requires Hub DATABASE_URL. Run from the Engagement Hub (Aventora-Assistant) deployment package.
Changelog
| Date | Change |
|---|---|
| 2026-07-22 | Connect campaign auto-seeded ACTIVE on Hub account create; welcome email includes landing URL + QR; ops backfill script for existing accounts. |
| 2026-07-21 | Absolute campaign landing URLs: Hub falls back through standard public Hub URL envs; Admin/CRM absolutize path-only landingUrl when needed. |
| 2026-07-21 | Hub Admin create/edit aligned with CRM: source label, interest options, landing appearance, engagement type/channel/cockpit action, notify-instead-of-bridge. |
| 2026-07-19 | CRM campaign detail Leads lists People by campaignId (not Hub submission rows), so pre-migration attributed leads still appear. |
| 2026-07-19 | Hub Admin campaign detail aligned with CRM: Overview, Leads, Landing page (QR), Lead capture; Hub-only CRM banner when linked. |
| 2026-07-19 | Migration reads CRM via GET /rest/aventora/campaigns/local-export (not GraphQL) so Hub proxy does not return empty lists. |
| 2026-07-19 | Hub owns campaign data/API; Hub Admin Campaigns UI; CRM UI proxies to Hub; optional CRM lead sync; ops migration script. |