Intermediate~20 min setupProductivity & CRMVerified April 2026
Google Sheets logo
HubSpot logo

Deal pipeline export — HubSpot to Google Sheets in n8n

Every morning, export all active deals from HubSpot to a Google Sheet with deal name, stage, value, and owner.

Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.

Best for

Sales teams needing daily deal visibility in spreadsheets for reporting or external sharing

Not ideal for

Teams wanting real-time updates or complex multi-stage deal workflows

Sync type

scheduled

Use case type

reporting

Real-World Example

💡

A SaaS startup's sales director shares deal pipeline updates with the board every week using Google Sheets. The sales team lives in HubSpot but board members prefer spreadsheets. Without automation, someone spends 45 minutes every Monday morning copying 150+ active deals, updating values, and reformatting data. This workflow exports the entire pipeline in under 2 minutes with consistent formatting.

What Will This Cost?

Drag the slider to your expected monthly volume.

/mo
505005K50K

Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.

Prices shown for annual billing. Based on published pricing as of April 2026.

Estimated ROI

1000

min saved/mo

$583

labor value/mo

Free

no platform cost

Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.

Implementation

Skip the setup

Import this workflow directly into n8n

Copy the pre-built n8n blueprint and paste it straight into n8n. All modules, filters, and field mappings are already configured — you just need to connect your accounts.

Before You Start

Make sure you have everything ready.

HubSpot account with a Private App configured (scopes: crm.objects.deals.read, crm.objects.owners.read)
Google Sheets document created and shared with the service account email
n8n instance running (self-hosted or n8n Cloud) with HubSpot and Google Sheets nodes available
Super Admin access in HubSpot to create the Private App (one-time setup)

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Deal Namedealname
Deal Stagedealstage
Deal Amountamount
Deal Ownerhubspot_owner_id
3 optional fields▸ show
Close Dateclosedate
Deal Sourcedeal_source
Company Nameassociatedcompanyid

Step-by-Step Setup

1

Create new workflow in n8n

Log into your n8n instance and click the '+' button to create a new workflow. Name it 'Daily Deal Pipeline Export' in the top-left field. Click 'Save' to store the workflow. You'll see an empty canvas with a 'Start' node already placed. This workflow will run on a schedule, so you won't need manual triggers.

2

Add schedule trigger node

Click the '+' button next to the Start node and search for 'Schedule Trigger'. Select it from the list. In the node settings, set Mode to 'Every Day' and Time to '08:00' (or your preferred morning time). Set Timezone to match your business location. This ensures the export runs every morning at the same time, giving your team fresh data to start the day.

Common mistake — Check your n8n instance timezone in Settings. If it differs from your business timezone, deals might export at unexpected hours.
n8n
+
click +
search apps
Google Sheets
GO
Google Sheets
Add schedule trigger node
Google Sheets
GO
module added
3

Connect HubSpot node

Add a new node and search for 'HubSpot'. Choose the HubSpot node and set the Resource to 'Deal' and Operation to 'Get All'. Authenticate with your HubSpot account by clicking 'Create New Credential' and following the OAuth flow. Once connected, set 'Return All' to true. Then add a second HubSpot node after it — set Resource to 'Owner' and Operation to 'Get All'. This fetches the owner directory so you can resolve owner IDs to real names in the transform step.

Common mistake — The HubSpot connection requires admin permissions. If authentication fails, ask your HubSpot admin to grant API access to your account.
4

Filter active deals only

Add a 'Filter' node after HubSpot. Set the condition to 'String' -> 'Equal' and configure it to filter where 'dealstage' does not equal 'closedwon' and does not equal 'closedlost'. You might need to add multiple conditions using 'Add Condition' depending on your deal stage names. This prevents closed deals from cluttering your daily export with historical data.

Common mistake — Filters are the most common place setups break. Double-check the field name and value exactly match what your app sends — a single capital letter difference will block everything.
Google Sheets
GO
trigger
filter
Deal Stage
≠ "Closed"
yes — passes through
no — skipped
HubSpot
HU
notified
5

Transform and resolve owner names

Add a 'Code' node to clean up the HubSpot data. The deal API returns owner IDs like '12345' instead of names, and amounts as unformatted strings. Use the code snippet from the pro tip section below — it cross-references the Owners API response to output readable names like 'Sarah Johnson' and formats currency with dollar signs. Connect both the Deals and Owners HubSpot nodes as inputs to this Code node.

Common mistake — HubSpot custom properties use internal names, not display names. Check your HubSpot property settings if fields come through as 'undefined'.

HubSpot returns owner IDs (like "12345") instead of names. This Code node cross-references the Owners API response to output readable names like "Sarah Johnson." You need a separate HubSpot node set to Resource: Owner, Operation: Get All before this step.

JavaScript — Code Node// Clean HubSpot deal data for Google Sheets
▸ Show code
// Clean HubSpot deal data for Google Sheets
// Requires: HubSpot node (Get All Owners) run before this step
// Pass owner list as items[0] and deals as items[1], or merge them upstream

... expand to see full code

// Clean HubSpot deal data for Google Sheets
// Requires: HubSpot node (Get All Owners) run before this step
// Pass owner list as items[0] and deals as items[1], or merge them upstream

