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

# Connect HubSpot

> Paste a HubSpot private app token and PipeLime creates contacts, notes and email history in your portal.

export const UiPath = ({children}) => {
  const parts = String(children).split(/\s*(?:→|>)\s*/).filter(Boolean);
  return <span className="pl-path">
      {parts.map((part, index) => <span key={`${index}-${part}`}>
          {index > 0 && <span className="pl-path__sep">→</span>}
          {part}
        </span>)}
    </span>;
};

export const Screenshot = ({id, alt, caption, frame = 'browser', url, marks = [], lang = 'en', workspace = 'northwind-outbound'}) => {
  const src = `/images/screenshots/${lang}/${id}.png`;
  const chrome = url ? `app.pipelime.ai/${workspace}${url}` : 'app.pipelime.ai';
  return <figure className={`pl-shot pl-shot--${frame} not-prose`}>
      <div className="pl-shot__frame">
        {frame !== 'bare' && <div className="pl-shot__bar">
            <span className="pl-shot__dots">
              <span className="pl-shot__dot" />
              <span className="pl-shot__dot" />
              <span className="pl-shot__dot" />
            </span>
            <span className="pl-shot__url">{chrome}</span>
          </div>}
        <div className="pl-shot__media">
          <img src={src} alt={alt} loading="lazy" />
          {marks.map(mark => <span key={mark.n} className="pl-shot__mark" style={{
    left: `${mark.x}%`,
    top: `${mark.y}%`
  }} aria-hidden="true">
              {mark.n}
            </span>)}
        </div>
      </div>
      {caption && <figcaption className="pl-shot__caption">{caption}</figcaption>}
    </figure>;
};

Connect HubSpot with a Private App token so you can push leads there as contacts, with a note and their email history attached.

<div className="pl-availability">
  <div className="pl-availability__row">
    <div className="pl-availability__label">Where</div>
    <div className="pl-availability__value"><span className="pl-path">Integrations<span className="pl-path__sep">→</span>Integrations<span className="pl-path__sep">→</span>Apps & CRM</span></div>
  </div>

  <div className="pl-availability__row">
    <div className="pl-availability__label">Your role needs</div>
    <div className="pl-availability__value">Read access to Apps & CRM <code>read-integrations</code>. Admin, Member and Viewer have it by default.</div>
  </div>

  <div className="pl-availability__row">
    <div className="pl-availability__label">To create or change</div>
    <div className="pl-availability__value"><code>create-integrations</code> to add one, <code>update-integrations</code> to change one, on top of the permission above.</div>
  </div>

  <div className="pl-availability__note">If you cannot find this in your sidebar, your workspace may have a custom menu configuration. Contact support and we will check it for you.</div>
</div>

## Before you begin

* A HubSpot account where you can create a Private App and give it read and write access to CRM contacts and companies.
* Nothing has to be set up on our side. The token is your own credential, so this connects the same way on every workspace.

## Steps

<Steps>
  <Step title="Open the HubSpot connect dialog">
    Go to <UiPath>Integrations → Apps & CRM</UiPath>, choose **Add integration**, then choose **HubSpot** from the list. The dialog opens with a walkthrough for creating the token, and an empty field to paste it into underneath.

    <Screenshot id="integrations/connect-hubspot--token-step" frame="bare" alt="The Connect HubSpot dialog on its token step: an orange panel titled How to get your Private App Token with six numbered instructions, links to open HubSpot's Private Apps page and its documentation, and an empty Enter your HubSpot Private App Token field below" caption="Every string in this dialog except Cancel is English only. The instructions read the same whatever language you use the app in." />
  </Step>

  <Step title="Create a Private App token in HubSpot">
    The panel's six instructions walk you through HubSpot's own settings:

    1. Log in to your HubSpot account.
    2. Go to "Development → Legacy apps" in the left sidebar.
    3. Click "Create legacy app" and select "Private".
    4. Give it a name (the panel suggests "Email Integration") and, if you want, a description.
    5. Click the "Scopes" tab, then "Add new scope", and enable "CRM > Contacts (Read/Write)" and "CRM > Companies (Read/Write)".
    6. Click "Create app" and copy the access token it shows.

    The panel also links straight to HubSpot's Private Apps page and to its documentation.

    Only a token starting with `pat-` is accepted. The dialog checks that prefix itself and rejects anything else without sending it anywhere.
  </Step>

  <Step title="Paste the token and connect">
    Paste the token into the field and choose **Connect**. The token is used to read a contact from HubSpot, and if that works the dialog shows which HubSpot account it connected to.

    <Screenshot id="integrations/connect-hubspot--connected" frame="bare" alt="The dialog's success state: a green check circle, the heading HubSpot Connected!, a line reading Connected to: Northwind CRM, and a Done button" caption="Check the name before you close the dialog. It is the account the token belongs to, which matters if you have access to more than one." marks={[{ n: 1, x: 50, y: 62 }]} />

    The name next to "Connected to:" (1) is read from HubSpot's own account details: the account's company name, or its portal name. If HubSpot returns neither, the connection is named HubSpot Account.

    <Note>
      A workspace only ever holds one HubSpot connection. Connecting again with a different token replaces the existing one rather than adding a second.
    </Note>
  </Step>
