---
title: How to Pull HubSpot Data Directly Into Excel Without a Third-Party Integration
description: Learn how to pull HubSpot data directly into Excel using an API script, eliminating the need for third-party integrations. Automate and simplify your data processes.
---

[WHInsights](https://www.whimpact.co/wh1nsights)

# [How to Pull HubSpot Data Directly Into Excel Without a Third-Party Integration](https://www.whimpact.co/wh1nsights/how-to-pull-hubspot-data-directly-into-excel-without-a-third-party-integration)

 Written by [Ryan Schweighart](https://www.whimpact.co/wh1nsights/author/ryan-schweighart) | Apr 3, 2025 11:29:35 PM

If you want to pull HubSpot company data directly into Excel—without using a third-party tool—this guide will show you how.

### Why Do This?

One of my clients needed to regularly compare HubSpot company records with another data source. Instead of manually exporting and formatting data every month, we automated the process using Excel and a HubSpot API script—no third-party integrations required.

 

### Step 1: Create a Private App in HubSpot

1. Go to **Settings** in HubSpot.
2. Under **Integrations**, select **Private Apps**.
3. Click **Create a private app**.
4. Give it a name and description.
5. Under **Scopes**, add:
   
     - `crm.objects.companies.read`
     - `crm.schemas.companies.read`
6. Save the app and copy your **access token** (you’ll need it later).

### Step 2: Set Up Excel to Pull HubSpot Data

1. Open a new or existing Excel workbook.
2. Go to the **Data** tab > **Get Data** > **From Other Sources** > **Blank Query**.
3. Open the **Advanced Editor** (found in the Home tab).
4. Paste in the custom Power Query script (available below).
5. Replace the placeholder token with your **HubSpot private app token**.
6. Define which properties you want to retrieve from the API using the `properties` list in the script.
7. Click **Done** > **Close & Load**.

The script handles pagination, so it will pull more than 100 records if needed.

### Step 3: Customize the Data

To pull additional HubSpot properties (like country or region):

1. Find the **internal name** of the property in HubSpot (not the label).
2. Add the internal name to the `properties` list in the script.
3. Refresh the Excel query to see the new data appear.

### Refresh and Update

After setup, updating your HubSpot data in Excel is as easy as clicking **Refresh** in the workbook. Any new records or updates in HubSpot will be reflected in Excel.

### Use Cases

This method works for more than just company data. You can adapt it to pull contacts, deals, or other objects by modifying the endpoint and properties in the script.

### Final Thoughts

This method eliminates unnecessary tools and gives you direct control over your data. It’s simple, secure, and flexible for various HubSpot reporting needs.

### Power Query Script

`let`  
`    // ===============================`  
`    // 1) Replace with your Token`  
`    // ===============================`  
`    AccessToken = "{your_access_token}",`

`    // ------------------------------------------------------------------------------`  
`    // 2) Base URL and pagination settings`  
`    // ------------------------------------------------------------------------------`  
`    baseUrl = "https://api.hubapi.com/crm/v3/objects/companies",`  
`    pageSize = 100, // maximum is 100`

`    // ------------------------------------------------------------------------------`  
`    // 3) Define the list of properties we want returned`  
`    //    (These are appended as multiple &properties=XYZ in the query string)`  
`    // ------------------------------------------------------------------------------`  
`    PropertiesList = {`  
`        "name",`  
`        "address",`  
`        "address2",`  
`        "city",`  
`        "state",`  
`        "zip",`  
`        "phone",`  
`        "fax",`  
`        "email",`  
`        "country",`  
`        "hs_country_code",`  
`        "createdate"`  
`    },`

`    // ------------------------------------------------------------------------------`  
`    // 4) Generate the query segment for the properties`  
`    //`  
`    //    This will produce something like:`  
`    //    "properties=owner_number___ogsys&properties=name&properties=active&..."`  
`    // ------------------------------------------------------------------------------`  
`    PropertiesQueryString = Text.Combine(`  
`        List.Transform(PropertiesList, each "properties=" & _),`  
`        "&"`  
`    ),`

`    // ------------------------------------------------------------------------------`  
`    // 5) Recursive function to get pages`  
`    // ------------------------------------------------------------------------------`  
`    GetPage = (after as text) =>`  
`        let`  
`            // If no 'after' (i.e. first page), don't include it in the query.`  
`            url = `  
`                if after = "" then`  
`                    baseUrl `  
`                    & "?" `  
`                    & PropertiesQueryString `  
`                    & "&limit=" `  
`                    & Number.ToText(pageSize)`  
`                else`  
`                    baseUrl `  
`                    & "?" `  
`                    & PropertiesQueryString `  
`                    & "&limit=" `  
`                    & Number.ToText(pageSize) `  
`                    & "&after=" `  
`                    & after,`

`            // Make the API call`  
`            Source = Json.Document(`  
`                Web.Contents(`  
`                    url,`  
`                    [`  
`                        Headers = [`  
`                            Authorization = "Bearer " & AccessToken,`  
`                            #"Content-Type" = "application/json"`  
`                        ]`  
`                    ]`  
`                )`  
`            ),`

`            // 'results' is the array of company objects`  
`            results = if Record.HasFields(Source, "results") `  
`                      then Source[results] `  
`                      else {},`

`            // 'paging' is the record that may contain 'next' info`  
`            paging = if Record.HasFields(Source, "paging") `  
`                     then Source[paging]`  
`                     else null,`

`            // If 'paging.next.after' exists, store that. Otherwise it's null.`  
`            nextAfter = `  
`                if paging <> null `  
`                   and Record.HasFields(paging, "next") `  
`                   and Record.HasFields(paging[next], "after") `  
`                then paging[next][after] `  
`                else null,`

`            // Recursively combine results with next pages if nextAfter is present`  
`            combined = `  
`                if nextAfter <> null then`  
`                    List.Combine({results, @GetPage(Text.From(nextAfter))})`  
`                else`  
`                    results`  
`        in`  
`            combined,`

`    // ------------------------------------------------------------------------------`  
`    // 6) Retrieve all data by calling GetPage() starting with an empty 'after'`  
`    // ------------------------------------------------------------------------------`  
`    data = GetPage(""),`

`    // ------------------------------------------------------------------------------`  
`    // 7) Convert the list of records into a table`  
`    // ------------------------------------------------------------------------------`  
`    #"Converted to Table" = Table.FromList(data, Splitter.SplitByNothing(), null, null, ExtraValues.Error),`

`    // ------------------------------------------------------------------------------`  
`    // 8) Expand the top-level record columns (id, properties, etc.)`  
`    // ------------------------------------------------------------------------------`  
`    #"Expanded Record" = Table.ExpandRecordColumn(`  
`        #"Converted to Table", `  
`        "Column1", `  
`        {"id", "properties"}, `  
`        {"id", "properties"}`  
`    ),`

`    // ------------------------------------------------------------------------------`  
`    // 9) Expand the requested properties into columns`  
`    // ------------------------------------------------------------------------------`  
`    #"Expanded properties" = Table.ExpandRecordColumn(`  
`        #"Expanded Record",`  
`        "properties",`  
`        PropertiesList,`  
`        PropertiesList`  
`    )`  
`    in`  
`    #"Expanded properties"`

[View full post](https://www.whimpact.co/wh1nsights/how-to-pull-hubspot-data-directly-into-excel-without-a-third-party-integration)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Ryan Schweighart"
  },
  "dateModified" : "2025-04-03T23:29:35.371Z",
  "datePublished" : "2025-04-03T23:29:35Z",
  "headline" : "How to Pull HubSpot Data Directly Into Excel Without a Third-Party Integration",
  "image" : {
    "@type" : "ImageObject",
    "height" : 1080,
    "url" : "https://20619232.fs1.hubspotusercontent-na1.net/hubfs/20619232/2025.04.03_whinsight.png",
    "width" : 1920
  },
  "mainEntityOfPage" : "https://www.whimpact.co/wh1nsights/how-to-pull-hubspot-data-directly-into-excel-without-a-third-party-integration",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60.0,
      "url" : "https://20619232.fs1.hubspotusercontent-na1.net/hubfs/20619232/WHInsights%20Logo%2043.png",
      "width" : 80.0
    },
    "name" : "WHInsights"
  }
}
```