Hubspot – Shopify

Integration Specification — Technical Reference
HubSpot CRM Shopify
OAuth 2.0 + Private App Tokens Event-Driven Bi-Directional Sync
78 / 100
VIABLE
Health Score
Integration Viability Score — Proprietary Assessment
HubSpot CRM Shopify
Auth Robustness20/25
Webhook / Event Support22/25
Rate Limit Generosity18/25
Documentation Quality18/25
VERDICTA mature, well-documented integration pairing OAuth 2.0 on both sides with rich webhook support, enabling real-time commerce-to-CRM data synchronization at enterprise scale.

Executive Summary

The HubSpot CRM ↔ Shopify integration bridges B2C commerce and B2B revenue operations by synchronizing customers, orders, products, and lifecycle events across both platforms in real time. HubSpot exposes a RESTful API suite secured via OAuth 2.0 and Private App tokens, covering CRM objects (Contacts, Companies, Deals), Commerce objects (Orders, Products), and a full Webhooks API for outbound event streams. Shopify provides a GraphQL Admin API (with a legacy REST Admin API) secured via OAuth 2.0, complemented by a robust Webhooks system covering order, customer, product, and inventory lifecycle events. Together they form a bidirectional event-driven pipeline: Shopify order and customer events flow into HubSpot to update contact records, deals, and lifecycle stages, while HubSpot CRM changes (deal stage updates, contact property modifications) can trigger Shopify customer tag updates or order notes. This integration is particularly valuable for DTC brands scaling into B2B, enabling RevOps teams to unify commerce revenue data with CRM pipeline intelligence.

⚡ Accelerate your integration roadmap

Stop wrestling with API rate limits, undocumented endpoints, and unreliable webhooks. Our engineering team designs and deploys resilient, enterprise-grade integration architectures in days. Prefer to build it in-house? Leverage our recommended middleware platform.

Logical Architecture & Data Flow

Architecture Component Breakdown

