HubSpot Integration

Sync your HubSpot CRM contacts and companies with Propstreet automatically.

Overview

Feature Support
Market Global (Nordic-wide)
Sync Direction Bidirectional
Real-time Updates Yes (customer-managed sync)
Contacts ✅ Full support
Companies ✅ Full support
Projects ✅ Full support (v1.2.0)
Prospects ✅ Full support (v1.2.0)
Properties ⚠️ API available (v1.3.0)

Data Mapping

Contact Fields

HubSpot Propstreet Notes
First Name First Name
Last Name Last Name
Email Email Primary email synced
Phone / Mobile Phone Mobile preferred
Job Title Job Title Synced to company connection
Company Connection Links contact to company
Lifecycle Stage Tags Mapped as tag (e.g., "customer")
Avatar Profile Picture See profile picture section below

Note: HubSpot supports additional emails. We sync the primary email to Propstreet's email field.

Company Fields

HubSpot Propstreet Notes
Company Name Name
Website URL Homepage URL Full URL synced
Domain Domain Set directly or auto-extracted from URL
Country Country Code ISO 2-letter code
Organization Number External Reference Custom property setup
Company Logo Profile Picture See profile picture section below

How Sync Works

HubSpot → Propstreet

You control the sync through your own integration layer:

  1. Configure HubSpot to send webhooks to your middleware (e.g., Zapier, Make, Azure Logic Apps, or custom service)
  2. Your middleware transforms and pushes data to Propstreet via our API
  3. Records are matched using email or company domain and created/updated in Propstreet

This gives you full control over sync timing, filtering, and data transformation.

Propstreet → HubSpot

When you update a contact in Propstreet, you have two options:

Option A: Webhooks (Recommended)

  1. Register a Propstreet webhook for contact.* and company.* events
  2. Propstreet pushes changes to your endpoint in real-time
  3. Your middleware transforms and pushes to HubSpot

Option B: Polling

  1. Your integration layer polls the Propstreet API for changes (using updated_since)
  2. Changes are transformed and pushed to HubSpot via their API
  3. Your HubSpot records stay in sync

Webhooks provide near real-time sync without polling overhead.

Duplicate Handling

We use smart matching to prevent duplicates:

  • Contacts: Matched by email address first, then HubSpot record ID
  • Companies: Matched by domain, then organization number (if configured)

If we detect a potential duplicate, we update the existing record rather than creating a new one.

Field Considerations

Multiple Emails

HubSpot supports additional email addresses per contact. Propstreet syncs the primary email only; additional emails remain in HubSpot but are not synced.

Phone Numbers

HubSpot has separate fields for phone and mobile phone. We prefer the mobile number for Propstreet; if mobile is empty, we use the main phone number.

Job Title and Company

HubSpot stores job title directly on the contact record. In Propstreet, job title is part of the company connection. When syncing:

  • The contact's job title maps to their primary company connection in Propstreet
  • If a contact is associated with multiple companies in HubSpot, the primary association is used

Lifecycle Stage

HubSpot's lifecycle stages (subscriber, lead, customer, etc.) are mapped to Propstreet tags. For example, a "Customer" lifecycle stage becomes a lifecycle-customer tag.

Website URL and Domain

