Sync HubSpot contacts, deals, and reports to Google Sheets without paying for Operations Hub. 5 methods compared honestly, including free options.
You can sync HubSpot data to Google Sheets without Operations Hub using the free HubSpot API with Google Apps Script, Zapier (with limitations), or a third-party connector like brooked.io. HubSpot's native Workflow → Sheets action requires Operations Hub Professional at $720+/year, but you have real alternatives.
The Problem: Operations Hub Is Not the Only Path
HubSpot is excellent CRM software. Its Google Sheets integration story is not excellent.
The frustration is well-documented in their own community:
"Is there a way I can automatically export reports into Google Sheets? I didn't see a native option for this aside from a manual export of unstructured data." (HubSpot Community Forum)
"I want to pull all my contacts with certain properties into a Google Sheet that refreshes automatically. Every solution I find either costs hundreds of dollars per year or is a one-time export." (Reddit r/hubspot)
"HubSpot told me I need Operations Hub Professional to use the Sheets workflow action. That's $720 a year just to get my own data into a spreadsheet." (HubSpot Community Forum)
Here is what makes this frustrating: HubSpot markets several features that sound like Google Sheets integrations but are not what most users need.
Operations Hub "Data Sync", This syncs HubSpot with other CRMs (Salesforce, Pipedrive, Zoho). It is not a Google Sheets connector. The name is misleading and the confusion is common.
The HubSpot for Google Sheets extension, This is designed for pushing data INTO HubSpot from a spreadsheet, not pulling data OUT. More on this in Method 2.
The Workflow → Google Sheets action, This is the real native connector, and it requires Operations Hub Professional ($720/year billed annually) or higher. Many teams do not need Operations Hub for anything else.
Here is a clear map of the actual cost barrier:
| HubSpot Plan | Google Sheets Workflow Action Available? | Annual Cost |
|---|---|---|
| Free / Starter / Pro (without Ops Hub) | No | - |
| Operations Hub Starter | No | ~$240/year |
| Operations Hub Professional | Yes | $720/year |
| Operations Hub Enterprise | Yes | $2,000+/year |
If you are paying for the Sheets workflow action and using it heavily, $720/year is probably fair. If you just want your contacts or deal pipeline in a spreadsheet once a week, there are better ways to spend that money.
Method 1: Manual CSV Export
Cost: Free Real-time: No Code required: No
HubSpot lets you export contacts, companies, deals, and custom object records as CSV files from any list or report. This is the zero-cost baseline.
How to Do It
- Go to Contacts > Contacts (or Deals, Companies, etc.)
- Filter your view or select specific records
- Click Export in the top right
- Choose your properties, select CSV format
- HubSpot emails you a download link (usually within a few minutes for standard exports)
- Download, open in Excel or Sheets, clean up the formatting, import or paste
The Real Gotchas
The email delay. HubSpot does not download immediately. It sends a link to your email. For large exports, this can take 10–20 minutes. If you are doing this weekly, that friction adds up.
Row caps. List exports are capped at 1,000 records in some contexts. Report exports have their own limits depending on the report type. You may need to segment your export into multiple files and stitch them together.
ISO date format hell. HubSpot exports dates in ISO 8601 format (2024-01-15T14:32:00.000Z). Google Sheets does not automatically parse these as dates. You will spend time reformatting or writing a formula like =DATEVALUE(MID(A2,1,10)) for every date column.
Hidden lifecycle date properties. HubSpot's lifecycle stage timestamp properties, hs_lifecyclestage_lead_date, hs_lifecyclestage_customer_date, and the newer hs_v2_date_entered_* properties: are not included in default exports. You must manually select them in the property chooser before exporting, and many users never realize they exist.
It does not scale. If you need this weekly or more often, manual CSV export is not a sustainable workflow. It is appropriate for one-time analysis or infrequent pulls on small datasets.
Method 2: HubSpot for Google Sheets Extension
Cost: Free Real-time: No Code required: No
This is the most misunderstood tool in the HubSpot ecosystem. The official HubSpot for Google Sheets add-on is prominently available in the Google Workspace Marketplace and is frequently recommended in forum threads as "the free integration." It is not what most people think it is.
What It Actually Does
The HubSpot for Google Sheets extension is designed to import data from a spreadsheet INTO HubSpot, to create or update contacts, companies, or deals in bulk from a spreadsheet. It is an import tool, not an export tool.
Specifically, it helps you:
- Map spreadsheet columns to HubSpot properties
- Import new contacts or update existing ones by matching on email
- Handle deduplication during bulk imports
What It Cannot Do
- Pull contacts, deals, or companies OUT of HubSpot into your spreadsheet
- Refresh data on a schedule
- Sync two-way changes between HubSpot and Sheets
- Export reports or list data
If you install this extension expecting to see your HubSpot contacts populate a Google Sheet, you will be confused. The direction of data flow is the opposite of what most users need.
When to use it: It is genuinely useful if you need to do a bulk import or update in HubSpot, for example, updating phone numbers or adding a custom property value for thousands of contacts at once. For pulling data out of HubSpot, you need a different solution.
Method 3: Zapier and Make.com
Cost: $19–$69/month (Zapier), $10–$18/month (Make.com) Real-time: Trigger-based (near real-time for new records) Code required: No
Zapier and Make.com can connect HubSpot to Google Sheets without Operations Hub, and they are the most popular no-code options. But they come with limitations that are not always clear from the marketing.
How the HubSpot → Google Sheets Zap Works
The typical Zap triggers on a HubSpot event (a contact is created, a deal moves to a stage, a form is submitted) and appends a row to a Google Sheet. This is reliable for capturing new events as they happen.
The 100-Record Cap on List Exports
If you want to run a scheduled export of a HubSpot list (rather than capturing individual new records), Zapier's HubSpot integration processes a maximum of 100 records per Zap run. For lists with more than 100 contacts, you need the Looping by Zapier add-on to paginate through the results. Looping is available on Zapier's Professional plan ($49/month) and above. It is not included in the basic paid plans.
Task Billing Is Aggressive
Zapier bills per task. A single HubSpot → Google Sheets workflow that processes one contact typically consumes 2–3 tasks depending on how many steps your Zap has (trigger, formatter steps, the Sheets action). A list export of 1,000 contacts can cost 2,000–3,000 tasks in a single run. At Zapier's Professional plan, you get 2,000 tasks per month: a single large sync can exhaust your monthly quota.
Make.com Is More Generous
Make.com (formerly Integromat) charges per "operation" rather than per task, and its pricing is significantly more efficient for high-volume use. A 1,000-record sync might cost 1,000–2,000 operations, and Make.com's basic plans include 10,000 operations per month. For most small-to-medium HubSpot databases, Make.com is more cost-effective than Zapier for this use case.
The Fundamental Limitation
Both tools are trigger-based, meaning they are best at capturing events as they happen. They are not designed for scheduled bulk exports of a complete HubSpot dataset. If you need a full snapshot of all your contacts (or filtered by a complex property) refreshed weekly, you are working against the architecture of these tools.
Method 4: Google Apps Script + HubSpot API
Cost: Free Real-time: Scheduled (as frequent as every minute via time triggers) Code required: Yes (JavaScript)
HubSpot's API is free to use up to its rate limits, and Google Apps Script can call it directly. This is the most powerful free option and gives you full control over what data you pull, how you filter it, and how often it refreshes.
Getting Started: Private App Tokens
HubSpot deprecated API key authentication in 2022. You must now use a Private App token:
- In HubSpot, go to Settings > Integrations > Private Apps
- Create a new Private App
- Under "Scopes," select the objects you need:
crm.objects.contacts.read,crm.objects.deals.read, etc. - Copy the access token (it starts with
pat-) - Store this token in Apps Script > Project Settings > Script Properties as
HUBSPOT_TOKEN
Working Example: Export All Contacts with Pagination
HubSpot's v3 API paginates results using a cursor: each response includes an after value that you pass as a query parameter to get the next page. This is critical for lists with more than 100 contacts.
function syncHubSpotContactsToSheets() {
const token = PropertiesService.getScriptProperties().getProperty('HUBSPOT_TOKEN');
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Contacts')
|| SpreadsheetApp.getActiveSpreadsheet().insertSheet('Contacts');
sheet.clearContents();
// Define the properties you want to pull
const properties = [
'firstname', 'lastname', 'email', 'phone',
'lifecyclestage', 'hs_lead_status',
'hs_lifecyclestage_customer_date', // Hidden date - must be explicit
'createdate', 'lastmodifieddate',
'hs_v2_date_entered_customer' // Newer hidden lifecycle date
].join(',');
const headers = [
'First Name', 'Last Name', 'Email', 'Phone',
'Lifecycle Stage', 'Lead Status',
'Became Customer Date',
'Created Date', 'Last Modified',
'Entered Customer Stage'
];
sheet.appendRow(headers);
let after = null;
let totalRecords = 0;
do {
let url = `https://api.hubapi.com/crm/v3/objects/contacts?limit=100&properties=${properties}`;
if (after) url += `&after=${after}`;
const response = UrlFetchApp.fetch(url, {
headers: { 'Authorization': `Bearer ${token}` },
muteHttpExceptions: true
});
const statusCode = response.getResponseCode();
if (statusCode === 429) {
// Rate limited - HubSpot allows 100 requests per 10 seconds for private apps
Utilities.sleep(10000);
continue;
}
const data = JSON.parse(response.getContentText());
const contacts = data.results || [];
const rows = contacts.map(contact => {
const p = contact.properties;
return [
p.firstname || '',
p.lastname || '',
p.email || '',
p.phone || '',
p.lifecyclestage || '',
p.hs_lead_status || '',
p.hs_lifecyclestage_customer_date || '',
p.createdate || '',
p.lastmodifieddate || '',
p.hs_v2_date_entered_customer || ''
];
});
if (rows.length > 0) {
sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, rows[0].length).setValues(rows);
}
totalRecords += contacts.length;
after = data.paging?.next?.after || null;
// Small delay to respect rate limits
if (after) Utilities.sleep(200);
} while (after);
Logger.log(`Sync complete: ${totalRecords} contacts written to sheet`);
}Rate Limits to Know
HubSpot's API rate limits depend on your subscription:
| HubSpot Tier | API Rate Limit |
|---|---|
| Free / Starter | 100 requests per 10 seconds |
| Professional | 150 requests per 10 seconds |
| Enterprise | 200 requests per 10 seconds |
For most contact databases under 10,000 records, you will stay within these limits easily. For databases with 50,000+ contacts, plan for the sync to take several minutes and add appropriate Utilities.sleep() calls.
Scheduling the Sync
In Apps Script, go to Triggers (the clock icon) and set a time-based trigger to run syncHubSpotContactsToSheets daily, weekly, or at whatever interval you need. This is free and runs automatically without any manual steps.
The Honest Tradeoffs
Writing and maintaining this script takes real effort. Schema changes in HubSpot (new properties, renamed properties) require script updates. Rate limit handling, error logging, and dealing with HubSpot's various date formats add complexity. For a developer or technically-minded analyst, it is manageable. For a sales ops person who just needs the data, it is probably not the right investment.
Method 5: Third-Party Connectors
Cost: $20–$100/month depending on tool and plan Real-time: Scheduled refreshes (typically 15 min to daily) Code required: No
Several tools have built dedicated HubSpot → Google Sheets connectors that handle authentication, pagination, rate limiting, and scheduled refreshes without code.
brooked.io
brooked.io connects HubSpot (and other data sources) to Google Sheets with a visual interface for selecting objects and properties. It handles cursor pagination automatically, surfaces hidden properties like the hs_lifecyclestage_*_date fields that manual exports miss, and refreshes on a schedule you define. For teams that want the flexibility of a custom query without writing Apps Script, brooked.io supports SQL-style filtering on HubSpot data.
Coefficient
Coefficient is well-established in this space and has a strong HubSpot connector. It supports two-way sync (write back to HubSpot from Sheets), which most competitors do not. The free tier covers basic use cases; paid plans add scheduled refresh and higher row limits.
Superjoin
Superjoin is a Google Sheets add-on focused on connectors for SaaS tools. The HubSpot integration is solid and the setup takes about 10 minutes. It is competitive on pricing and tends to be favored by smaller teams who want a fast setup without enterprise pricing.
Dataslayer
Dataslayer is primarily a marketing analytics connector (Google Ads, Facebook, etc.) that has added HubSpot as a source. If you are already using Dataslayer for marketing data, it makes sense to consolidate your HubSpot data there too. If HubSpot is your primary use case, it is not the most focused tool for the job.
Comparison Table
| Method | Cost | Real-time? | Code? | Two-way? | Best for |
|---|---|---|---|---|---|
| Manual CSV Export | Free | No | No | No | One-time pulls, small teams |
| HubSpot for Sheets Extension | Free | No | No | Import only | Bulk imports INTO HubSpot |
| Zapier / Make.com | $10–$69/mo | Trigger-based | No | With extra steps | Event-driven syncs, small lists |
| Apps Script + HubSpot API | Free | Scheduled | Yes (JS) | With extra code | Developers, full control |
| brooked.io | Paid | Scheduled | No | Planned | Teams wanting automation without code |
| Coefficient | Free tier / Paid | Scheduled | No | Yes | Two-way sync needs |
| Superjoin | Paid | Scheduled | No | No | Fast setup, small teams |
| Dataslayer | Paid | Scheduled | No | No | Marketing teams consolidating data |
Troubleshooting
My CSV export is missing lifecycle stage date columns
HubSpot's lifecycle date properties (hs_lifecyclestage_lead_date, hs_lifecyclestage_customer_date, and the hs_v2_date_entered_* variants) are not included in default exports. When choosing properties to export, you must explicitly search for and add these. In the property chooser, search "date entered" to find the hs_v2_date_entered_* set.
Zapier is processing contacts but not all of them appear in my sheet
You are likely hitting the 100-record limit per Zap run. For larger lists, you need Looping by Zapier (Professional plan) to paginate through results. Alternatively, switch to Make.com which handles pagination more naturally in its data iterator module.
My Apps Script stops mid-sync with a 429 error
HubSpot is rate-limiting your requests. Add Utilities.sleep(1000) between API calls in your loop. For the contacts endpoint specifically, you can request up to 100 records per call: make sure you are using limit=100 to minimize the total number of requests.
Apps Script returns a 401 Unauthorized error
Your Private App token has expired or the scopes are incorrect. Go to HubSpot Settings > Private Apps, check that your app has the correct scopes (e.g., crm.objects.contacts.read), regenerate the token if needed, and update the value in Script Properties.
My dates appear as numbers (e.g., "1705276800000") in Google Sheets
HubSpot returns timestamps in Unix milliseconds for most date/datetime properties. To convert in Google Sheets: =TEXT(A2/86400000 + DATE(1970,1,1), "YYYY-MM-DD"). In Apps Script, you can convert before writing: new Date(parseInt(timestamp)).toISOString().split('T')[0].
The HubSpot for Google Sheets add-on does not show my contacts
This is the directional confusion issue described in Method 2. The add-on imports data into HubSpot. It does not export contacts to your sheet. You are using the right tool for the wrong job. Switch to Apps Script or a third-party connector.
The Bottom Line
The HubSpot → Google Sheets integration story has more friction than it should, and HubSpot has a genuine incentive to push you toward Operations Hub. Most teams do not need $720/year just to get their CRM data into a spreadsheet.
Here is the honest recommendation by team type:
Solo operators and small teams doing infrequent pulls: Manual CSV export is painful but free. Get comfortable with the date formatting gotchas and add the lifecycle date properties explicitly.
Marketing or sales ops with some technical comfort: Apps Script + HubSpot API is the best free automated option. The code in Method 4 will get you most of the way there in an afternoon. Set a weekly time trigger and you have a free automated sync.
Teams using Zapier already: Make.com is more cost-efficient for this specific use case. If you are already on Zapier Professional, the Looping add-on solves the record cap problem, but do the task math before you commit.
Non-technical teams who need reliable scheduled syncs: A third-party connector is worth the cost. The time saved not managing API tokens, rate limits, and script maintenance justifies $20–$50/month quickly. brooked.io and Coefficient are the most mature options for HubSpot specifically.
The $720/year Operations Hub spend only makes sense if you actually use Operations Hub features beyond the Google Sheets action. For most teams, it does not.
Sync HubSpot to Google Sheets Without the Operations Hub Tax
brooked.io connects HubSpot contacts, companies, deals, and custom objects to Google Sheets on a schedule you control, no Operations Hub required, no code, no CSV exports. It handles pagination, rate limits, hidden lifecycle date properties, and ISO date formatting automatically.
Set up a sync in minutes and stop paying for a $720/year plan just to get your own data into a spreadsheet.
Start your free trial at brooked.io →
Troubleshooting quick reference
Frequently asked questions
Do I need Operations Hub to sync HubSpot to Google Sheets?
No. Operations Hub Professional ($720/year) is required only for HubSpot's native Workflow → Google Sheets action. You can sync data using the free HubSpot API via Apps Script, Zapier, Make.com, or third-party connectors like brooked.io and Coefficient: all without an Operations Hub subscription.
What is the difference between HubSpot Data Sync and a Google Sheets integration?
HubSpot Data Sync (included in Operations Hub) syncs HubSpot records with other CRM and contact database tools. Salesforce, Pipedrive, Zoho, Mailchimp, and similar platforms. It does not have a Google Sheets connector. The Google Sheets workflow action (separate from Data Sync) is the actual feature that requires Operations Hub Professional.
Can I sync deals and companies, not just contacts?
Yes. HubSpot's API exposes all CRM objects: contacts, companies, deals, tickets, and custom objects. The Apps Script example in this article covers contacts, but the same pagination pattern works for /crm/v3/objects/deals, /crm/v3/objects/companies, and others. Third-party connectors like brooked.io and Coefficient also support all standard objects.
How do I pull HubSpot report data into Google Sheets?
HubSpot's reporting API is separate from the CRM objects API and has more limited export options. For most reporting use cases, the practical approach is to build the underlying data pull in Google Sheets (e.g., all contacts with relevant properties) and then build your report logic using QUERY() or pivot tables in the sheet itself. True report embedding (pulling a saved HubSpot report directly into Sheets) is not supported by any of the methods in this article.
Is there a free way to get HubSpot data into Google Sheets automatically?
Yes. Google Apps Script with the HubSpot API is free and can be scheduled to run automatically. It requires JavaScript skills and some setup time, but there are no ongoing costs beyond the time you spend building and maintaining the script. See Method 4 above for a complete working example with pagination and rate limit handling.
What HubSpot properties are commonly missed in exports?
The most commonly missed properties are the lifecycle stage timestamp fields. HubSpot tracks when each contact entered each lifecycle stage, but these properties are not in default exports and are easy to overlook in the property chooser. They are: - hs_lifecyclestage_lead_date - hs_lifecyclestage_marketingqualifiedlead_date - hs_lifecyclestage_salesqualifiedlead_date - hs_lifecyclestage_opportunity_date - hs_lifecyclestage_customer_date - The newer hs_v2_date_entered_ equivalents These are inva
Can I write data back from Google Sheets to HubSpot?
Yes, but it requires additional setup. The HubSpot API supports PATCH requests to update records, and Apps Script can make these. Coefficient also supports two-way sync with HubSpot as a built-in feature. This is a more complex workflow and carries risks (overwriting production data with stale spreadsheet data), so approach it carefully and always use a staging/test property first.
Ready to connect your data to Google Sheets?
Brooked's free tier covers 100 imports per month with AI Analyst included, no credit card required.
Install Brooked free →

