Platforms

HubSpot

Connect a HubSpot portal so inbox contacts become HubSpot contacts, messages land on their timelines and closed-won deals reach your ad platforms.

Link a HubSpot portal to a profile, and the profile's inbox flows into your CRM by itself. Anyone who writes to you is created as a HubSpot contact, each message lands on that contact's timeline, and won deals can go back to your ad networks as purchases. You make no calls after connecting: each message syncs a few seconds after it arrives.

#What you can do

Job How
Create or match HubSpot contacts for inbox contacts Automatic (syncContacts, on by default)
Log every inbox message on the contact's timeline Automatic (logMessages, on by default)
Write a contact at a chosen step of a flow hubspot_upsert_contact workflow node
Send closed-won deals to ad platforms as purchases reportDeals, off by default
Property Value
Platform id hubspot
How it connects OAuth, through HubSpot's own consent screen, which installs the app in the portal
Scopes Always oauth, crm.objects.contacts.read and crm.objects.contacts.write; crm.objects.deals.read when you want deals
Portals per profile A single one
Posting, analytics, inbox on the account itself No

#Connect a portal

Whoever connects needs a HubSpot login with permission to install apps in that portal.

curl "https://api.pozy.ai/v1/connect/hubspot?profileId=6710c3a9e4b0d2f1a8c95e21&redirect_url=https://app.example.com/connected" \
  -H "Authorization: Bearer $POZY_API_KEY"

The user picks a portal and approves the app. They return to your redirect_url with connected=hubspot, profileId, accountId and username (the portal domain). Contact sync and message logging start right away. Reconnecting the same portal refreshes the account and keeps its settings.

#Choose what syncs

curl -X PATCH https://api.pozy.ai/v1/accounts/6710c4e7e4b0d2f1a8c95e60/hubspot-settings \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "logMessages": false, "reportDeals": true }'
Setting Default What it does
syncContacts true Creates a HubSpot contact when an inbox contact matches none
logMessages true Writes each inbox message on the contact's timeline
reportDeals false Sends deals that become closed won as Purchase events

Read the current values, plus the portal id and granted scopes, with GET /v1/accounts/{accountId}/hubspot-settings.

#How contacts are matched

For each message, Pozy looks for the HubSpot contact in this order:

  1. A contact with the same email address.
  2. A contact with the same phone number, taken from the person's WhatsApp, SMS, RCS or iMessage channel.
  3. With syncContacts on, a new contact with the person's name, email and phone. With it off, the message is skipped.

Once found, the link is kept. Pozy attaches to a contact that already exists without changing its name or any property. Should that contact later be deleted or merged, Pozy looks for a match again.

#How messages are logged

Channel Logged as
WhatsApp Communication (WhatsApp)
SMS Communication (SMS)
Any other inbox channel Note

Each entry names the channel and direction, then the text. Attachments are listed as links. A message is logged once, even when its sync is retried. Only conversations linked to an inbox contact sync, and only messages sent or received after you connected. Nothing is backfilled.

#Save a contact from a workflow

To push a lead to HubSpot at a chosen step, say right after a bot collects an email address, put a hubspot_upsert_contact node in the workflow:

Workflow node
{
  "id": "save-lead",
  "type": "hubspot_upsert_contact",
  "config": { "email": "{{answer}}", "properties": { "lifecyclestage": "lead" } }
}

The node finds the contact with the same matching as the inbox sync, then writes just the fields you filled in; empty values are ignored. Keys in properties are HubSpot's internal property names. Afterwards the flow continues on success, or on error if the workflow's profile has no HubSpot portal or HubSpot rejects the update.

#Report closed-won deals

With reportDeals on, every deal that becomes closed won is sent as a Purchase to the profile's event destinations, so Meta, Google and your other ad platforms see real revenue. See Conversions.

Purchase field Taken from
value, currency The deal's amount and currency, falling back to the portal's default currency
eventTime When the deal closed
eventId hubspot_deal_{portalId}_{dealId}, which stops a network from counting one deal twice
user Email, phone, name and address of the first contact on the deal

Deals are checked about once an hour. Deals closed before you turned the setting on are not sent, and each deal is sent once. The portal must have granted deal access: if the deals option shows as locked on the consent screen, a HubSpot admin enables it under Settings > Integrations > Connected Apps, then you reconnect.

#Disconnect

DELETE /v1/accounts/{accountId} stops syncing and uninstalls the app from the portal, unless another profile still uses that portal. Uninstalling from HubSpot shows the account as disconnected the next time a message syncs. Contacts and timeline entries already written stay in HubSpot.

#Limits

  • One portal per profile.
  • Contacts and their timelines only. Companies, deals and tickets are not synced (deals are read only for purchase reporting).
  • Some channels log only messages sent from the inbox, not every broadcast, sequence or workflow send.
  • A busy portal that HubSpot rate limits can lag by a few minutes; Pozy waits and retries.

#Errors

Error Why What to do
hubspot_profile_has_portal on the redirect A different portal is already linked to this profile Disconnect that one first, or pick another profile
hubspot_access_denied on the redirect The user did not approve the app Start again and approve it
hubspot_invalid_state on the redirect The connect link was too old or had been used already Get a new authUrl
hubspot_connection_failed on the redirect HubSpot did not complete the token exchange, or Pozy could not read the portal Try again; if it keeps failing, write to support@pozy.ai
400 on settings No boolean field in the body, deal access missing for reportDeals, or not a HubSpot account Send at least one setting to a HubSpot account id
404 on settings The account is gone or your key cannot reach it List accounts for a current id

#Endpoints

Endpoint What it does
GET /v1/connect/hubspot Get HubSpot OAuth connect URL
GET /v1/accounts/{accountId}/hubspot-settings Get HubSpot account settings
PATCH /v1/accounts/{accountId}/hubspot-settings Update HubSpot account settings
GET /v1/contacts List contacts

#Webhook events

Event When it fires
contact.updated Contact updated.
contact.deleted Contact deleted.
account.disconnected Account disconnected.
contact.tag_added Contact tag added.
contact.tag_removed Contact tag removed.
contact.field_changed Contact field changed.