> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superjoin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Upsert data into HubSpot from your Spreadsheet

> Step-by-step guide for upserting data from Google Sheets or Microsoft Excel to HubSpot

<Tabs>
  <Tab id="gsheets" title="Google Sheets">
    <iframe width="560" height="315" src="https://www.youtube.com/embed/4k3eNbJstjY?si=HGbAeOcw9mVNW9ki" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

    ## Understanding Upserts in HubSpot

    **What is an Upsert?** An upsert operation allows you to both insert new records and update existing ones in a single action.

    **Why can't we use HubSpot Record IDs?** HubSpot's native Record IDs are **read-only** fields. This means:

    * ✅ You can use them to **update** existing records
    * ❌ You **cannot** use them to **insert** new records (because new records don't have Record IDs yet)

    **The Solution:** To enable upserts, we need to create a custom unique identifier field in HubSpot that can handle both new and existing records.

    <Note>
      **Supported Objects:** Upserts are available for the following HubSpot objects:

      **CRM Objects:** Contacts, Companies, Deals, Leads, Tickets

      **Commerce Objects:** Products, Quotes, Line Items, Carts, Discounts, Fees, Invoices, Orders, Taxes

      **Engagement Objects:** Calls, Emails, Meetings, Notes, Tasks, Communications, Postal Mails
    </Note>

    ***

    ## Part 1: Setup in HubSpot

    <Info>
      **Why are we doing this?** We need to create a custom unique identifier field in HubSpot that works for both new and existing records, since the built-in Record ID cannot be used for inserts.
    </Info>

    <Steps>
      <Step title="Click Settings in HubSpot">
        Click the `Settings` button that's on the navigation bar.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert01.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=daf5325ae87514714d887fae40148f82" alt="HubSpot Settings" width="2880" height="1800" data-path="images/hubspot/upsert01.png" />
        </Frame>
      </Step>

      <Step title="Navigate to Properties">
        Scroll down the Settings sidebar menu on the left and click on `Properties`

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert02.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=fcff14a6cb7f2fdb0858b4d7364978bf" alt="Properties Menu" width="2880" height="1800" data-path="images/hubspot/upsert02.png" />
        </Frame>
      </Step>

      <Step title="Create a new property">
        Select the Object in which you want to create this new field in then click on the orange colored button on the right called `Create property`

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert03.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=0e37ef8b653160bc4dd67e2b9656c26b" alt="Create Property" width="2880" height="1800" data-path="images/hubspot/upsert03.png" />
        </Frame>
      </Step>

      <Step title="Fill in property details">
        Fill in the details of the field.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert1.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=4d86a4f64bde9e6fdd862aba24f0be66" alt="Property Details" width="2880" height="1800" data-path="images/hubspot/upsert1.png" />
        </Frame>
      </Step>

      <Step title="Set field type to Number">
        Choose `Number` as the field type.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert2.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=863f98650a577415e61c4c3aff3e60f4" alt="Field Type" width="2880" height="1800" data-path="images/hubspot/upsert2.png" />
        </Frame>
      </Step>

      <Step title="Make the field unique">
        **Important:** Make sure to check the "Unique value" option (as shown in the image). This ensures each record has a distinct identifier. Click the orange `Create` button on the top right.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert3.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=33194d27a7329cdeaae6dcc35012da81" alt="Unique Value Option" width="2880" height="1800" data-path="images/hubspot/upsert3.png" />
        </Frame>

        <Tip>
          **Why make it unique?** This field will be used to identify records. Making it unique prevents duplicate records and ensures accurate upserts.
        </Tip>
      </Step>
    </Steps>

    ***

    ## Part 2: Setup and Upsert in Superjoin

    <Info>
      **What are we doing now?** We'll prepare your Google Sheets with the custom unique identifier, validate it with HubSpot, and then perform upserts.
    </Info>

    <Steps>
      <Step title="Create the unique identifier field in Google Sheets">
        In your Google Sheet, create a new column with the **same name** as the HubSpot field you just created.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert4.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=6e8e3fc6d05a9ea362b48ab48e5892ca" alt="Create Column in Google Sheets" width="2880" height="1800" data-path="images/hubspot/upsert4.png" />
        </Frame>

        <Note>
          The column name must match exactly with your HubSpot property name for proper mapping.
        </Note>
      </Step>

      <Step title="Populate the field with unique values">
        Now you need to fill this column with unique values:

        <CardGroup cols={2}>
          <Card title="For existing records" icon="arrows-rotate">
            Copy the HubSpot Record IDs into this new field
          </Card>

          <Card title="For new records" icon="plus">
            Use any unique numbers (e.g., 10001, 10002, etc.)
          </Card>
        </CardGroup>

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert5.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=e193f1201b0e2ea5dc827d4156efa539" alt="Populate Unique Values" width="2880" height="1800" data-path="images/hubspot/upsert5.png" />
        </Frame>

        <Warning>
          ⚠️ **Every value in this column must be unique.** Duplicates will cause upsert failures.
        </Warning>

        <Info>
          **Don't have Record IDs?** If you don't have Record IDs for existing records, check out the [FAQ: What if I don't have Record IDs?](#what-if-i-dont-have-record-ids-to-fill-the-unique-field-with) below to learn how to import them from HubSpot first.
        </Info>
      </Step>

      <Step title="Choose Update action">
        **Why this step?** Before HubSpot allows upserts using your custom field, it needs to see the field populated with data at least once. We'll do a one-time update to validate it.

        Choose the `Update` action and click `Next`.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert6.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=03ea3268eb3d9ffbebe65a763f563e5d" alt="Choose Update Action" width="2880" height="1800" data-path="images/hubspot/upsert6.png" />
        </Frame>
      </Step>

      <Step title="Map fields including custom ID">
        Map all the fields to their respective HubSpot fields, **including your new custom unique identifier field**. Click `Save` and then click `Export`.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert7.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=dc4ab134f165ff808987545082ce294e" alt="Map Fields" width="2880" height="1800" data-path="images/hubspot/upsert7.png" />
        </Frame>
      </Step>

      <Step title="Select entire sheet to update">
        Select the `Entire Sheet` option, then click `Next` and update the data.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert8.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=fd1b48aea5798ac8b49e10bf4bebd42a" alt="Select Entire Sheet" width="2880" height="1800" data-path="images/hubspot/upsert8.png" />
        </Frame>
      </Step>

      <Step title="Validation complete">
        **What happened?** Your existing records were updated with the custom unique identifier values. New records were skipped (since the `Update` action can't insert new data).

        Your custom field is now validated and ready for upserts! ✅

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert9.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=ba7215cef00960543f9f78fe09e4509a" alt="Validation Results" width="2880" height="1800" data-path="images/hubspot/upsert9.png" />
        </Frame>

        <Note>
          This validation step only needs to be done once. After this, you can perform upserts freely.
        </Note>
      </Step>

      <Step title="Choose Upsert action">
        **Now the magic happens!** You can update existing records AND insert new records in a single operation.

        Choose the `Upsert` action and click `Next`.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert10.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=7b20642598fe790facbfc524cdf60162" alt="Choose Upsert Action" width="2880" height="1800" data-path="images/hubspot/upsert10.png" />
        </Frame>
      </Step>

      <Step title="Map fields for upsert">
        Map your fields carefully:

        * ✅ **Do include:** Your custom unique identifier field and all data fields you want to sync
        * ❌ **Don't include:** HubSpot `Record ID` field or any Superjoin-generated metadata fields (like sync timestamps)

        Click `Save` and then click `Export`.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert11.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=33135fcb8027775f83cb962e91087a62" alt="Map Upsert Fields" width="2880" height="1800" data-path="images/hubspot/upsert11.png" />
        </Frame>
      </Step>

      <Step title="Select rows to upsert">
        Select the entire sheet or specific rows you want to upsert, then click `Next` and run the upsert.

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert12.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=18d369a4d863f7e2d763b697c63a9f20" alt="Select Rows" width="2880" height="1800" data-path="images/hubspot/upsert12.png" />
        </Frame>
      </Step>

      <Step title="Upsert complete!">
        🎉 **Success!** Your data has been upserted to HubSpot.

        **What just happened:**

        * Existing records (matched by your custom unique ID) were updated
        * New records were inserted into HubSpot
        * All in one seamless operation!

        <Frame>
          <img src="https://mintcdn.com/superjoin/gjRFjFkthepgDSdX/images/hubspot/upsert13.png?fit=max&auto=format&n=gjRFjFkthepgDSdX&q=85&s=62b1630c4e7fc8e1523237763d4ba459" alt="Upsert Success" width="2880" height="1800" data-path="images/hubspot/upsert13.png" />
        </Frame>

        This completes the process of using Superjoin to upsert data from Google Sheets to HubSpot.<br />
        Below are the steps to automate this process.
      </Step>

      <Step title="Automate the process">
        Now you'll see a card called `Automatic Exports`. Click on the `Create Schedule` button.

        <Frame>
          <img src="https://mintcdn.com/superjoin/ti4mZujLxipbXAga/images/hubspot/hs-export-common8.png?fit=max&auto=format&n=ti4mZujLxipbXAga&q=85&s=0a9b39f462b9b8f00651e05829b7273f" alt="Automatic Exports" width="1254" height="1104" data-path="images/hubspot/hs-export-common8.png" />
        </Frame>
      </Step>

      <Step title="Create a schedule">
        Configure the frequency in which you want this upsert process to repeat.

        <Frame>
          <img src="https://mintcdn.com/superjoin/ti4mZujLxipbXAga/images/hubspot/hs-export-common9.png?fit=max&auto=format&n=ti4mZujLxipbXAga&q=85&s=9d038776555b9438fe2e09a7e6237ff2" alt="Schedule Configuration" width="984" height="962" data-path="images/hubspot/hs-export-common9.png" />
        </Frame>
      </Step>
    </Steps>

    ***

    ## Summary

    You've successfully set up upserts from Google Sheets to HubSpot! Here's what you accomplished:

    1. ✅ Created a custom unique identifier field in HubSpot (since Record IDs are read-only)
    2. ✅ Populated your Google Sheets with unique values
    3. ✅ Validated the field with an initial update
    4. ✅ Enabled seamless upserts that can insert new records and update existing ones

    Now you can modify data in Google Sheets and push all changes to HubSpot in one operation!

    ***

    ## Frequently Asked Questions

    <AccordionGroup>
      <Accordion title="Can I use multiple primary keys for upserts (e.g., Record ID and my custom unique ID)?">
        **No, you cannot use multiple primary keys for upsert operations.**

        HubSpot requires a **single unique identifier** to match and upsert records. Here's why:

        * **How upserts work:** When you perform an upsert, HubSpot looks at the unique identifier field to determine if a record already exists. If it finds a match, it updates that record; if not, it creates a new one.

        * **Why only one:** Having multiple primary keys would create ambiguity. For example, if Record ID matches but your custom ID doesn't, HubSpot wouldn't know whether to update the existing record or create a new one.

        * **Record ID limitation:** Remember that HubSpot Record IDs cannot be used as the primary key for upserts because they are read-only and don't exist for new records yet.

        **Best practice:** Use your custom unique identifier field (the one you created in this guide) as the single source of truth for all upsert operations.
      </Accordion>

      <Accordion title="I get an error &#x22;Requires Unique ID to upsert&#x22; - how do I fix this?">
        This error means HubSpot doesn't have a validated unique identifier field to use for matching records during upsert operations.

        **Quick fix - follow these steps:**

        1. **Create a custom unique field in HubSpot:**
           * Go to Settings → Properties in HubSpot
           * Create a new Number field with the "Unique value" option enabled
        2. **Add the field to Google Sheets:**
           * Create a column with the same name as your HubSpot field
           * Fill it with unique values (use Record IDs for existing records, unique numbers for new records)
        3. **Validate the field:**
           * Run a one-time **Update** operation (not upsert) to push the unique values to HubSpot
           * This validates the field and populates existing records with your custom IDs
        4. **Now try upsert again:**
           * Select the **Upsert** action
           * Map your custom unique identifier field
           * Your upserts will now work!

        **Tip:** Make sure you've completed the validation step (step 3). Without it, HubSpot won't recognize your custom field as valid for upsert operations.
      </Accordion>

      <Accordion title="Why can't I use HubSpot's Record ID for upserts?">
        **HubSpot Record IDs are read-only fields**, which creates a fundamental limitation for upsert operations.

        Here's the problem:

        **For existing records:**

        * ✅ Record IDs work perfectly for **updates**
        * Every existing record already has a Record ID assigned by HubSpot

        **For new records:**

        * ❌ Record IDs **don't exist yet** - they're only assigned after a record is created
        * You can't provide a Record ID when inserting a new record
        * This makes Record IDs incompatible with the "insert" part of "upsert"

        **What is an upsert?**

        * An upsert combines **insert** (create new records) + **update** (modify existing records) in one operation
        * It needs a unique identifier that works for both scenarios

        **The solution:**

        * Create a **custom unique identifier field** that you control
        * For existing records: populate it with Record IDs or other unique values
        * For new records: assign unique numbers (e.g., 10001, 10002, etc.)
        * This field works for both inserts and updates, enabling true upsert functionality

        **In summary:** Record IDs are perfect for updates only, but upserts need a field that can handle both new and existing records - which is why you need a custom unique identifier.
      </Accordion>

      <Accordion title="What if I don't have Record IDs to fill the unique field with?">
        If you don't already have HubSpot Record IDs in your Google Sheet, you'll need to import them first. **Record IDs are required for existing records** to properly identify and update them during upserts.

        **Solution: Import data from HubSpot first**

        Use Superjoin to import your existing HubSpot records into Google Sheets, which will automatically pull the Record IDs along with your data:

        1. **Import your HubSpot data:**
           * Use Superjoin's import feature to pull data from HubSpot
           * Make sure to include the **Record ID** field in your import
           * This will create a sheet with all your existing records and their HubSpot Record IDs
        2. **Populate your custom unique field:**
           * Copy the Record IDs from the imported data
           * Paste them into your custom unique identifier field
           * For any new records you want to add, use unique numbers (e.g., 10001, 10002, etc.)
        3. **Continue with the upsert process:**
           * Follow the validation and upsert steps from this guide
           * Your existing records will be matched using the Record IDs you imported

        **Why is this necessary?**

        * **Existing records:** Need their original HubSpot Record IDs so the system can match and update them correctly
        * **New records:** Can use any unique numbers since they don't exist in HubSpot yet
        * **Without Record IDs:** You risk creating duplicate records instead of updating existing ones

        <Info>
          **Need help importing?** Check out our [complete guide on importing data from HubSpot](/integrations/hubspot/import) to learn how to pull your existing records with their Record IDs.
        </Info>
      </Accordion>
    </AccordionGroup>

    ***

    ##### Hope this guide helped you export your data from Google Sheets to HubSpot using Superjoin.

    ##### If you have any questions or need further assistance, please don't hesitate to reach out to our support team. Thank you!
  </Tab>

  <Tab id="excel" title="Microsoft Excel">
    #### Coming Soon!
  </Tab>
</Tabs>
