# Sync new Adobe Commerce shoppers to HubSpot contacts

> Every hour, pull newly registered Adobe Commerce shoppers into HubSpot so your CRM always mirrors your storefront, without duplicates.

- Workflow type: code
- Services: Adobe Commerce (Magento), HubSpot
- Categories: Operations, Sales
- Published: 2026-07-17

## What it does

- Checks Adobe Commerce every hour for shoppers who registered since the last run
- Copies each new shopper into HubSpot with their name, email, phone, and billing address
- Matches on email so existing HubSpot contacts get updated in place instead of duplicated
- Tags each contact with the Adobe Commerce customer ID and store view so you can cross-reference orders back to the CRM

## What you'll need

- An Adobe Commerce (Magento) store with admin access to create an integration
- A HubSpot account with permission to create and update contacts
- Two custom HubSpot contact properties for the Adobe Commerce customer ID and store view code (one-time setup in HubSpot settings)

## Prompt

Every hour, sync newly registered Adobe Commerce shoppers into HubSpot as contacts. This is a deterministic one-way sync with no reasoning required, so build it as a code workflow.

Trigger: cron every hour. Keep a persisted watermark for the last successful run timestamp. On the first run, seed the watermark with the workflow start time so we do not backfill the entire customer base.

Step 1: Call Adobe Commerce Search Customers with searchCriteria filtering created_at greater-than-or-equal to the last-run watermark (condition_type=gteq), sort by created_at ascending, pageSize 100, and page through by incrementing currentPage until the accumulated items reach total_count.

Step 2: For each Adobe Commerce customer, build a HubSpot contact properties payload: email from email, firstname from firstname, lastname from lastname, phone from the default billing address telephone (look up the address in the customer.addresses array whose id equals customer.default_billing), city from that address city, state from that address region.region, country from that address country_id. Also set two custom properties: adobe_commerce_customer_id (from customer.id) and store_view_code (from customer.store_id, resolved to the store view code via GET /store/storeViews if the property expects the code rather than the numeric id). Skip any customer without an email.

Step 3: Chunk the payloads into batches of 100 and call HubSpot Batch Upsert Contacts with idProperty set to "email" so existing HubSpot contacts are updated in place instead of duplicated. Handle 429 responses by respecting the Retry-After header.

Step 4: After the run completes, persist the highest created_at from the successfully upserted batch as the new watermark. If a batch fails, only advance the watermark past the last successfully processed customer so a partial failure does not skip records on the next run.

## How to customize

- Change how often the sync runs (default hourly, works just as well every 15 minutes or once a day)
- Add or remove which shopper fields get copied across (for example include newsletter opt-in or gender)
- Restrict the sync to specific store views if you run multiple storefronts on one Magento install

## FAQ

### Will this create duplicate HubSpot contacts if the shopper already exists?

No. Each contact is matched on email, so an existing HubSpot record is updated in place instead of a new one being created.

### Does it work on HubSpot Free?

Yes. Creating and updating contacts is available on every HubSpot plan, including Free.

### What if the same customer registers on two different store views?

HubSpot still matches on email, so both registrations land on one contact. The store view code field records the most recent store the shopper registered on.

### Can I backfill my existing Adobe Commerce customer base?

Yes. The first run can be pointed at any start date so you can pull historical shoppers into HubSpot; after that it only picks up new registrations.

### What happens if HubSpot is unreachable during a run?

The next hourly run picks up from the same start timestamp, so nothing is lost.

Use this prompt in General Input: https://www.generalinput.com/prompts/sync-new-adobe-commerce-shoppers-to-hubspot-contacts