HubSpot
Run your workspace's CRM on HubSpot: deals, tasks and notes written through, outreach logged on the timeline, and campaigns that stop when HubSpot says a contact has moved on.
A workspace can use Warmbly's own CRM or HubSpot. In HubSpot mode, HubSpot is the system of record. The deals, pipelines, tasks and notes you see in Warmbly are HubSpot's records, mirrored into Warmbly so lists, search and the board stay fast, and every change you make in Warmbly goes to HubSpot first. Your outreach is logged on each contact's HubSpot timeline, and HubSpot can stop a campaign when a contact becomes a deal or a customer.
The basic HubSpot connection (a contact upsert from an automation or Push to CRM) works without HubSpot mode. This page covers the full mode.
What HubSpot mode does
- Deals, pipelines, tasks and notes are HubSpot's. A deal you create, move or edit in Warmbly is written to HubSpot before it is saved here. If HubSpot refuses it (a required property, a missing permission), you see HubSpot's reason and nothing is saved.
- Your outreach lands on the HubSpot timeline. Sends and replies are logged as email activities, bounces and unsubscribes are recorded, and booked meetings become HubSpot meetings.
- A "Warmbly" property group on HubSpot contacts carries each contact's outreach status, so HubSpot users can filter lists, build reports and trigger workflows on it.
- HubSpot can stop outreach. A deal opened in HubSpot, a lifecycle stage you choose or an email opt-out holds the contact's campaigns.
- The contact panel shows HubSpot's side. In the contact drawer and the inbox, a contact shows its HubSpot owner, lifecycle stage, lead status, company and any properties you choose, and you can edit the owner, lifecycle stage and lead status in place.
Connect and set up
- Open Integrations > HubSpot and select Connect. Sign in to HubSpot, pick the account, and approve the permissions. Connecting takes someone who can install apps in that HubSpot account.
- The setup wizard opens. Every question has a default that works, so you can finish it without changing anything and adjust later. It asks which activity to log, whether Warmbly may create contacts and companies, what a positive reply does, which rules stop outreach, which deal pipelines to mirror, and how contact fields map.
- Finish the wizard. Warmbly creates the Warmbly property group in HubSpot and starts the first pull: owners, pipelines, then recent deals and tasks. The dashboard fills in as it runs, usually within a minute or two.
After setup the same page holds the settings and the sync health panel. Changing them needs the manage_settings permission.
A connection made before HubSpot mode existed needs a reconnect
Earlier HubSpot connections only asked for contact access. HubSpot mode also needs companies, deals, owners and the contact schema, so the page asks you to reconnect before you can switch, and the switch is refused with crm_reauth_required until you do.
What syncs
| Record | Direction | How |
|---|---|---|
| Deals | Both ways | Warmbly writes through to HubSpot. Changes in HubSpot are pulled every minute |
| Pipelines and stages | HubSpot to Warmbly | Managed in HubSpot only. Pulled every 30 minutes, and sooner when a deal arrives in a stage Warmbly has not seen |
| Tasks | Both ways | Warmbly writes through. Tasks owned by matched members are pulled every minute |
| Notes | Both ways | Warmbly writes through. A contact's HubSpot notes are pulled when you open the contact |
| Task types | HubSpot to Warmbly | Fixed to HubSpot's: To-do, Call, Email, LinkedIn |
| Owners | HubSpot to Warmbly | Pulled every 30 minutes and matched to members by email |
| Contacts | Both ways, per field | Owner, lifecycle stage, lead status, company, opt-out and the fields you map. See contacts and field mapping |
| Outreach activity | Warmbly to HubSpot | See activity logged to HubSpot |
Warmbly pulls only what changed since the last pull, so the minute-by-minute pull stays light. Opening a contact in Warmbly also refreshes that contact's HubSpot record, deals, tasks and notes on the spot.
Deals and pipelines
The Pipelines page lists only your HubSpot pipelines, and creating, renaming or deleting a pipeline or stage is refused with crm_managed_externally: make the change in HubSpot and it appears in Warmbly within minutes. In the wizard you can limit the mirror to some pipelines; deals in the others are not mirrored.
Deals in a pipeline that only exists in Warmbly are hidden from the deal table and board while HubSpot is your CRM. They are not deleted: copy them into HubSpot or switch back to see them again.
In HubSpot, won and lost are stages rather than a status. Marking a deal won or lost in Warmbly moves it to the pipeline's first closed-won or closed-lost stage, and moving it to a closed stage sets its status. Stages carry HubSpot's closed flag, won flag and probability. A deal owned by someone in HubSpot who is not a workspace member shows that owner's name.
Deals created by an automation's Create deal or Move deal stage action reach HubSpot too, through the sync queue rather than at once.
Tasks
The Tasks page shows the HubSpot tasks owned by HubSpot users who are matched to workspace members. The first pull brings in tasks changed in the last 90 days. A contact's own tasks are pulled when you open the contact, whoever owns them.
| Warmbly | HubSpot |
|---|---|
Priority low, medium, high, urgent | Low, Medium, High (urgent is written as High) |
Status pending, in progress, completed, cancelled | Not started, In progress, Completed, Deferred |
| Assignee | Task owner. A member with no matched HubSpot owner cannot be assigned (crm_owner_unmapped) |
Creating, editing or deleting a task type is refused with crm_managed_externally, because HubSpot's task types are fixed. Tasks Warmbly opens by itself, such as follow-up tasks from replies and an automation's Create a task, are written to HubSpot as well.
Contacts and field mapping
A Warmbly contact is linked to a HubSpot contact by email address. Linking happens when Warmbly emails the contact, when you open it, when HubSpot changes a contact whose address Warmbly has, and after an import from a HubSpot list.
When Warmbly emails someone HubSpot does not have, it creates the HubSpot contact (on by default). With company creation on (also the default), the new contact is associated with the company on its email domain, and a company is created when HubSpot has none. Free mail domains such as gmail.com never become companies. With creating contacts off, a contact HubSpot does not have is simply not logged there.
Each mapped field has a direction:
| Direction | What happens |
|---|---|
| Push | Warmbly writes the field to HubSpot when the contact is edited in Warmbly and each time it emails them |
| Pull | A change in HubSpot is copied onto the Warmbly contact |
| Both | The most recent change wins: an edit in HubSpot is copied onto the Warmbly contact, and an edit in Warmbly is written to HubSpot |
The defaults map first name, last name, company and phone to firstname, lastname, company and phone, all Both. A custom field maps as custom:<key>. A blank value in HubSpot never blanks a Warmbly field, and the email address is never overwritten from HubSpot.
You can also pick up to 40 extra HubSpot properties to show on the contact panel.
Activity logged to HubSpot
| In Warmbly | In HubSpot | Default |
|---|---|---|
| A campaign email is sent | An outgoing email activity with the subject and body | On |
| The contact replies | An incoming email activity | On |
| An email bounces | The logged email is marked BOUNCED | On |
| The contact unsubscribes | A note on the contact, and warmbly_unsubscribed set | On |
| A meeting is booked through Calendly or Cal.com | A HubSpot meeting | On |
| An open | warmbly_last_opened_at updated, no timeline entry | Off |
| A click | warmbly_last_clicked_at updated, no timeline entry | Off |
Each email activity is associated with the contact, its company and its open deals. Its owner is the member who owns the sending mailbox when that member is matched to a HubSpot owner, otherwise the contact's owner. Activity is logged within seconds and never depends on your webhooks or their per-minute limit, so a large send is logged in full.
Opens and clicks are off by default because mail privacy proxies and security scanners open and click on their own, and HubSpot timelines fill with noise. Turned on, they only update the two properties, at most once an hour per contact, and never create a contact in HubSpot.
The Warmbly property group
Warmbly creates a Warmbly group of contact properties in HubSpot when you switch, and keeps it up to date (on by default; turning it off stops every property write, including opens and clicks). Properties you or your HubSpot admins already changed are left as they are.
| Property | Holds |
|---|---|
warmbly_status | contacted, replied, interested, not_interested, meeting_booked, bounced or unsubscribed. A later send never moves a contact back from a reply status to contacted |
warmbly_last_campaign | The name of the last campaign that emailed the contact |
warmbly_last_contacted_at | When Warmbly last emailed the contact |
warmbly_last_replied_at | When the contact last replied |
warmbly_reply_intent | How Warmbly classified the latest reply |
warmbly_last_opened_at | Last open, when open logging is on |
warmbly_last_clicked_at | Last click, when click logging is on |
warmbly_unsubscribed | Set when the contact unsubscribes from Warmbly outreach |
warmbly_link | A link that opens the contact in Warmbly |
Owners
HubSpot's owners (its users) are matched to workspace members by email address. Where the addresses differ, pick the member by hand on the HubSpot page; a match you choose is kept and never replaced by the email match. Matching decides:
- whose tasks appear on the Tasks page
- who owns the email activity a mailbox logs
- which HubSpot owner a deal or task gets when you assign it to a member in Warmbly
Positive replies
When a reply is classified as interested, Warmbly can:
- set the contact's lead status (default
In progress) - set its lifecycle stage (off by default). HubSpot refuses to move a lifecycle stage backwards; the lead status is still set when it does
- create a deal in a pipeline and stage you choose (off by default). It is skipped when the contact already has an open deal
The follow-up task comes from your existing reply follow-up setting and is written to HubSpot like any other task.
Exit rules
Exit rules hold a contact in every campaign it is in when HubSpot says it has moved on, so nobody gets a follow-up after becoming a deal or a customer. A held lead stays held until someone resumes it; the hold shows the reason, such as "A deal was opened in HubSpot".
| Rule | Default |
|---|---|
| A deal associated with the contact is opened in HubSpot | On. Only deals created in the last 48 hours count, so the first pull's existing deals stop nobody |
| The contact's lifecycle stage changes to one you choose | On, for Opportunity and Customer |
| The contact opts out of email in HubSpot | On. The address is added to the suppression list |
Import guards
Guards decide who an import from a HubSpot list leaves out:
| Guard | Default |
|---|---|
| Skip contacts opted out of email | On |
| Skip contacts in these lifecycle stages | On, for Customer and Evangelist |
| Skip contacts with an open deal | On |
| Skip contacts owned by someone outside the workspace | Off |
Working from inside HubSpot
Two things put Warmbly inside HubSpot itself, so a rep never has to switch tabs to act on a contact:
- The Warmbly card on every contact record shows the contact's Warmbly status, each campaign they are in with its step, and why a lead is paused. From the card you can add the contact to a campaign, pause or resume all of their campaigns, and open them in Warmbly. A contact new to Warmbly is created from the HubSpot record when you add them.
- The "Add to Warmbly campaign" workflow action enrolls a workflow's contacts in the campaign you pick, so a HubSpot list, form or lifecycle change can feed outreach on its own. Contacts who opted out of email in HubSpot are skipped, and the action reports what happened in its output for the next step of the workflow.
Both act as the HubSpot user's matched member when there is one, and as the workspace owner otherwise.
Importing from HubSpot lists
On the HubSpot page, pick one of your HubSpot lists. The preview counts who would come in and who is skipped, by reason: opted out, lifecycle stage, open deal, owned by someone outside the workspace, no email address, and duplicate address. Continue, and the list becomes an ordinary contact import, finished in the usual import review where you pick the campaign, labels and duplicate handling.
One import takes up to 25,000 contacts; a larger list is cut off at that number and the preview says so. The imported contacts are linked to their HubSpot records a couple of minutes later, so their first sends log against the right person.
List import needs HubSpot's list permission, which is optional. A connection without it is asked to reconnect and allow list access.
Copying your Warmbly CRM into HubSpot
When a workspace that used Warmbly's CRM switches, its own deals, tasks and notes are not in HubSpot yet. The HubSpot page counts them and copies the kinds you pick, once:
- Deals move onto your first HubSpot pipeline. Each keeps its stage when HubSpot has a stage with the same name, and otherwise goes to the first stage that matches its status (open, won or lost)
- Tasks and notes are created in HubSpot with their contact and deal
A record already in HubSpot is never copied twice, so running it again only picks up what was missed. A Warmbly deal, task or note you edit after switching is also created in HubSpot at that moment.
Sync health and fixing errors
The HubSpot page shows what is waiting, what failed in the last runs, how many records are mirrored, and when each pull (owners, pipelines, deals, tasks, contacts) last ran with any error it hit. Sync now starts a full pull; a second one within 30 seconds is refused with crm_sync_running.
Changes you make in the dashboard go to HubSpot while you wait. Activity logging, automation-written records and copies go through a queue that retries a failure with growing gaps (a minute, five minutes, half an hour, up to several hours) before marking it failed. Failed items stay listed for 30 days with a plain-language reason. Retry sends them again and Discard drops them.
| You see | What to do |
|---|---|
| Reconnect HubSpot | HubSpot revoked Warmbly's access or a permission is missing. Reconnect from Integrations and approve every permission |
| HubSpot refused the change | HubSpot's own rule, shown in its words (for example a required deal property). Fix it in HubSpot or on the record, then retry |
| This record no longer exists in HubSpot | It was deleted in HubSpot. Discard the item |
| That member is not a HubSpot user yet | Match the member to a HubSpot owner in owners |
| HubSpot did not answer | HubSpot was slow or down. It retries by itself |
Warmbly keeps its calls under HubSpot's limit for each HubSpot account (about 90 requests every 10 seconds, shared across every Warmbly process), and waits and retries when HubSpot asks it to slow down.
Switching back and disconnecting
Choosing Warmbly as the CRM again, or disconnecting HubSpot, stops the sync and the activity logging. Nothing is deleted on either side: the deals, pipelines, tasks and notes that were mirrored stay in Warmbly as ordinary records you can edit, the hidden Warmbly-only pipelines come back, and HubSpot keeps everything that was written there. Switching back to the same HubSpot account later picks up the same records rather than duplicating them.
Self-hosting
A self-hosted instance uses its own HubSpot app. Create one in a HubSpot developer account, then:
- Set the redirect URL to
BACKEND_PUBLIC_URLplus/integrations/oauth/callback, or to the value ofINTEGRATIONS_OAUTH_REDIRECT_URLwhen you set one. - Add the required scopes:
oauth,crm.objects.contacts.read,crm.objects.contacts.write,crm.objects.companies.read,crm.objects.companies.write,crm.objects.deals.read,crm.objects.deals.write,crm.objects.owners.read,crm.schemas.contacts.readandcrm.schemas.contacts.write. Addcrm.lists.readandsales-email-readas optional scopes. - Set
HUBSPOT_OAUTH_CLIENT_IDandHUBSPOT_OAUTH_CLIENT_SECRETon the backend and the consumer, and setAPP_URLso thewarmbly_linkproperty points at your dashboard. See configuration.
The consumer runs the minute-by-minute pull and the sync queue, so HubSpot mode needs no inbound traffic from HubSpot. Webhooks are optional: subscribe the app to contact.creation, contact.propertyChange, contact.deletion, deal.creation, deal.propertyChange and deal.deletion with the target URL <backend>/api/v1/integrations/hubspot/webhooks, and a change is picked up within seconds instead of within the minute. Deliveries are verified with HubSpot's X-HubSpot-Signature-v3 signature and only make the next read come sooner; Warmbly always reads the record from HubSpot itself.
Moving a workspace
A workspace export carries the CRM mode, its setup choices, the owner matches, which Warmbly record is which HubSpot record, and each contact's HubSpot details, so the destination keeps updating the same HubSpot records instead of creating duplicates. The sync queue and the pull checkpoints stay behind; the destination starts its own pull. Reconnect HubSpot on the destination unless it uses the same HubSpot app and the archive carried credentials.
FAQ
Does it work with free HubSpot? Yes. Contacts, companies, deals, tasks, notes, owners and custom contact properties are all part of HubSpot's free CRM. The list and email-reading permissions are optional, so an account that cannot grant them still connects; only list import is unavailable without the list permission.
Which permissions does Warmbly ask for? Read and write on contacts, companies and deals, read on owners, and read and write on the contact schema (for the Warmbly property group). Lists and email reading are asked for as optional.
Why are opens off? Mail privacy proxies and security scanners open and click automatically, so opens are a weak signal and would bury the timeline. Turned on, they only update warmbly_last_opened_at and warmbly_last_clicked_at.
What happens to my data when I disconnect? Everything that was mirrored stays in Warmbly as ordinary records, and nothing is removed from HubSpot. See switching back and disconnecting.
Can I edit pipelines in Warmbly? No, while HubSpot is your CRM. Edit them in HubSpot and they update in Warmbly within minutes.
Does every member need a HubSpot seat? No. Members without a matched owner still see deals, tasks and notes; they cannot be assigned HubSpot deals or tasks, and their mailboxes log email under the contact's owner.