HubSpot CRM API
RESTful API providing CRUD operations on CRM Objects (Contacts, Companies, Deals, Tickets), Commerce Objects (Orders, Products, Carts), and Associations. Secured via OAuth 2.0 or Private App tokens. Base URL: https://api.hubapi.com.
Shopify GraphQL Admin API
Primary Shopify API surface for admin operations — customers, orders, products, inventory, fulfillment. Versioned (e.g. 2025-01). Endpoint: https://{shop}.myshopify.com/admin/api/{version}/graphql.json. OAuth 2.0 or Admin API access tokens.
HubSpot Webhooks API
Outbound webhook subscriptions on CRM object property changes and contact lifecycle stage transitions. Configured per app via the Developer portal. Delivers signed JSON payloads to a registered endpoint. Supports contact.creation, deal.propertyChange, and more.
Shopify Webhooks API
Native webhook system supporting topics such as orders/create, orders/paid, customers/create, products/update, and fulfillments/create. Configurable via GraphQL Admin API (webhookSubscriptionCreate) or REST. HMAC-SHA256 signature verification required.
Integration Middleware
Orchestration layer (e.g. custom Node.js service, AWS Lambda, or iPaaS like Make/Zapier/n8n) responsible for webhook ingestion, payload transformation, field mapping, deduplication logic, idempotency keying, error handling, and retry queuing between both platforms.
OAuth 2.0 Token Store
Secure credential store managing access tokens and refresh tokens for both HubSpot (OAuth 2.0 via https://api.hubapi.com/oauth/v1/token) and Shopify (OAuth 2.0 install flow). Handles token refresh, rotation, and encrypted persistence per connected shop and HubSpot portal.
Dead Letter Queue & Retry
Durable message queue (e.g. SQS, Redis Streams) capturing failed webhook deliveries and API write failures for exponential backoff retry. Prevents data loss during transient outages on either platform and surfaces alerting for persistent failures.
HubSpot Commerce API
Dedicated CRM Commerce layer covering /crm/v3/objects/orders, /crm/v3/objects/line_items, /crm/v3/objects/products, and /crm/v3/objects/carts. Enables mirroring of Shopify order data as structured HubSpot Commerce objects associated to Contact records.

Authentication Architecture

Both platforms support OAuth 2.0 Authorization Code flows, making this a well-matched authentication pairing. HubSpot authenticates via OAuth 2.0 using the authorization URL https://app.hubspot.com/oauth/authorize and token exchange at https://api.hubapi.com/oauth/v1/token. Access tokens expire every 30 minutes and must be refreshed using a stored refresh token. For server-to-server integrations without a user install flow, HubSpot Private App tokens (Bearer tokens) are recommended — these do not expire but are scoped at creation time. Shopify authenticates via OAuth 2.0 with the per-shop authorization URL https://{shop}.myshopify.com/admin/oauth/authorize and token exchange at https://{shop}.myshopify.com/admin/oauth/access_token. Shopify access tokens do not expire (offline access mode) but are shop-specific and must be stored per installed merchant. Both platforms require HTTPS for all API calls. Webhook payloads from Shopify must be verified using HMAC-SHA256 against the X-Shopify-Hmac-SHA256 header; HubSpot webhook signatures use the app client secret for verification against the X-HubSpot-Signature-v3 header.

Data Flow Diagram

orders/create POST /crm/v3/objects deal.propertyChange customerUpdate auth on fail Shopify GraphQL Admin API Middleware Transform & Route HubSpot CRM REST API OAuth Token Store / Refresh Dead Letter Queue & Retry Shopify Customer Update Middleware CRM → Commerce HubSpot Webhook Outbound SHOPIFY → HUBSPOT FLOW HUBSPOT → SHOPIFY FLOW

Enterprise Use Cases

Use Case 1: Order-to-Deal Pipeline Automation

USE CASE 4.1
TRIGGER: orders/paid (Shopify Webhook)
→ HubSpot Deal + Line Items Created
Shopify Paid Orders → HubSpot Deals with Line Items
When a Shopify orders/paid webhook fires, the middleware extracts the order payload and performs a contact lookup or creation via POST /crm/v3/objects/contacts using the customer email. A Deal is then created via POST /crm/v3/objects/deals with dealname set to the Shopify order name, amount mapped from total_price, and the pipeline stage set to “Closed Won.” Line items are created via POST /crm/v3/objects/line_items for each Shopify order line, associated to the deal using POST /crm/v4/associations/{fromObjectType}/{fromObjectId}/batch/create. This gives RevOps teams full order-level revenue visibility inside HubSpot without manual data entry.

Use Case 2: Customer Lifecycle Stage Synchronization

USE CASE 4.2
TRIGGER: customers/create (Shopify Webhook)
→ HubSpot Contact Created / Updated
New Shopify Customer → HubSpot Contact with Lifecycle Stage
A Shopify customers/create or customers/update webhook triggers an upsert to HubSpot contacts via POST /crm/v3/objects/contacts/batch/upsert using email as the deduplication key. The HubSpot contact’s lifecyclestage property is set to customer and custom properties like shopify_customer_id and total_spent are populated from the Shopify customer object. Subsequent repeat purchases trigger a PATCH /crm/v3/objects/contacts/{contactId} to update num_associated_deals and custom revenue properties, enabling segmentation and automated marketing enrollment in HubSpot Workflows.

Use Case 3: Abandoned Cart Recovery via HubSpot Sequences

USE CASE 4.3
TRIGGER: checkouts/create (Shopify Webhook)
→ HubSpot Workflow Enrollment
Shopify Abandoned Checkout → HubSpot Cart Recovery Workflow
When Shopify fires a checkouts/create webhook for a checkout that includes an email, the middleware creates or updates a HubSpot Cart object via POST /crm/v3/objects/carts with properties including hs_cart_abandon_url mapped from Shopify’s abandoned_checkout_url. A custom HubSpot contact property shopify_cart_status is set to abandoned via PATCH /crm/v3/objects/contacts/{contactId}. HubSpot Workflows trigger on this property change to enroll the contact in a timed sequence sending recovery emails. When Shopify fires checkouts/delete (checkout completed), the middleware updates the HubSpot cart object status and unenrolls the contact from the recovery sequence.

Use Case 4: Bi-Directional Product Catalog Sync

USE CASE 4.4
TRIGGER: products/update (Shopify Webhook)
→ HubSpot Product Library Updated
Shopify Product Updates → HubSpot Product Library Sync
Shopify products/create and products/update webhooks trigger creation or patching of HubSpot Product objects via POST /crm/v3/objects/products or PATCH /crm/v3/objects/products/{productId}. The canonical SKU (variant.sku) is stored as a custom HubSpot property to serve as the idempotency key. Price (variant.price), name (title), and description (body_html, stripped of HTML) are mapped to HubSpot’s price, name, and description fields. This ensures that HubSpot quotes and deals always reference current pricing from Shopify without manual product library maintenance.

Use Case 5: Fulfillment Event → HubSpot Deal Stage Progression

USE CASE 4.5
TRIGGER: fulfillments/create (Shopify Webhook)
→ HubSpot Deal Note + Stage Update
Order Fulfillment → HubSpot Post-Sale Deal Tracking
When Shopify fires fulfillments/create, the middleware locates the associated HubSpot Deal (matched via the stored shopify_order_id property) and creates a HubSpot Engagement Note via POST /crm/v3/objects/notes containing the tracking number and carrier, then patches the deal property hs_deal_stage_probability and moves it to a post-sale pipeline stage via PATCH /crm/v3/objects/deals/{dealId}. This enables customer success teams to track fulfillment status without leaving HubSpot and triggers post-purchase NPS or upsell workflows.

Standard API Field Mapping

Note: Field names reflect canonical API schema identifiers. All endpoints verified against official documentation at developers.hubspot.com and shopify.dev.

Entity HubSpot Field Method Shopify Field Method Type
Contact / Customer email POST customer.email WEBHOOK String (dedup key)
Contact / Customer firstname POST customer.first_name WEBHOOK String
Contact / Customer lastname POST customer.last_name WEBHOOK String
Contact / Customer phone PATCH customer.phone WEBHOOK String
Deal / Order dealname POST order.name WEBHOOK String
Deal / Order amount POST order.total_price WEBHOOK Decimal (String)
Deal / Order closedate POST order.processed_at WEBHOOK ISO 8601 → Unix ms
Line Item / Order Line name POST line_item.title WEBHOOK String
Line Item / Order Line price POST line_item.price WEBHOOK Decimal (String)
Line Item / Order Line quantity POST line_item.quantity WEBHOOK Integer
Product / Product name POST product.title WEBHOOK String
Product / Product price PATCH variant.price WEBHOOK Decimal (String)
Contact / Customer lifecyclestage PATCH customer.orders_count GET Enum ← Derived Logic

Limitations & Rate Limits

Risk Advisory: Validate all rate limits with vendor TAMs before production go-live.

HubSpot CRM Rate Limits

Constraint Limit Detail Mitigation
API Calls (Free/Starter) 110 req/10 sec Applies per private app / OAuth token across all CRM endpoints Implement token bucket with 100 req/10s ceiling; use batch endpoints
API Calls (Professional/Enterprise) 150 req/10 sec Higher burst allowance for paid tiers; daily limit also applies Monitor X-HubSpot-RateLimit-Remaining response header and back off on 429
Daily Request Limit 500,000 req/day Cumulative across all apps in a portal for Professional/Enterprise Use batch APIs (/batch/create, /batch/update) to minimize call count
Batch Write Operations 100 records/batch Maximum records per single batch create/update/upsert call Chunk payloads into 100-record batches with sequential submission and jitter
Webhook Subscriptions 25 subscriptions/app Maximum active webhook subscriptions per HubSpot app Consolidate event types per subscription endpoint where possible

Shopify Rate Limits

Constraint Limit Detail Mitigation
GraphQL Admin API (cost-based) 1,000 cost units/sec Each query has a calculated cost; bucket refills at 50 units/sec (standard) Request extensions.cost in GraphQL response and throttle based on throttleStatus
REST Admin API (legacy) 40 req/app/store/sec Leaky bucket algorithm; bucket size 80 calls; Shopify Plus: 80 req/sec Monitor X-Shopify-Shop-Api-Call-Limit header; implement leaky bucket client-side
Webhook Delivery Timeout 5 second response Shopify expects HTTP 200 within 5s or marks delivery as failed; retries up to 48h Immediately return 200 and process payload asynchronously via queue
Webhook Topics per Store DATA_UNAVAILABLE No hard limit publicly documented for webhook subscription count per store Validate with Shopify Partner support before high-volume subscription deployment
Bulk Operations (GraphQL) 1 concurrent/shop Only one bulk operation (bulkOperationRunQuery) can run at a time per shop Poll currentBulkOperation status before initiating new bulk exports

Critical Engineering Constraints


Idempotency is Non-Negotiable: Shopify will retry webhooks for up to 48 hours on non-2xx responses. Without an idempotency key (e.g. Shopify’s X-Shopify-Webhook-Id header mapped to a processed-events store), duplicate HubSpot objects (Deals, Contacts) will be created under high load or network instability.

Shopify API Versioning: Shopify deprecates API versions quarterly. All GraphQL Admin API calls must include an explicit version in the endpoint path (e.g. /admin/api/2025-01/graphql.json). Failing to upgrade before deprecation will cause silent failures. Subscribe to the Shopify Developer Changelog and build version upgrade automation into your CI/CD pipeline.

HubSpot Contact Deduplication: HubSpot deduplicates contacts by email by default, but the batch upsert endpoint requires explicit use of the idProperty parameter (set to email or a custom unique property). Without this, concurrent webhook processing of the same customer can create duplicate contact records that must be manually merged, corrupting pipeline attribution.

HubSpot Token Expiry (OAuth): HubSpot OAuth access tokens expire after 30 minutes. Any middleware service must implement proactive token refresh before expiry using the stored refresh token against https://api.hubapi.com/oauth/v1/token. Failure to handle 401 EXPIRED_AUTHENTICATION gracefully will cause data loss during high-volume order synchronization windows.

Shopify GraphQL Cost Throttling: Large nested GraphQL queries (e.g. fetching orders with all line items, customer, and fulfillments in one query) can exhaust the 1,000 cost unit bucket instantly. Always request the extensions block in every response to read throttleStatus.currentlyAvailable and implement adaptive query complexity splitting for bulk historical sync operations.

Official Documentation


HUBSPOT
API Reference Overview — All HubSpot APIs
VIEW DOCS →


HUBSPOT
CRM Associations API v4 — Object Relationship Management
VIEW DOCS →


HUBSPOT
Webhooks API v4 — Real-Time CRM Change Notifications
VIEW DOCS →


SHOPIFY
GraphQL Admin API Reference — Primary Shopify Admin Interface
VIEW DOCS →


SHOPIFY
Webhooks Reference — Event Topics, Delivery, and Verification
VIEW DOCS →


HUBSPOT
Authentication Guide — OAuth 2.0 and Private App Tokens
VIEW DOCS →