HubSpot has two related company properties:

  • Website URL (website) - The full URL (e.g., https://www.acme.com/about)
  • Company Domain Name (domain) - The root domain only (e.g., acme.com)

Propstreet mirrors this pattern:

  • Homepage URL (homepageUrl) - Maps to HubSpot's Website URL
  • Domain (domain) - Can be set directly or auto-extracted from Homepage URL

When syncing HubSpot → Propstreet:

  • If HubSpot has website, use it for homepageUrl - domain is auto-extracted
  • If HubSpot only has domain (no website), set Propstreet's domain field directly
  • When both are provided in the same request, homepageUrl takes precedence for domain derivation

When syncing Propstreet → HubSpot, set HubSpot's website property with the full homepageUrl. HubSpot will auto-populate its domain property from this.

Profile Pictures

Contact avatars:

  • HubSpot auto-populates contact avatars from social media (via FullContact) and Gravatar
  • Manually uploaded avatars are accessible via hs_avatar_filemanager_key
  • HubSpot does not support setting contact avatars via API
  • Recommendation: Sync Propstreet → HubSpot only for profile pictures uploaded through Propstreet's UI

Company logos:

  • HubSpot stores company logos but API support is limited
  • Company logos cannot be reliably set via API
  • Recommendation: Manage company logos directly in each system

Note: Due to HubSpot API limitations, profile picture sync is one-way (Propstreet → your display layer) or manual.

Organization Number (Nordic)

HubSpot doesn't have a built-in organization number field. For Nordic markets, create a custom property in HubSpot to store:

  • Norway: Organisasjonsnummer
  • Sweden: Organisationsnummer
  • Denmark: CVR-nummer
  • Finland: Y-tunnus

This enables accurate company matching via Propstreet's externalRefs field.

Setup Requirements

To build a HubSpot integration, you'll need:

  1. HubSpot Account - Professional or Enterprise tier recommended for webhook support
  2. Propstreet API Credentials - Generate in your account settings
  3. Integration Layer - Middleware to handle webhooks and API calls (Zapier, Make, Azure Logic Apps, n8n, or custom)
  4. HubSpot Custom Properties - Create any additional fields you need (e.g., organization number)

Getting Started

  1. Generate Propstreet API credentials in your account settings (requires login)
  2. Review the Propstreet API documentation for endpoints and data models
  3. Set up your integration layer to sync data between HubSpot and Propstreet
  4. Create any custom properties needed in HubSpot
  5. Test with a small dataset before full rollout

You're responsible for building and maintaining the integration.

Frequently Asked Questions

Which HubSpot plans support the integration?

The integration works with all HubSpot plans. However, HubSpot webhook support (for real-time sync to your middleware) requires Professional or Enterprise tier.

How often does data sync?

Sync frequency depends on how you configure your integration layer:

  • Real-time: Use HubSpot webhooks (Pro/Enterprise) to trigger immediate syncs
  • Scheduled: Poll both APIs on a schedule (e.g., every 15 minutes, hourly)
  • Manual: Trigger syncs on-demand

What happens to data if I stop syncing?

Your data remains in both systems. No data is deleted. Use externalRefs to maintain record linkage if you resume syncing later.

Can I choose which contacts to sync?

Yes. Your integration layer controls which records to sync. Common filtering approaches:

  • HubSpot lists or segments
  • Contact properties (e.g., only sync contacts with certain tags)
  • Company associations

How should I handle merge conflicts?

Design your integration layer to handle conflicts. Common approaches:

  • Last write wins: Use timestamps to determine the most recent change
  • Source of truth: Designate one system as authoritative for specific fields
  • Manual review: Flag conflicts for human review

Projects & Prospects (v1.2.0)

Sync real estate deals between HubSpot Deals and Propstreet Projects. Track investor prospects through your pipeline with bidirectional classification sync.

Deal to Project Mapping

HubSpot Deal Propstreet Project Notes
hs_object_id externalRefs namespace: "hubspot"
dealname name Direct mapping
dealstage status Map to pipeline stages (see below)
pipeline Use to filter which deals to sync
(custom) is_portfolio isPortfolio Create custom boolean property
(custom) property_count propertyCount Create custom number property
createdate createdUtc Read-only in Propstreet
hs_lastmodifieddate updatedUtc For delta sync

Deal-Contact Associations to Prospect Mapping

HubSpot Association Propstreet Prospect Notes
Deal-Contact link contactId Via Contact external ref lookup
Deal-Company link companyId Alternative for company prospects
Association label classification Use custom labels (see below)

Stage Mapping

Propstreet uses three separate fields for project state. Map HubSpot deal stages to the appropriate combination:

HubSpot Stage (example) status classification teaser.stage Notes
Draft open draft Initial deal setup
Marketing open active published Deal being marketed
Under Review open active communicated Teaser sent to investors
LOI Submitted open active communicated Active negotiations
Due Diligence open active communicated Deep investor engagement
Closed Won closed Deal completed
Closed Lost deleted Deal fell through
  • status: Lifecycle state (open, closed, deleted) — read-only, set by system
  • classification: Work stage (draft, active, inactive) — settable via API
  • teaser.stage: Teaser progress (property_added, drafting, published, verified, communicated) — read-only, set by system

Custom Association Labels for Classifications

Create custom association labels in HubSpot to track prospect classifications:

# Create custom label for Deal-Contact associations
POST /crm/v4/associations/deal/contact/labels
{
  "label": "Interested Investor",
  "name": "interested_investor"
}
Propstreet Classification Suggested HubSpot Label
not_contacted "Not Contacted"
contacted "Contacted"
interested "Interested Investor"
not_interested "Not Interested"
bidder "Bidder"

Custom Properties to Create

Create these custom properties in HubSpot for real estate deal sync:

POST /crm/v3/properties/deals
{
  "name": "propstreet_project_id",
  "label": "Propstreet Project ID",
  "type": "string",
  "fieldType": "text",
  "groupName": "dealinformation"
}

Recommended properties:

  • propstreet_project_id — For reverse lookup
  • is_portfolio — Boolean for multi-property deals
  • property_count — Number of properties
  • property_type — Office, Retail, Industrial, etc.

Sync Architecture

HubSpot → Propstreet (using Webhooks):

  1. Create a HubSpot private app with crm.objects.deals.read scope
  2. Subscribe to deal.creation, deal.propertyChange, deal.deletion events
  3. Transform and push to Propstreet Projects API
  4. Store Propstreet IDs in custom properties
// Handle HubSpot webhook
async function handleHubSpotWebhook(payload) {
  const { objectId, propertyName, propertyValue } = payload;

  if (payload.subscriptionType === "deal.creation") {
    const deal = await hubspot.get(`/crm/v3/objects/deals/${objectId}`);
    const project = await propstreet.post("/api/v1/projects", {
      name: deal.properties.dealname,
      externalRefs: [{ namespace: "hubspot", id: String(objectId) }],
    });
    // Store Propstreet ID in HubSpot
    await hubspot.patch(`/crm/v3/objects/deals/${objectId}`, {
      properties: { propstreet_project_id: project.id },
    });
  }
}

Propstreet → HubSpot (using Webhooks):

  1. Register webhooks for project.* and prospect.* events
  2. Look up HubSpot Deal ID from externalRefs
  3. Update HubSpot via CRM API
// Handle Propstreet webhook
async function handlePropstreetWebhook(payload) {
  const hubspotId = payload.data.externalRefs?.find(
    (ref) => ref.namespace === "hubspot"
  )?.id;

  if (payload.event === "project.updated" && hubspotId) {
    await hubspot.patch(`/crm/v3/objects/deals/${hubspotId}`, {
      properties: { dealname: payload.data.name },
    });
  }
}

Webhook Events

Subscribe to these Propstreet events for deal sync:

Event Description HubSpot Action
project.created New project created Create Deal
project.updated Project fields modified Update Deal properties
project.deleted Project soft-deleted Move to Closed Lost stage
prospect.created Investor added to prospect list Create Deal-Contact association
prospect.updated Classification changed Update association label
prospect.deleted Investor deleted from prospect list Remove Deal-Contact association

Example: Create Project with HubSpot Reference

curl -X POST "https://app.propstreet.com/api/v1/projects" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nordic Office Portfolio",
    "isPortfolio": true,
    "propertyCount": 3,
    "externalRefs": [{ "namespace": "hubspot", "id": "12345678" }]
  }'

Example: Lookup Project by HubSpot ID

curl "https://app.propstreet.com/api/v1/projects/external/hubspot/12345678" \
  -H "Authorization: Bearer $TOKEN"

Batch Operations

Both platforms support batch operations for efficient sync:

Propstreet: Add up to 100 prospects in a single request:

POST /api/v1/projects/{id}/prospects:batch

HubSpot: Create up to 100 associations per request:

POST /crm/v4/associations/deal/contact/batch/create

API References