# Sync Audiences to HubSpot Audience


<blockquote class="announcement">
  <div class="tip-quote">
    
    <div class="tip-text"><p>The <strong>HubSpot Audience</strong> destination is in <strong>Private Beta</strong>.</p>
<p>Reach out to <a href="mailto:support@rudderstack.com" >Customer Success</a> to enable it for your workspace.</p>
</div>
  </div>
</blockquote>

<p>This guide lists the steps to configure HubSpot Audience as a destination in RudderStack and sync the created audiences to it.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p><strong>HubSpot Audience</strong> is separate from the Event Stream <a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/hubspot/" >HubSpot</a> destination.</p>
<ul>
<li>Use <strong>HubSpot</strong> to create and update contacts and send Event Stream traffic.</li>
<li>Use <strong>HubSpot Audience</strong> only to change list membership. This sync does not create or update contacts.</li>
</ul></div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="prerequisites">Prerequisites</h2><ul>
<li>Authenticate with a HubSpot <a href="https://developers.hubspot.com/docs/apps/developer-platform/build-apps/authentication/account-service-keys" >Service Key</a> that has <code>crm.lists.read</code>, <code>crm.lists.write</code>, <code>crm.objects.contacts.read</code>, and <code>crm.objects.contacts.write</code>.</li>
<li>Use a dedicated Service Key limited to those scopes. Contact write only updates list membership; this sync does not create or update contacts.</li>
</ul>
<p>See <a href="https://www.rudderstack.com/docs/destinations/reverse-etl-destinations/hubspot-audience/#prerequisites" >Prerequisites</a> for details.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="setup">Setup</h2><ol>
<li>Set up an audience in RudderStack using the <a href="https://www.rudderstack.com/docs/audiences/audience-builder/create-audience/" >Audience Builder</a>.</li>
<li>Go to the <strong>Syncs</strong> tab of the audience page and click <strong>Add sync</strong>. Then, select <strong>HubSpot Audience</strong>.</li>
<li>Click <strong>New destination</strong> — you can also select an already-configured destination here.</li>
<li>Specify a unique name to identify this destination in RudderStack.</li>
<li>In the <strong>HubSpot account</strong> section, select an existing account or add a new one with an account name and Service Key:</li>
</ol>
<table>
  <thead>
      <tr>
          <th>Setting</th>
          <th><div>Description</div></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Account name</td>
          <td>Enter an account name.</td>
      </tr>
      <tr>
          <td>Service Key</td>
          <td>Enter a HubSpot Service Key with the scopes in <a href="#prerequisites" >Prerequisites</a>.</td>
      </tr>
  </tbody>
</table>
<ol start="6">
<li>Proceed to configure the sync.</li>
</ol>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="configure-sync">Configure sync</h2><p>This section lists the settings to correctly configure your audience syncs to the HubSpot Audience destination.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="choose-a-list">Choose a list</h3><p>Choose how the connection targets a HubSpot static contact list. <strong>Use existing list</strong> is the default.</p>
<ul>
<li><strong>Use existing list</strong>: Select a static contact list. Active lists do not appear in the picker.</li>
<li><strong>Create new list</strong>: Enter a list name. RudderStack creates an empty HubSpot static contact list when you finish setup, then saves the generated list ID on the connection.</li>
</ul>
<p>HubSpot requires a unique list name in the portal. If HubSpot rejects the name (for example, because it is already in use) or the Service Key lacks <code>crm.lists.write</code>, fix the name or permissions and try again. RudderStack does not rename HubSpot lists after the sync is created, and renaming the audience does not rename the HubSpot list.</p>

<!DOCTYPE html>
<html lang="en">
<blockquote class="tip">
  <div class="tip-quote">
    
    <div class="tip-text"><p>If setup creates the HubSpot list but saving the RudderStack connection fails, select that list with <strong>Use existing list</strong> and continue. Do not create another list for the same connection.</p>
<p>If RudderStack cannot confirm whether HubSpot created the list, check HubSpot for an empty list with that name before creating again. Recovery prompts in the UI do not survive a page reload.</p>
</div>
  </div>
</blockquote>
</html>
<p>The connection stays locked to the selected list. Editing a connection keeps that list fixed. To sync a different list, create a new connection. The previous list and its memberships stay unchanged. Lists created during setup are not deleted automatically when you disconnect.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="sync-mode">Sync mode</h3><p>RudderStack supports only <a href="https://www.rudderstack.com/docs/data-pipelines/reverse-etl/developer-guides/sync-modes/#mirror-mode" >Mirror mode</a> for this integration.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="map-identifiers">Map identifiers</h3><p>Map audience columns to HubSpot contact identifiers. At least one complete identifier mapping is required.</p>
<table>
  <thead>
      <tr>
          <th>Identifier</th>
          <th><div>Behavior</div></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>HubSpot Record ID (used first)</td>
          <td>Used first when the mapped value is present.</td>
      </tr>
      <tr>
          <td>Email (used when Record ID is empty)</td>
          <td>Used only when the Record ID is empty.</td>
      </tr>
  </tbody>