</Steps>

## What happens next

<Check>
  The dialog shows **HubSpot Connected!** with the account name from the step above. Choose **Done**, and the HubSpot card on <UiPath>Integrations → Apps & CRM</UiPath> shows a **Connected** chip and that same name.
</Check>

Connecting HubSpot does not push any leads by itself. Nothing moves until you turn on **Auto-push analyzed leads** on the card, choose **Push to CRM** on a lead's own page, or add a Send to CRM step to a workflow. See [Auto-push analyzed leads and stage filters](/en/integrations/auto-push-and-stage-filters) and [Push a lead to your CRM manually](/en/integrations/push-to-crm-manually).

Only one CRM ever owns a lead. If Salesforce, Odoo, Kommo or HeyReach already created a record for it, the automatic push skips it without telling you, and a Send to CRM step reports it as sent while creating nothing. A manual push from the lead's page is the one route that still goes through.

<Screenshot id="integrations/connect-hubspot--card" url="/integrations" alt="The connected HubSpot card on the Apps & CRM grid, its Auto-push analyzed leads switch on and the stage-filter chips visible underneath, all unticked" caption="The card's title reads 'Hubspot', not 'HubSpot'. It is generated from the integration type, not the brand's own capitalization." />

Once a lead is pushed, it lands in HubSpot as a contact: its name split into first and last, its most recently added email and phone number, job title, LinkedIn URL, and its company's name, website and industry, leaving out whichever of those it does not have. A note is attached carrying the lead's LinkedIn URL, the lead's own description, the company's description and summary, and the company's saved links (again, whichever of those exist). One email engagement is created for each message in the lead's email thread, skipping only warm-up traffic. The note and the engagements are attached by separate calls once the contact exists: if either fails, the contact is still created and nothing in the app tells you. [Field mapping reference per CRM](/en/integrations/what-gets-pushed-per-crm) has the complete, field-by-field version.

## Troubleshooting

<AccordionGroup>
  <Accordion title="'Invalid API key format…'">
    The full message reads `Invalid API key format. HubSpot Private App tokens start with "pat-"`. The dialog checks the prefix itself, so nothing was sent to HubSpot. Copy the token straight from HubSpot's Private Apps page (the dialog links to it) rather than retyping it.
  </Accordion>

  <Accordion title="'Invalid HubSpot API key…'">
    The full message reads `Invalid HubSpot API key. Please ensure you have the correct Private App access token with CRM permissions.` The token was sent to HubSpot and the read it was checked with failed, so the connection was refused and nothing was saved. Open the private app in HubSpot, check it still carries CRM > Contacts and CRM > Companies with read and write, and paste a fresh token if it was regenerated.
  </Accordion>

  <Accordion title="Connected, but leads aren't showing up in HubSpot">
    Connecting only makes HubSpot available as a destination. It doesn't push anything on its own. Check whether **Auto-push analyzed leads** is on for this card, and see [Auto-push analyzed leads and stage filters](/en/integrations/auto-push-and-stage-filters) for every reason a push can be silently skipped. A contact with no note or no email history is a different, narrower case: those are attached separately from the contact itself, and a failure attaching either one is never shown in the app.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Auto-push analyzed leads and stage filters" icon="send" href="/en/integrations/auto-push-and-stage-filters">
    What triggers an automatic push, which stages it fires on, and every reason a lead is silently skipped.
  </Card>

  <Card title="Field mapping reference per CRM" icon="table" href="/en/integrations/what-gets-pushed-per-crm">
    What object each connector creates, which lead fields land where, and what happens to your email history.
  </Card>

  <Card title="Push a lead to your CRM manually" icon="plug" href="/en/integrations/push-to-crm-manually">
    Send one lead from its own page, and read the badge it leaves behind once it's synced.
  </Card>
</CardGroup>
