A one-way, read-only connection: noombat reads your CRM on a schedule and never writes anything back. One private app, one token — a HubSpot super admin can complete this in about 10 minutes.
Using Salesforce instead? Salesforce setup guide →
app.hubspot.com URL) and your data hosting region (Settings > Account Defaults > Data Hosting). EU portals issue pat-eu1-… tokens, US portals pat-na1-… — no other setting depends on it, we just need to know.A private app is HubSpot's built-in way to give one integration its own key with an exact list of permissions — auditable on its own, unaffected by staff changes, and revocable in one click.
Development > Legacy apps > Create legacy app — choose Private. In portals still on the older navigation it's Settings > Integrations > Private Apps > Create a private app — same screen either way.“Legacy apps”? Don't let the label worry you
Scopes tab — tick exactly these, read scopes only
crm.objects.companies.read | the companies you sell to |
crm.objects.contacts.read | the people at those companies — this also unlocks the calls, meetings and notes logged on your records (HubSpot has no separate scope for those) |
crm.objects.owners.read | record owners, so activity and companies can be attributed to your reps |
crm.lists.read | which of your lists each company and contact belongs to |
sales-email-read | the content of one-to-one emails logged on your records |
crm.objects.deals.read | optional — deals and pipelines, so revenue outcomes connect back to the market |
forms | optional — form submissions, if you capture demand through HubSpot forms |
content | optional — marketing email opens and clicks; HubSpot only offers this scope on Marketing Hub or CMS Hub Professional/Enterprise |
The optional three (deals, forms, marketing email events) are worth ticking if you use those parts of HubSpot — skip any you don't, and tell us which.
No write scopes — that's the whole point
.write sibling. Leave every write scope unchecked: we don't want them, and with only read scopes granted, HubSpot itself rejects any write — read-only is enforced by the platform, not by our promise.Click Create app and confirm. Scopes can be adjusted any time later — edits apply to the existing token immediately, so a missed scope is a ten-second fix, not a redo.
(the app) > Auth > Show token > CopyThe token starts with pat-na1- or pat-eu1- depending on your region. Use the Copy button rather than selecting the text — a surprising number of failed setups are a token that picked up a space or lost a character on the way.
This token is the one secret — treat it like a password
pat-…)Share the token securely — never in a plain email
integrations@noombat.ai. Also good: a self-destructing link (e.g. onetimesecret.com — paste the value, send the link, it burns after one view). Or read it out on a call. If the token ever leaks, rotate it on the Auth tab and the old one dies instantly.Once the details arrive we run a read-only verification the same day — connecting with your token and checking each object returns what it should — and confirm back to you. If anything's off, we tell you the exact setting to adjust; the table below is the complete list of what it could be.
Real failure modes with the exact fix. If yours isn't here, send it over — we diagnose these quickly.
| What you see | Why | Fix |
|---|---|---|
| 403 MISSING_SCOPES — “This app hasn't been granted all required scopes to make this call” | A scope from the step-1 checklist wasn't ticked. The response names the missing scope under “requiredGranularScopes”. | Open the app → Scopes → tick it → Save. The existing token picks up the new scope immediately — no new token needed. |
| The same MISSING_SCOPES error, but the scope IS ticked — or the scope doesn't appear in the picker at all | Your HubSpot tier doesn't include that feature. The “content” scope (marketing email events) needs Marketing Hub or CMS Hub Professional/Enterprise. | It's optional for us — skip that scope and tell us, and we plan the integration around it. |
| 401 INVALID_AUTHENTICATION — “Authentication credentials not found” | The token was truncated or picked up whitespace when pasted, or it has been rotated since you copied it. | Re-copy with the Copy button on the app's Auth tab (avoids manual selection) and check for spaces or line breaks. |
| Everything worked for weeks, then every call returns 401 | The token was rotated, or the app deleted. HubSpot emails every super admin when either happens. | Send us the new token the secure way from step 3 and we're back the same day. |
| You can't find the private apps page, or can't create the app | Private apps are visible to super admins only. | Have a super admin run step 1 — it's the only HubSpot permission this setup needs. |
| Association lookups fail with USER_DOES_NOT_HAVE_PERMISSIONS | The super admin who created the app has since been removed or downgraded — HubSpot ties some calls to the creator. | Rotate the token (or recreate the app) under an active super admin and send us the new value. |
| “Hub <your id> is unknown to this Hublet” | Rare — stale routing state after HubSpot migrated your portal between data centres. | Rotate the token; the new one carries the current region and routing fixes itself. |
The questions security-conscious admins ask us, answered the way we answer them.
Yes, and it's enforced by HubSpot, not by our promise. The private app holds only read scopes — every write endpoint checks for the paired .write scope, which the app doesn't have, so the platform itself rejects any write attempt. There is nothing to configure to get this guarantee; it's how HubSpot scopes work.
Companies and contacts (who you sell to), deals (pipeline and revenue), the engagements logged on your records — calls, meetings, emails, notes — plus list memberships, form submissions and marketing email opens/clicks (how your market responds), and owners (who works what). noombat keeps a read-only mirror and uses it to score your market, connect the leads it generates to the activity and revenue they produce, and show your team a live, prioritised view. Historical data matters too: the scoring learns from what already happened, which is why a forward-only feed (like a webhook) isn't enough.
Honestly: HubSpot's scopes are object-level, so a token can't be limited to specific properties the way Salesforce field-level security works — HubSpot's own docs note that its user-facing property restrictions don't apply to API access. Two things do help. First, noombat only requests the specific properties it uses (happy to share the exact list). Second, if you're on Enterprise, HubSpot's Sensitive Data feature gates any property you classify as sensitive behind dedicated *.sensitive.* scopes — which we don't request, so those values are platform-blocked to our token.
Nothing. Private apps are included in every HubSpot tier — including the free CRM — with up to 20 per account, and a private app is an account-level credential, not a user, so no seat is consumed. The one tier-dependent piece is the optional content scope (marketing email opens/clicks), which HubSpot only offers on Marketing Hub or CMS Hub Professional/Enterprise; everything else works on any tier.
A webhook works well for pushing one object's changes in real time, but it can't replace API access here: webhooks only send changes going forward (noombat needs the existing history to learn from), each object needs an automation built and maintained on your side, and to fetch the full record a webhook receiver ends up calling the API anyway. We're happy to add webhooks on top of API access for time-sensitive events later.
Instantly, from your side, in either of two ways: on the app's Auth tab choose Rotate and expire now (the old token dies immediately), or delete the private app (its token is permanently revoked). Nothing on our side can restore access. If you want a graceful handover instead, “Rotate and expire later” keeps the old token alive for 7 days while the new one is delivered.
Yes. The private app's page in HubSpot has an API call log covering the past 30 days — every request with its method, endpoint and response code, filterable and exportable as CSV. Because noombat is the only thing using this app's token, everything in that log is attributable to us alone. (HubSpot doesn't store request or response payloads in the log, only the calls themselves.)
In an isolated per-client database schema hosted in the EU (Frankfurt), encrypted in transit and at rest, never mixed with other customers' data, and deleted if we part ways. We're happy to put data-handling terms in writing or walk through it with your security team.
Anything unclear, or a policy conflict? integrations@noombat.ai — or bring your HubSpot admin and we'll do the whole thing together on a call.