</table>
<p>A bad Record ID does not fall back to email.</p>
<p>Note that:</p>
<ul>
<li>Deduplicate the audience first. Within a sync, each resolved HubSpot contact must correspond to one audience member. If two members resolve to the same contact and only one leaves, that delete can remove the contact while the other member does not re-add it.</li>
<li>Preview shows audience members only. It does not confirm which HubSpot contacts will match.</li>
<li>Mirror mode only removes contacts represented by this source. Other existing list members stay unchanged.</li>
</ul>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="sync-settings">Sync settings</h2>

<p>Two options are available to schedule your audience syncs:</p>
<ul>
<li><strong>Run syncs automatically</strong> based on a specified frequency (every 5 minutes, 10 minutes, 15 minutes, 30 minutes, 1 hour, 3 hours, 6 hours, 12 hours, or 24 hours) and a specific time (in UTC).</li>
<li><strong>Run syncs manually</strong> — trigger a sync from the sync details page. You will need to run the sync each time.</li>
</ul>

<figure class="image--main ">
<a href="/docs/images/audiences/destinations/fb-custom-audience/run-sync.webp">
<img src="/docs/images/audiences/destinations/fb-custom-audience/run-sync.webp" decoding="async" loading="lazy" class="img-shortcode"/>
</a>
</figure>

<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="sync-observability-settings">Sync observability settings</h4>

<table>
  <thead>
      <tr>
          <th>Setting</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Retain sync logs</td>
          <td>This setting is toggled on by default and instructs RudderStack to store the sync logs in your warehouse. You can also configure the below settings: <br /><br /><table><tr><th width="20%">Setting</th><th width="80%">Description</th></tr><tr><td>Sync log retention</td><td>Specify the retention period of the <a href="https://www.rudderstack.com/docs/data-pipelines/reverse-etl/developer-guides/sync-observability/#sync-logs" >sync logs</a> in your warehouse. <br /><br />If you set it to 1, then RudderStack deletes any sync log older than a day (in UTC time). </td></tr><tr><td>Snapshot table retention</td><td>Specify the number of <a href="https://www.rudderstack.com/docs/data-pipelines/reverse-etl/developer-guides/sync-observability/#snapshot-table-schema" >snapshot tables</a> to retain. </td></tr></table></td>
      </tr>
      <tr>
          <td>Retry failed records</td>
          <td>This setting is toggled on by default and causes RudderStack to continually <a href="https://www.rudderstack.com/docs/data-pipelines/reverse-etl/developer-guides/sync-observability/#retry-failed-records" >retry sending the failed records</a>.</td>
      </tr>
      <tr>
          <td>Retain and show failures</td>
          <td>This setting is toggled off by default. Turn it on to have RudderStack write the error recorded for every failed record to a <a href="https://www.rudderstack.com/docs/data-pipelines/reverse-etl/developer-guides/rudderstack-schema/#failed-records-table" >failed records table</a> in your warehouse and show it in the sync&rsquo;s <a href="https://www.rudderstack.com/docs/data-pipelines/reverse-etl/developer-guides/sync-observability/#failed-records" >failed records view</a>. It applies from the next sync and can take up to a minute to reach your data plane. <br /><br /><table><tr><th width="20%">Setting</th><th width="80%">Description</th></tr><tr><td>Failure retention</td><td>Number of days RudderStack keeps each sync&rsquo;s failed records in your warehouse. The default is 30 and the minimum is 7.</td></tr></table></td>
      </tr>
  </tbody>
</table>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">Storing sync logs, snapshot tables, and failed records may incur additional warehouse costs.</div>
  </div>
</blockquote>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="enable-sync">Enable sync</h2>

<p>Once the setup is complete, enable the sync.</p>

<figure class="image--main ">
<a href="/docs/images/audiences/destinations/tiktok/enable-sync.webp">
<img src="/docs/images/audiences/destinations/tiktok/enable-sync.webp" decoding="async" loading="lazy" class="img-shortcode"/>
</a>
</figure>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="how-membership-is-written-to-hubspot">How membership is written to HubSpot</h2><ul>
<li>Insert or update adds the resolved contact to the list. Delete removes the contact from the list.</li>
<li>A full sync adds current members but removes none.</li>
</ul>
<p>See <a href="https://www.rudderstack.com/docs/destinations/reverse-etl-destinations/hubspot-audience/#how-membership-is-written-to-hubspot" >How membership is written to HubSpot</a> for when a full sync runs, row outcomes, and batch sizes.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="if-a-sync-fails">If a sync fails</h2><p>Membership updates fail if the key lacks required write scopes, HubSpot rejects the key, or the selected list has been deleted.</p>
<p>See <a href="https://www.rudderstack.com/docs/destinations/reverse-etl-destinations/hubspot-audience/#if-a-sync-fails" >If a sync fails</a> for how to fix each case.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="stop-a-sync">Stop a sync</h2><p>Disabling or deleting the sync does not call HubSpot. The list and its members stay as they are, including lists created during setup. Remove members or delete the list in HubSpot if you no longer want them.</p>
<br />

