HubSpot logo

CRM & marketing

Connect HubSpot to Excel, Sheets and AI

CRM data as virtual tables: contacts, companies, deals, pipelines. Same read-only SQL as your warehouse.

1connection
0inbound ports
read-onlyenforced

One connection, every surface

Where your HubSpot data can go

Connect HubSpot once and the same read-only connection feeds all of these — no second setup, no second copy of the data. 8 of 11 have a step-by-step guide.

Guide

HubSpot to Excel

Microsoft Excel · Excel add-in

Pull live HubSpot results straight into a worksheet and refresh them on demand — desktop Excel, Excel Online, Microsoft 365.

Read the guide
Guide

HubSpot to Google Sheets

Sheets add-on

Run a saved HubSpot query from the sidebar and drop the rows into the sheet. Shared collaborators can refresh it themselves.

Read the guide
Guide

HubSpot MCP server

Claude, Cursor and MCP clients

Give an AI assistant read-only access to HubSpot with the schema it needs to write correct SQL — no credentials in the chat.

Read the guide
Supported

HubSpot REST API

HTTP endpoint

Publish a HubSpot query as an authenticated JSON endpoint any application can call, with an OpenAPI 3.1 spec and ready-made Postman, Insomnia and Hoppscotch collections. No database port is opened.

How REST API works no HubSpot walkthrough written yet
Guide

HubSpot to Airtable

Automation platform

Sync HubSpot rows into an Airtable base on a schedule, or fetch them inside an Airtable automation script.

Read the guide
Guide

HubSpot to Baserow

Automation platform

Feed a Baserow table from HubSpot over the REST endpoint — self-hosted or Baserow cloud.

Read the guide
Guide

HubSpot to SeaTable

Automation platform

Keep a SeaTable base current with HubSpot data without exporting a file or exposing the database.

Read the guide
Guide

HubSpot to Smartsheet

Automation platform

Push HubSpot results into a Smartsheet grid so plans and reports read from the source system, not last week's export.

Read the guide
Guide

HubSpot to Anvil

Anvil Works · App platform

Back an Anvil Python app with HubSpot through the REST endpoint instead of embedding database credentials in the app.

Read the guide
Supported

HubSpot to Power BI

Power Query M

Paste the generated Power Query M into the Power BI Advanced Editor and the report reads live HubSpot results over HTTPS — no ODBC driver, no database port opened.

How Power BI works no HubSpot walkthrough written yet
Supported

HubSpot alerts and reports

Slack · Discord · Email · Webhook

Put a HubSpot query on a schedule and have the rows delivered to Slack, Discord, email or a signed webhook — or hold the message until a row count, threshold or percentage change crosses the line you set.

How alerts and reports work no HubSpot walkthrough written yet

How it works

5 steps, no inbound firewall change

01

Create a private app in your HubSpot portal and give it read scopes for the objects you care about.

02

Install the Network Agent and paste the access token. It is held there; HubSpot only ever hears from your own network.

03

Choose which of the 31 tables to sync and how often. Contacts, companies, deals, owners, pipelines, pipeline stages and properties are on by default.

04

Write ordinary SQL against hubspot.deals, hubspot.companies and the rest — or let Nova write it.

05

Read it from Excel, Sheets, Power BI, MCP or REST, and join it to your own database in the same statement.

Feature deep-dive

What HubSpot gives you

Associations are a table, not a puzzle

The thing that makes HubSpot exports painful is that the interesting information is in the links between objects, and a CSV of contacts does not carry them. Here they are their own table with both sides on every row.

  • hubspot.associations holds the from-object, the to-object, the association type and the label, so a deal's contacts or a ticket's company is a plain JOIN.
  • Contacts to companies, contacts to deals, companies to deals, deals to line items, tickets to contacts and tickets to companies are all covered.
  • Pipelines and pipeline stages are separate tables too, so a deal's stage resolves to a name and an order rather than an opaque id.

The 31 tables

  • CRM objects — contacts, companies, deals, tickets, owners, pipelines, pipeline_stages, products, line_items.
  • Engagements — calls, emails, meetings, notes, tasks, communications.
  • Commerce — quotes, invoices, subscriptions, payments, taxes, discounts, fees.
  • Marketing — marketing_events, forms, form_submissions, feedback_submissions.
  • Lists and automation — lists, workflows.
  • Definitions — properties, schemas, associations.

Where your custom properties actually are

Worth being precise about, because it is the one thing people assume works differently. Each object table carries a fixed set of named columns — the standard fields — and everything else HubSpot returned, custom properties included, is kept in a raw_data JSON column on the same row.

  • Nothing is discarded. A custom property is queryable, but through the JSON column rather than as a column of its own.
  • hubspot.properties lists every property definition across fifteen object types — name, label, type, field type — so you can look up what exists and what it is called.
  • hubspot.schemas holds custom object definitions. Custom object records are not synced as tables of their own.
  • If you want a custom property to read as a first-class column in a spreadsheet, pull it out in the saved query. That is one expression once, and every consumer of that query then sees a proper column.

Shared by every API connector

How every API connector works

  • Your account becomes tables — endpoints are mapped to typed SQL tables with primary keys and indexes, so you write SELECT, JOIN and GROUP BY instead of paging through JSON.
  • You choose what syncs, and how often — each table has its own interval, or none at all. Where the vendor's API supports it, only records that changed since the last run are fetched.
  • The copy is yours — it lives in an AES-256-GCM encrypted DuckDB file next to the agent, on your machine. Not in our cloud.
  • The vendor only ever hears from you — the agent calls the API directly from your own network, so your token is not needed by Query Streams to answer a query.

