CRED × HubSpot — sync, enrichment, troubleshooting

Last updated: May 13, 2026

Quick answers

Question

Short answer

Section

How often does CRED sync with HubSpot?

Continuous incremental sync via the HubSpot Search API filtered by lastmodifieddate — new and modified records arrive in CRED within minutes; the full nightly safety pass picks up anything missed.

2

How do I trigger a manual sync (HS → CRED, CRED → HS)?

Per-record buttons in the CRED app, list-level bulk actions, or a full re-sync from Settings.

3

Why doesn't "Sync with HubSpot" enrich the company at the same time? Can it be forced?

Sync and enrichment are two separate actions. Sync moves data; enrichment uses credits to attach CRED graph data. To force them together, either enable auto-enrich on create, or build a workflow with Enrich → Sync to HubSpot.

4

Not all mapped fields are passed over — how do I troubleshoot?

Walk the seven-reason checklist (unmapped, write-back off, NULL_VALUE_ONLY, type mismatch, read-only in HS, missing OAuth scope, picklist mismatch).

5

Can I see action logs?

Yes — record Activity tab, Integration Sync Log, Workflow Run Log, Admin Audit Log. Every sync attempt records the HubSpot correlation ID for support.

6


1. What CRED syncs from HubSpot

CRED supports six HubSpot object types out of the box. Custom objects are supported via a separate setup.

HubSpot object

CRED entity

API used

Direction

users

RemoteUser

Settings Users API (/settings/v3/users)

Read-only

companies

Account

CRM Search API (/crm/v3/objects/search)

Two-way

contacts

Contact

CRM Search API

Two-way

pipelines

OpportunityPipeline

Pipelines API (/crm/v3/pipelines/deals)

Read-only

stages

OpportunityStage

Pipelines API

Read-only

deals

Opportunity

CRM Search API + Associations v4 API

Two-way

Custom properties: CRED auto-discovers every custom property on companies, contacts, and deals during the initial setup. They appear in the field-mapping UI; map the ones you want to sync.

What's not synced today: Notes, Tasks, Calls, Emails, Line Items, and HubSpot custom objects (as opposed to custom properties) are tracked in our internal roadmap (HubSpot expansion epic, COM-34471 to COM-34478) but not yet in the live integration. Workflows / Lists / Forms metadata is read for usage analytics but does not create CRED entities.


2. When and how often CRED syncs with HubSpot

Initial sync (when you first connect)

Triggered immediately after OAuth completes. CRED queues a SETUP_IMPORTS task, then a ENSURE_SYNC_SETTINGS task two minutes later, then a full DATA_SYNC_READ for each of the six entity types staggered every two minutes in dependency order:

  1. Users (referenced by companies, contacts, deals)

  2. Companies

  3. Contacts

  4. Pipelines

  5. Stages

  6. Deals (with company and contact associations fetched in batch)

Total time depends on portal size. Reference: a 50,000-company portal takes roughly 30–90 minutes; a 500,000-contact portal can take 4–8 hours. Progress is visible in Settings → Integrations → HubSpot → Sync log.

Ongoing sync after the initial import

