HubSpot leads sync — what flows
Last updated: May 19, 2026
HubSpot leads sync — what flows
Wevion lead captures (from ad campaigns) sync to HubSpot Contacts in real time via an outbox + queue pattern. Attribution data (source campaign, UTM, first/last touch) lands in wevion_* custom properties. Ad-clicks and conversions logged in the HubSpot contact timeline via event sink. Bulk historical sync via reverse ETL.
Who is this for
Admins setting up HubSpot integration, anyone wondering "why is my Wevion lead not in HubSpot yet" or "what attribution data does HubSpot get".
The lead-to-HubSpot pipeline
1. User clicks ad on Meta/Google/TikTok
↓
2. Lands on landing page → fills lead form
↓
3. Wevion pixel/CAPI fires Lead event (browser + server)
↓
4. Wevion creates lead record in DB
↓
5. Outbox table queues HubSpot sync (apps/backend/src/services/hubspot-outbox.service.ts)
↓
6. SQS worker (apps/backend/src/sqs/workers/sync/hubspot-sync.worker.ts) processes
↓
7. HubSpot Contacts API → Contact created or updated
↓
8. Event sink (apps/backend/src/services/event-sinks/hubspot-event-sink.service.ts)
logs ad-click + conversion to HubSpot timeline
↓
9. HubSpot Contact visible in HubSpot CRM with full attribution
Typical end-to-end latency: < 60 seconds.
Default property mapping
Wevion auto-maps these fields:
Wevion lead field | HubSpot Contact property | HubSpot type |
|---|---|---|
| Standard | |
First name |
| Standard |
Last name |
| Standard |
Phone |
| Standard |
Company (if B2B) |
| Standard |
Source platform |
| Single-line text |
Source campaign |
| Single-line text |
Source ad set |
| Single-line text |
Source ad |
| Single-line text |
UTM source |
| Single-line text |
UTM medium |
| Single-line text |
UTM campaign |
| Single-line text |
First touch timestamp |
| DateTime |
Last touch timestamp |
| DateTime |
Lead score (if set) |
| Number |
You can map additional Wevion custom fields to HubSpot properties via /connect/hubspot → Property mapping → Add custom mapping.
The wevion_* prefix
All Wevion-created HubSpot properties use the wevion_* prefix. This:
Avoids collision with HubSpot default properties
Avoids collision with other integrations (Marketo, Salesforce sync, etc.)
Provides clear ownership / audit trail
Allows safe deletion (filter by prefix to clean up)
Important: post-PR #588 rebrand (April 2026), all properties moved from adrow_* to wevion_*. If you have old adrow_* properties:
They're kept for backward compatibility
Wevion writes to
wevion_*going forwardMigrate (via support) when you're ready: backfill
wevion_*fromadrow_*, then archiveadrow_*properties
Custom property setup
For custom fields not in the default map:
Step 1: Create the property in HubSpot
HubSpot Settings → Properties → Create property
Object: Contact (most common)
Group: pick existing group or create "Wevion" group
Type: match Wevion's data type (text, number, datetime, etc.)
Internal name:
wevion_my_custom_field(use the wevion_ prefix)
Step 2: Map in Wevion
/connect/hubspot → Property mapping → AddWevion field: pick from dropdown
HubSpot property: pick the new property you created
Save
Step 3: Sync going forward
New leads include the custom field; existing contacts updated via reverse ETL if you trigger backfill.
Reverse ETL (bulk historical sync)
For initial population or recovery:
/connect/hubspot → Reverse ETLpanelPick date range (e.g. last 12 months)
Pick properties to include (default: all mapped)
Click Start backfill
Service:
apps/backend/src/services/hubspot-reverse-etl.service.tsBulk-writes to HubSpot with rate-limit awareness (chunked to avoid HubSpot's 100 req/10s limit)
Use cases:
Just connected HubSpot — backfill all historical leads
New custom property mapping — backfill to populate for existing contacts
Post-rebrand
adrow_*→wevion_*migration
Event timeline integration
Wevion-tracked events appear on the HubSpot contact's timeline:
Wevion event | Timeline entry |
|---|---|
Ad clicked | "Clicked ad: [Campaign Name] on [Platform]" |
Landing page viewed | "Viewed: [Page URL]" |
Lead captured | "Submitted form: [Form/Page]" |
Conversion (e.g. Purchase) | "Converted: [Event Name] - [Value]" |
Email opened (if marketing email integration on) | "Opened: [Email Subject]" |
Implemented via apps/backend/src/services/event-sinks/hubspot-event-sink.service.ts.
This gives HubSpot users a unified view of the user's full ad journey + offline activity, useful for sales follow-up + lead scoring.
Bidirectional sync (limited)
Currently Wevion-side syncs:
Deal stage updates (HubSpot → Wevion): when a deal stage changes in HubSpot (e.g. Qualified → Won), Wevion can update lead status + attribution for closed-loop reporting
Configure at
/connect/hubspot → Bidirectional sync
Future bidirectional features on roadmap (contact activity sync, deal value sync).
Rate limiting + throttling
HubSpot enforces 100 requests / 10 seconds per OAuth app. Wevion:
Queues writes via outbox pattern (decouples lead capture from sync)
Batches when possible (HubSpot batch API for bulk contact create/update)
Auto-throttles to stay under limits
Retries on transient errors with exponential backoff
You shouldn't hit rate limits in normal use. Heavy lead volumes (10k+/day): contact support for elevated quota arrangement with HubSpot.
What you'll see
Healthy sync:
/connect/hubspotshows last sync timestamp recentOutbox queue (admin view) low / zero (events flushed quickly)
HubSpot Contacts show recent Wevion-sourced contacts with
wevion_*properties populatedTimeline entries appearing on contacts within minutes of ad events
Common issues
Lead in Wevion but not in HubSpot after 5 min: check outbox queue (admin view) for stuck events. Check connector card for errors.
Property mapping not working: HubSpot property doesn't exist (must create in HubSpot first) or wrong data type. Verify HubSpot Settings → Properties.
Duplicate contacts in HubSpot: same email created twice — HubSpot's dedup didn't match. Check HubSpot Contacts → Settings → Duplicate management.
Timeline events not appearing: event sink may need re-init. Contact support to verify.
Reverse ETL stuck: large batch (100k+ contacts). Patience; if > 24h contact support.
Legacy
adrow_*properties still being written: shouldn't happen post-rebrand. Verify Wevion version + contact support if observed.
Related
Connect HubSpot — initial setup
Integrations overview — full integration catalog
Data and sync troubleshooting — generic sync issues