StabisoDocs

Sales and customers

HubSpot

A company that runs its marketing in HubSpot connects its HubSpot account to Stabiso. HubSpot stays the marketing tool: the campaigns, the website forms, the e-mails, the scoring. When a contact reaches the stage where marketing hands over to sales, it arrives in Stabiso as a lead, and from then on Stabiso is the system of record. Stabiso tells HubSpot what became of each lead (worked, disqualified, a deal, won, revenue invoiced), so marketing sees which campaigns brought paying customers. The design is ADR-0097.

Connecting a company

Settings > HubSpot (administrators) connects one company to one HubSpot account. Choose:

  • the company whose leads the contacts become;
  • the hand-over stage: Lead, Marketing qualified lead (the default) or Sales qualified lead. Contacts at that stage, or a later one before Opportunity, come in;
  • optionally a default owner for leads whose HubSpot owner is not a person in Stabiso.

Then connect it one of two ways:

  • Connect with HubSpot opens HubSpot's consent page, where someone with the right to install apps in that HubSpot allows Stabiso, and HubSpot sends them back. Shown when this system has its HubSpot app.
  • A private app key: in the company's own HubSpot, Settings > Integrations > Private apps > Create a private app, tick the permissions the page lists (read and write contacts, read and write contact properties, read owners), create it and paste its access token.

Stabiso asks HubSpot for the account first (which proves the token) and adds its own properties to the account's contacts, in a group Stabiso. The token is kept sealed in the database (see security) and never shown again. Connecting again replaces the token. A company connected to one account is not connected to another: disconnect it first, so that leads of two accounts never mix.

What comes in

Every 5 minutes, and on Read now, Stabiso reads the contacts at the hand-over stage that changed since the last round (the first round reads the last 90 days, at most 500 contacts a round; the next round goes on from there). Each contact read for the first time becomes a new lead:

Lead From the HubSpot contact
First and last name, company, role, e-mail, phone firstname, lastname, company, jobtitle, email, phone (else mobilephone)
Country country, as a code or a name (CH, Switzerland, Schweiz); left empty when it is neither
Message message (what the person wrote in a HubSpot form)
Source HubSpot, with HubSpot's original source as the detail (Paid search: autumn campaign)
Owner the contact's HubSpot owner when that is an active person here (the same e-mail address), else the default owner, else nobody: Autopilot or a person gives it one
  • No duplicates. A contact becomes a lead once per company and account, also after disconnecting and connecting the same account again. An open lead of the company with the contact's e-mail that came from nowhere else is linked to the contact rather than copied.
  • While the lead is new, HubSpot's changes to the contact (a phone number added) update it. Once someone works the lead, Stabiso owns it and HubSpot's changes no longer reach it.
  • The lead's dialog links to the contact in HubSpot.

What goes back

On the same rounds, each contact a lead came from is sent what changed since it was last sent:

In Stabiso HubSpot lead status Lifecycle stage
New New
Being worked In progress Sales qualified lead
Disqualified Unqualified
Converted, the deal open or lost Open deal Opportunity
The deal won, or revenue invoiced Open deal Customer

And Stabiso's own properties: Stabiso lead number, Stabiso status (Being worked, Disqualified: no budget, Deal open, Deal won, Deal lost, Customer, invoiced), Stabiso deal won (the deal's amount once won, when the deal is in the company's currency), Stabiso revenue invoiced (net revenue invoiced to the customer since the lead was converted: posted invoices less credit notes, in the company's currency) and Stabiso currency.

HubSpot's lifecycle stage only moves forward, so Stabiso never sends a stage earlier than the one it read or sent. What HubSpot refuses for a contact is not sent again until something else about the lead changes.

Problems and disconnecting

  • HubSpot refusing the token (the app uninstalled, the private app's token rotated, a permission taken away) sets the connection to Connect again, with the reason on the page. Nothing is read until it is connected again.
  • HubSpot not answering or asking to slow down is noted on the page; the next round tries again.
  • Disconnect stops reading and sending. A consent's token is taken back at HubSpot; a private app's token is deleted in HubSpot. The leads stay, and so does which contact each came from.
  • Erasing a lead in Stabiso (a privacy request) empties it here, and nothing more is read into it or sent about it. It does not erase the contact in HubSpot: do that in HubSpot too.

Security

  • The token is sealed (AES-256-GCM) with a key that is never in the database: a backup, an export or a look at the table gives nothing. The key is the deployment's ERP_HUBSPOT_TOKEN_KEY, or, without one, derived from the database password, which Cloud Run reads from Secret Manager.
  • Connections are never exported and never copied into a test copy, and a test copy refuses to connect: a copy never reads or writes HubSpot.
  • Only an administrator connects, changes or disconnects a company; an AI agent never does.
  • Errors never carry HubSpot's answers, which could echo a contact's data or a token.

Not yet

Sending Stabiso's own website leads to HubSpot, HubSpot's deals and companies as records of their own, HubSpot's real-time webhooks (the 5-minute rounds are enough for leads) and marketing e-mails.

API

GET /v1/hubspot, POST /v1/hubspot/connections (a private app's token), POST /v1/hubspot/authorize and POST /v1/hubspot/connections/oauth (the consent page), PATCH /v1/hubspot/connections/{connection_id}, POST /v1/hubspot/connections/{connection_id}/sync and DELETE /v1/hubspot/connections/{connection_id} (API reference). The daily job (erp close-job) does a round with each account the API has not read for an hour.

Stabiso, the Enterprise System of Record · generated from the code and its guides · release 20b7dd5b0c4d