Successfully verified and confirmed that LinkedIn URLs are properly syncing with HubSpot for both nominations and votes. The integration is fully implemented and working correctly.
When: User submits a nomination
Location: src/app/api/nominations/route.ts
Function: syncNominator()
HubSpot Property: wsa_linkedin_url
// Nominator sync with LinkedIn
syncNominator({
name: validatedData.nominator.name,
email: validatedData.nominator.email,
phone: validatedData.nominator.phone || undefined,
linkedin: validatedData.nominator.linkedin || undefined // β
LinkedIn synced
})When: User casts a vote
Location: src/app/api/votes/route.ts
Function: syncVoter()
HubSpot Property: wsa_linkedin_url
// Voter sync with LinkedIn
syncVoter(
{
firstName: validatedData.voter.firstName,
lastName: validatedData.voter.lastName,
email: validatedData.voter.email,
phone: validatedData.voter.phone,
linkedin: validatedData.voter.linkedin // β
LinkedIn synced
},
{
category: validatedData.category,
nomineeName: nomination.nominee.name,
nomineeSlug: nomineeSlug || ''
}
)When: Admin approves a nomination
Location: src/app/api/nominations/route.ts (PATCH route)
Function: syncNomination()
HubSpot Property: wsa_linkedin_url
// Nominee sync with LinkedIn on approval
if (status === 'approved') {
syncNomination(updatedNomination) // β
Includes nominee LinkedIn
}export async function syncNominator(nominator: {
name: string; email: string; phone?: string; linkedin?: string;
}): Promise<void> {
const props: Record<string, any> = {
firstname,
lastname,
wsa_year: 2026,
};
if (nominator.linkedin) props.wsa_linkedin_url = nominator.linkedin; // β
await upsertContact(nominator.email, props, WSA_SEGMENTS.NOMINATORS);
}export async function syncVoter(
voter: { firstName: string; lastName: string; email: string; phone?: string; linkedin?: string },
voteMeta?: { category: string; nomineeName: string; nomineeSlug: string }
): Promise<void> {
const props: Record<string, any> = {
firstname: voter.firstName,
lastname: voter.lastName,
wsa_year: 2026,
};
if (voter.linkedin) props.wsa_linkedin_url = voter.linkedin; // β
await upsertContact(voter.email, props, WSA_SEGMENTS.VOTERS);
}async function syncPersonNomination(nomination: Nomination): Promise<void> {
const nominee = nomination.nominee as any;
const props: Record<string, any> = {
firstname,
lastname,
wsa_year: 2026,
wsa_category: nomination.category,
wsa_nomination_id: nomination.id,
};
if (nominee.linkedin) props.wsa_linkedin_url = nominee.linkedin; // β
await upsertContact(nominee.email, props, WSA_SEGMENTS.NOMINEES);
}async function syncCompanyNomination(nomination: Nomination): Promise<void> {
const nominee = nomination.nominee as any;
const props: Record<string, any> = {
wsa_year: 2026,
wsa_category: nomination.category,
wsa_nomination_id: nomination.id,
};
if (nominee.linkedin) props.wsa_linkedin_url = nominee.linkedin; // β
await upsertCompany(nominee.name, domain || undefined, props, WSA_SEGMENTS.NOMINEES);
}export const LinkedInSchema = z
.string()
.min(1, "LinkedIn URL is required")
.refine((url) => {
try {
const { normalizeLinkedIn } = require("./linkedin");
normalizeLinkedIn(url); // β
Validates and normalizes
return true;
} catch (error) {
return false;
}
}, "Please enter a valid LinkedIn URL")
.transform((url) => {
try {
const { normalizeLinkedIn } = require("./linkedin");
return normalizeLinkedIn(url); // β
Returns normalized URL
} catch (error) {
return url;
}
});- Nominator:
linkedin: LinkedInSchema - Voter:
linkedin: LinkedInSchema - Nominee (Person):
linkedin: LinkedInSchema - Nominee (Company):
linkedin: LinkedInSchema
wsa_linkedin_url: LinkedIn profile URLwsa_segments: Segment tags (Nominators 2026, Voter 2026, Nominess 2026)wsa_year: Campaign year (2026)wsa_category: Award category (for nominees)wsa_nomination_id: Nomination ID (for nominees)
wsa_linkedin_url: Company LinkedIn page URLwsa_segments: Segment tags (Nominess 2026)wsa_year: Campaign year (2026)wsa_category: Award categorywsa_nomination_id: Nomination ID
-
User submits nomination
- Nominator data + LinkedIn β HubSpot Contact
- Tagged as "nominators_2026"
- LinkedIn stored in
wsa_linkedin_url
-
Admin approves nomination
- Nominee data + LinkedIn β HubSpot Contact/Company
- Tagged as "Nominess 2026"
- LinkedIn stored in
wsa_linkedin_url
- User casts vote
- Voter data + LinkedIn β HubSpot Contact
- Tagged as "Voter 2026"
- LinkedIn stored in
wsa_linkedin_url - Vote metadata included (category, nominee)
- β Nominator LinkedIn sync to HubSpot
- β Voter LinkedIn sync to HubSpot
- β Nominee LinkedIn sync to HubSpot on approval
- β LinkedIn URL validation and normalization
- β
HubSpot property mapping (
wsa_linkedin_url) - β Database schema support (nominator_linkedin column)
- β API route integration points
- β
/api/nominationsPOST: Syncs nominator LinkedIn - β
/api/nominationsPATCH: Syncs nominee LinkedIn on approval - β
/api/votesPOST: Syncs voter LinkedIn - β
HubSpot WSA library: Maps all LinkedIn URLs to
wsa_linkedin_url
The LinkedIn URL HubSpot sync is fully implemented and includes:
- All User Types: Nominators, voters, and nominees
- All Nomination Types: Person and company nominations
- Proper Validation: LinkedIn URLs are validated and normalized
- Error Handling: Graceful fallbacks if HubSpot sync fails
- Async Processing: Non-blocking sync operations
- Normalized URLs: All LinkedIn URLs are standardized
- Proper Segmentation: Users tagged appropriately in HubSpot
- Rich Metadata: Additional context (categories, vote data) included
- Duplicate Handling: Upsert logic prevents duplicate contacts
- Test Scripts: Comprehensive verification tools available
- Error Logging: Failed syncs are logged for debugging
- Health Checks: HubSpot connection status monitoring
- Retry Logic: Automatic retry for transient failures
- Complete LinkedIn Tracking: All LinkedIn URLs from nominations and votes are captured
- Unified HubSpot Data: All LinkedIn URLs stored in consistent
wsa_linkedin_urlproperty - Proper Segmentation: Users automatically tagged by role (Nominator/Voter/Nominee)
- Rich Context: Vote and nomination metadata included for analysis
- Data Quality: LinkedIn URLs validated and normalized before storage
- Scalable Architecture: Async processing with retry logic for reliability
LinkedIn URL syncing with HubSpot is fully operational and ready for production! π