Once the full read is done, CRED switches to continuous incremental sync:

  • The Search API is queried with a filter on hs_lastmodifieddate (companies, deals) or lastmodifieddate (contacts) >= the timestamp of the last successful read.

  • Only records that changed are returned, paginated 200 at a time.

  • A new incremental pass is queued shortly after the previous one finishes. Cadence under normal load is on the order of minutes per entity type, not hours — so a property edited in HubSpot is typically reflected in CRED within a few minutes, not "twice a day".

  • If a read task hangs for more than 15 minutes it is auto-restarted.

  • If a record fails Phase 2 processing, it is retried after 4 hours by the stale-recovery job.

  • Rate limit: CRED self-throttles to a conservative 140 requests per 10 seconds via the Bottleneck rate limiter (HubSpot's Professional tier ceiling is 150). Customers on Free / Starter (100 / 10 s) get the same conservative throttle but proportionally fewer requests per period; large portals on those tiers will sync more slowly.

Write sync (CRED → HubSpot)

Every record you create or update in CRED schedules a DATA_SYNC_CREATE or DATA_SYNC_UPDATE task. Under normal load this runs within seconds — the record appears in HubSpot in near-real-time. Bulk writes are queued behind the rate limiter.

"Twice a day" / "scheduled at X o'clock" expectations

This is a frequent ask. CRED does not have a fixed "sync at 2am and 2pm" schedule. The integration is event-driven and continuous. If you want a deterministic time-based sync (for compliance reporting, etc.), build a CRED workflow with a scheduled trigger and a Sync to HubSpot step.


3. How to trigger a manual sync

HubSpot → CRED (pull)

Scope

How

What happens

One record

Open the record in CRED → record header 3-dot menu → Refresh from HubSpot

Single-record batch read on the HubSpot ID; updates the CRED record within seconds

One list / collection

Open the list → Sync → Pull from HubSpot

Targeted batch reads of every record's HubSpot ID

Whole portal

Settings → Integrations → HubSpot → Run full sync

Re-runs the full read for every entity type. Heavy — only use to recover from a known drift

CRED → HubSpot (push)

Scope

How

What happens

One record

Record header → Sync with HubSpot

Creates the company / contact / deal in HubSpot if it doesn't exist; otherwise updates it. Returns the HubSpot URL on success

Bulk

List → select rows → Bulk actions → Sync to HubSpot

Schedules a write per record, throttled to the rate limiter

Workflow

Add a Sync to CRM step to any workflow

Every record entering the step is written to HubSpot in real time

API

GraphQL syncToCRM mutation

For programmatic / scripted use

Manual sync respects your update mode. If Account.write is set to OFF, the button is disabled with an explanatory tooltip. If a custom field is NULL_VALUE_ONLY and HubSpot already has a value, that field is skipped during the manual push (intentional — flip the field to OVERWRITE if you want to replace).


4. Why "Sync with HubSpot" doesn't enrich at the same time

This is the single most common HubSpot question we get. Let's untangle it.

What the "Sync with HubSpot" button does

  • Takes the record as it currently is in CRED

  • Writes the mapped field values to HubSpot's API

  • Returns the HubSpot record URL

That's it. It does not call the CRED enrichment waterfall. It does not consume credits. If the CRED record has empty fields, those empty fields are pushed to HubSpot empty.

Why it's separated from enrichment

  1. Cost — enrichment uses credits. Sync is free with your CRED plan; enrichment isn't. Bundling them would mean every sync click silently consumed credits, which is the opposite of what most customers want.

  2. Predictability. "I clicked Sync" should always mean "the record I see is the record HubSpot gets". Adding a hidden enrichment step would make the result depend on which fields already had values.

  3. Asynchronicity. Enrichment can take seconds (waterfall hits) to minutes (DS scoring). Sync is sub-second. Bundling them would make the sync button feel slow or fail intermittently.

The three ways to get an enriched record into HubSpot

Option 1 — Manual two-step (best for one-offs)

  1. Open the record in CRED → click Enrich. Wait until the enriched fields populate (visible on the record card).

  2. Click Sync with HubSpot. The enriched values are pushed via the mapped CRED-custom fields.

Option 2 — Workflow (best for ongoing flows)

Workflows → New workflow → Trigger: "Company added to list X" → Steps: Enrich companySync to CRM (HubSpot). Every company entering the list is enriched first, then synced. This is the recommended pattern for sales motions where every prospect needs full data in HubSpot.

Option 3 — Auto-enrich on create (set and forget)

Settings → Integrations → HubSpot → Enrichment → toggle Auto-enrich on create. Any new company / contact arriving in CRED (via HubSpot sync, the "Add to CRED" button, or a workflow) is enriched immediately. Combined with a write-back rule, the enriched data flows to HubSpot without anyone clicking anything. Note: this consumes credits per record — if your portal has 100k+ companies, run a credit-budget calculation first.

"I already paid the credits — why didn't the sync use them?"

Credits are debited at the moment of enrichment, not at the moment of sync. If you paid for credits but never clicked Enrich on the record (or it never went through an enriching workflow), the record's CRED-custom enrichment fields are empty — and that's what was pushed to HubSpot.

To fix retroactively for an existing list:

  1. Build a list of the affected companies in CRED

  2. List actions → Bulk enrich. This consumes credits.

  3. Once enrichment finishes, list actions → Bulk sync to HubSpot.


5. Mapped fields not passing over — troubleshooting

HubSpot is the strictest of the three CRMs about validation. The seven-reason checklist from the cross-CRM article applies; here are the HubSpot-specific gotchas.

HubSpot-specific reasons fields fail to write

HubSpot error code

Meaning

Fix

PROPERTY_DOESNT_EXIST (400)

The HubSpot property in your mapping was deleted or renamed in HubSpot.

Re-fetch the schema (Settings → Integrations → HubSpot → Refresh fields) then re-map.

PROPERTY_VALUE_NOT_IN_OPTIONS (400)

You're writing a value to a HubSpot dropdown / radio that isn't in its allowed options.

Add the value to the HubSpot property's options, or map to a value that already exists.

READ_ONLY_PROPERTY (400)

The HubSpot property is computed or system-managed (e.g. hs_object_id, createdate, lifecyclestage on Free tier).

You cannot write to it; remove from the mapping.

VALIDATION_ERROR (400)

Generic. Usually a type mismatch (writing text to a number, malformed date, value too long).

Open the action log entry; the message usually says exactly which field and which value.

INVALID_AUTHENTICATION (401)

OAuth token expired or revoked. Auto-refresh failed.

Reconnect the integration: Settings → Integrations → HubSpot → Reconnect.

RATE_LIMIT (429)

You hit HubSpot's per-portal rate ceiling. Bottleneck handles this automatically; if it persists, your portal is on Free / Starter (lower ceiling) or a HubSpot app outside CRED is also hitting the limit.

Reduce parallel app load or upgrade HubSpot tier. Most customers never see this.

OBJECT_NOT_FOUND (404)

The HubSpot record was deleted but CRED still has the ID.

The record will be marked as deleted on the next sync. To clean up immediately, refresh the CRED record from HubSpot.

HubSpot OAuth scopes CRED requests

If you've changed your HubSpot app permissions, reconnect the integration. CRED requests:

  • oauth

  • crm.objects.companies.read / .write

  • crm.objects.contacts.read / .write

  • crm.objects.deals.read / .write

  • crm.objects.users.read

  • crm.objects.custom.read / .write

  • crm.schemas.companies.read / .contacts.read / .deals.read

If a write fails with INSUFFICIENT_PERMISSIONS, it is almost always one of these scopes missing — reconnecting will re-prompt you to grant them.

Things that look like a sync bug but aren't

  • Owner field is blank in HubSpot. If the CRED record's owner doesn't have a matching HubSpot user (matched by email), the owner field is left blank. Invite the user in HubSpot first.

  • Deal associations only show one company / contact. CRED currently syncs the first associated company and the first associated contact per deal via the Associations v4 API. Multi-association is on the roadmap (COM-34478).

  • Currency on a deal looks wrong. CRED uses HubSpot's deal_currency_code property; if it's blank on the HubSpot deal, CRED falls back to the connection's default currency. Set the deal-level currency in HubSpot if you need precision.

  • A picklist value vanishes after sync. Almost always a case-sensitivity issue. "Closed Won""closed-won".


6. Action logs — where to find them

Four places, in order of usefulness for HubSpot questions.

1. Record Activity tab (per-record sync history)

Open any company / contact / deal in CRED → Activity tab. Every sync attempt for that record shows:

  • Timestamp and direction (HS → CRED or CRED → HS)

  • Trigger (auto, manual button, workflow run, API call)

  • Field-level diff — which fields changed and from what to what

  • Success / error status with the HubSpot error code and message

  • The HubSpot correlation ID (every HubSpot API response includes one). Quote this when raising a HubSpot support ticket — HubSpot can trace any failure by correlation ID.

This is the right starting point for "field X didn't sync" questions.

2. Integration Sync Log (portal-wide feed)

Settings → Integrations → HubSpot → Sync log. Reverse-chronological feed of every sync task — entity type, direction, records read, records written, errors. Filter by:

  • Direction (HS → CRED, CRED → HS)

  • Entity (Company, Contact, Deal, User, Pipeline, Stage)

  • Status (Success, Partial, Error)

  • Time range

Each row drills into a per-record breakdown. Use this for "did anything sync today?" or "how many companies updated since 9am?" questions.

3. Workflow Run Log (per-workflow)

For records moved by a workflow (Enrich → Sync to HubSpot is the common one), Workflows → [workflow name] → Runs. Per run you see every step's input, output, and error. Useful when you can't tell whether the failure was in the enrichment step or the sync step.

4. Admin Audit Log

Settings → Audit log. Captures admin actions: reconnecting HubSpot, changing field mappings, switching update modes, running a full re-sync, granting / revoking integration access.

What to send if you raise a CRED support ticket

  • The CRED record ID and the HubSpot record ID (hs_object_id)

  • The action-log entry with the HubSpot correlation ID

  • The field name(s) you expected to sync and the values you expected

  • The current update mode for that entity (Settings → Integrations → HubSpot → Sync settings)

  • Approx timestamp of when you triggered the sync (UTC if possible)


7. HubSpot integration limits and known constraints

Limit

Value

Why it exists

API calls / 10 seconds (CRED self-throttle)

140

Conservative ceiling under HubSpot Professional's 150; prevents 429s

Min time between API calls

75ms

Smooths bursts

Max concurrent API calls

10

Bottleneck concurrency cap

Auto-retries on transient failures

3

Handles 429, transient 500s, network blips

Page size for reads

200

HubSpot Search API max

Token refresh skew

2 minutes before expiry

Prevents using a token that expires mid-call

Stale read auto-restart

15 minutes

Recovers from worker crashes

Stale Phase-2 retry

4 hours

Avoids fighting active processing

Known limitations (as of 2026-04-27)

  • No deleted-record detection. HubSpot has no batch deleted-records endpoint. If a record is deleted in HubSpot, CRED notices on the next per-record refresh or on a full re-sync, not in real time.

  • First association only on deals. Deals with multiple associated companies / contacts only sync the first via the Associations v4 API. Multi-association tracked in COM-34478.

  • Notes / Tasks / Calls / Emails / Line Items not synced. Schemas and OAuth scopes are in place; entity routing is on the roadmap (COM-34461, COM-34462).

  • Custom objects not yet active. Custom properties on standard objects are fully supported. Custom objects (e.g. a HubSpot custom object called "Sponsorship") need a manual setup — talk to your account manager.

  • Workflow / Lists / Forms metadata is read-only. CRED reads HubSpot Workflows / Lists / Forms for usage analytics and can clone HubSpot workflows into disabled CRED workflows for inspection. It does not push CRED workflows into HubSpot.


8. Reference — CRED-side technical detail

For curious admins. Most users do not need to read this section.

Pipeline architecture

CRED uses a two-phase pipeline shared across every CRM:

  1. Phase 1 — DATA_SYNC_READ: queries HubSpot Search API, paginates 200 records at a time, stores the raw payload as ImportRecord rows. Tracks progress in Import.readRowsCount; sets Import.readCompletedAt when finished.

  2. Phase 2 — IRP_PROCESS_IMPORT_RECORDS: converts each ImportRecord into a CRED entity (Account / Contact / Opportunity / …), resolving relationships (a Contact's company is matched to an existing Account by HubSpot ID).

Write-back tasks (DATA_SYNC_CREATE, DATA_SYNC_UPDATE) are pushed to a separate queue and obey the same rate limiter.

Key files (for support / engineering)

  • src/services/hubspot/hubspot-oauth-service.ts — OAuth + token refresh

  • src/services/hubspot/hubspot-rate-limit-config.ts — Bottleneck throttle

  • src/services/data-sync/hs/hs-data-sync-service.ts — main sync service

  • src/services/data-sync/hs/hs-api.ts — Search / Pipelines / Associations API client

  • src/services/data-sync/hs/fields.ts — field-mapping configurations

  • src/domain/integration/usecase/hubspot/authorize-hubspot-account.ts — OAuth callback handler

Useful HubSpot links