Good to know

  • It is a synced copy, not a live proxy — a query reads what has already been fetched, so it returns at SQL speed and never spends your API rate limit. Selected tables can additionally refresh a stale row as you read it.
  • Rate limits are respected for you — each connector paces itself well inside the vendor's published limits, so a report cannot get your account throttled for everything else that uses it.
  • Nothing is thrown away — fields the table does not name are kept in a raw_data JSON column you can still query.
  • Join it to your databases — an API table and a SQL Server table in the same statement is an ordinary query here, not an integration project.

Cross-source SQL

Join HubSpot to the rest of your data

A CRM knows who the account is; a payment processor knows what it paid. Neither knows both, and the number that gets asked for at the end of the quarter needs them in the same row. Each source runs only the part it can, streams the result back, and the join happens centrally — the sources never talk to each other and nothing is copied anywhere.

3 connections · 3 agents

HubSpot CRM & marketing
PostgreSQL Relational engine
Stripe Payments & billing

One statement

-- the account from HubSpot, your own customer row, the invoice from Stripe
SELECT   h.industry, COUNT(DISTINCT h.id) AS accounts, SUM(i.amount_due) / 100 AS invoiced
FROM     crm.hubspot.companies1   h
JOIN     pg_crm.public.customers2 c ON c.domain = h.domain
JOIN     billing.stripe.invoices3 i ON i.customer = c.stripe_id
GROUP BY h.industry
ORDER BY invoiced DESC;

The three parts are connection, schema and table — and the connection name is whatever you called it. Illustrative columns; your tables will be your tables. The join runs on the company domain because a HubSpot deal carries no customer reference of its own — the link between objects is a row in the associations table, which is queryable too when the deal rather than the account is what you want. Stripe reports money in the smallest currency unit, hence the division. Read-only applies to every piece: SELECT, WITH and EXPLAIN only, with a ceiling on how much any one source may hand over for a single query. How federated queries work

Connection details

What HubSpot needs

Authentication
A private app access token, held on the agent. Not an OAuth round trip you have to keep alive
Reached over
HTTPS from your network to HubSpot. Nothing inbound
Schema
hubspot — so hubspot.deals, hubspot.contacts, hubspot.associations
Tables
31, of which seven are on by default: contacts, companies, deals, owners, pipelines, pipeline_stages and properties
Custom properties
Kept in a raw_data JSON column on the object row, with their definitions listed in hubspot.properties. They are not added as columns
Incremental
Through HubSpot's CRM search on last-modified date, so edits to existing records are picked up
Live refresh
Available on 20 of the CRM object tables — a query keyed to one record checks it against HubSpot before answering
Rate limits
Paced to the floor of HubSpot's published limits, so a report cannot throttle the portal for everyone else
Local copy
An AES-256-GCM encrypted DuckDB file beside the agent, on your machine

Read-only is structural. The connector implements no HubSpot write call — every request it makes is a read, a search or a batch read — so a query cannot change a deal stage or touch a contact no matter what the token is scoped for. Scoping the private app to read anyway is still worth doing.

Syncing associations walks every object of each type and then reads the links in batches, so it is the most expensive table here. Give it a longer interval than the object tables unless you genuinely need the links up to the minute.

Vendor documentation: www.hubspot.com

FAQ

Questions about HubSpot

Which tools can read HubSpot data through Query Streams?

All of them, from one connection: Excel, Google Sheets, MCP, REST API, Airtable, Baserow, SeaTable, Smartsheet, Anvil, Power BI, scheduled alerts and reports. Connect the account once and every surface reads the same read-only connection — there is no per-tool setup and no second copy of the data.

Do I have to open a firewall port to my HubSpot account?

No. The Query Streams Network Agent runs inside your network and opens a single outbound encrypted connection. Nothing listens for inbound traffic, no VPN is required, and the account keeps its existing firewall rules.

Can Query Streams change data in HubSpot?

No. The agent enforces read-only at the point of execution — one statement at a time, SELECT and friends only. Credentials stay on the agent and are never sent to Query Streams.

What does Query Streams need to connect to HubSpot?

A reachable host, a role and its password — the agent carries the driver, so nothing is installed on the account. Authentication: A private app access token, held on the agent. Not an OAuth round trip you have to keep alive. Reached over: HTTPS from your network to HubSpot. Nothing inbound. Schema: hubspot — so hubspot.deals, hubspot.contacts, hubspot.associations. Tables: 31, of which seven are on by default: contacts, companies, deals, owners, pipelines, pipeline_stages and properties.

Can I join HubSpot to another database in the same query?

Yes — that is a federated query. One statement can reference HubSpot and your other connections at once, written as connection.schema.table. Each source runs only the part it can and streams the result back; the join happens centrally, so the sources never connect to each other and nothing is copied or scheduled. Read-only applies to every piece — SELECT, WITH and EXPLAIN only — and there is a ceiling on how much any one source may hand over for a single query. Federated queries are a plan feature; the federated queries page carries the current source and size limits.

Put HubSpot where the work happens

Install the agent, point it at your account, and pick a destination.

Read-only Outbound only Credentials stay on the agent