const ownerMap = {};
// Build owner lookup from the Owners API response
// If you passed owners through a Set node, adjust the path accordingly
const owners = items.filter(i => i.json.firstName);
owners.forEach(o => {
  ownerMap[o.json.id] = `${o.json.firstName} ${o.json.lastName}`;
});

const deals = items.filter(i => i.json.properties);
const cleanDeals = deals.map(deal => ({
  'Deal Name': deal.properties.dealname || 'Unnamed Deal',
  'Stage': deal.properties.dealstage
    ?.replace(/([a-z])([A-Z])/g, '$1 $2')
    .replace(/^./, str => str.toUpperCase()),
  'Amount': deal.properties.amount
    ? `$${parseFloat(deal.properties.amount).toLocaleString()}`
    : '$0',
  'Owner': ownerMap[deal.properties.hubspot_owner_id] || 'Unassigned'
}));

return cleanDeals.map(deal => ({ json: deal }));
6

Clear existing Google Sheet data

Add a 'Google Sheets' node and set Operation to 'Clear'. Select your target spreadsheet and worksheet name. Set Range to 'A2:Z1000' to clear old data but preserve your header row in row 1. This prevents duplicate entries from accumulating over time while keeping your column headers intact for easy reading.

7

Write headers to Google Sheet

Add another 'Google Sheets' node and set Operation to 'Append'. Configure it to write to range 'A1:D1' with values: 'Deal Name', 'Stage', 'Amount', 'Owner'. Set 'Value Input Mode' to 'Raw' and input the headers as a single row array. This ensures your export always has proper column labels even if you're starting with a blank sheet.

Common mistake — If your sheet already has headers, skip this step or you'll get duplicate header rows on every run.
8

Write deal data to sheet

Add a final 'Google Sheets' node with Operation set to 'Append'. Connect it to receive data from your Code node. Set 'Value Input Mode' to 'Raw' and configure it to write the transformed deal data starting from row 2. The node will automatically write all deals as separate rows, creating a complete pipeline snapshot in your spreadsheet.

9

Configure error handling

Click on each node and go to Settings -> 'Continue on Error'. Enable this for all nodes except the final Google Sheets append. This way if HubSpot is temporarily unavailable, your workflow won't crash completely. Add an 'IF' node after HubSpot to check if data exists before proceeding to Google Sheets operations.

Common mistake — Without error handling, a single API timeout can break your entire daily export routine.
10

Test and activate workflow

Click 'Execute Workflow' to run a test. Check your Google Sheet to verify deals appear correctly with proper formatting. Review the execution log for any errors or warnings. Once confirmed working, toggle the 'Active' switch in the top-right to enable daily scheduled runs. The workflow will now export your deal pipeline every morning automatically.

n8n
▶ Run once
executed
Google Sheets
HubSpot
HubSpot
🔔 notification
received

Scaling Beyond 500+ Records

If your volume exceeds 500 records, apply these adjustments.

1

Add pagination handling

For deals over 500, split the HubSpot query into batches using the 'Limit' parameter and loop through results to avoid API timeouts.

2

Implement incremental updates

Instead of clearing the entire sheet daily, track the last update timestamp and only export deals modified since the last run to reduce processing time.

3

Use multiple Google Sheets

Split deals by stage or owner into separate worksheets within the same Google Sheets document to improve readability and performance for large datasets.

Going live

Production Checklist

Before you turn this on for real, confirm each item.

Troubleshooting

Common errors and how to fix them.

Frequently Asked Questions

Common questions about this workflow.

Analysis

VerdictWhy n8n for this workflow

Use n8n for this if you need full control over data transformation and have complex deal stage logic. n8n's Code nodes let you format currency, clean stage names, and handle missing data exactly how your team needs it. You also get unlimited executions on self-hosted instances, making it cost-effective for daily exports. Skip n8n if you just need basic field copying without transformation — Zapier's HubSpot integration is simpler for straightforward exports.

Cost

This workflow uses 1 execution per day. At 30 runs per month, that's essentially free on n8n Cloud's starter plan or any self-hosted setup. Zapier would cost $20/month for the same schedule since their HubSpot integration requires a paid plan. Make.com falls in the middle at around $9/month, but you'll hit operation limits faster with large deal volumes.

Tradeoffs

Make has better visual pipeline stage mapping and handles HubSpot's nested data structure more elegantly out of the box. Zapier offers pre-built Google Sheets formatting options that save setup time for basic reports. But n8n wins for flexibility — its Code nodes let you build custom deal calculations, handle missing owners gracefully, and format currency exactly how your board expects to see it without wrestling with platform limitations.

You'll discover that HubSpot's deal owner field returns cryptic ID numbers, not names, requiring an extra API call to make your export human-readable. The Google Sheets API occasionally times out during peak hours, so morning schedules work better than afternoon ones. Deal amounts come through as strings with inconsistent currency formatting that will break any spreadsheet formulas until you clean them in the Code node.

Ideas for what to build next

  • Add deal stage change notificationsBuild a webhook-triggered workflow that sends Slack messages when deals move to 'Closed Won' or get stuck in one stage too long.
  • Create weekly pipeline summary emailSchedule a weekly digest that calculates total pipeline value, deals by stage, and sends formatted reports to your sales leadership team.
  • Build reverse sync for deal updatesAllow sales teams to update deal amounts or close dates directly in Google Sheets and sync those changes back to HubSpot automatically.

Related guides

Was this guide helpful?
Google Sheets + HubSpot overviewn8n profile →