Platform
Chatbot Builder Bulk Messaging Team Inbox Mini CRM API & Webhooks AI Integration WhatsApp Flows
Industries
E-commerce & D2C Real Estate Education Healthcare Finance & BFSI Logistics Hospitality Retail
Integrations
Learn
Learning Hub Help & Docs Connect Guides Automation Codex Blog Message Templates
Pricing Get Started →
HomeConnect › Connect HubSpot to WhatsApp
HubSpot CRM Integration Guide · CRM / Sales

Connect HubSpot CRM to WhatsApp

Pull live contact data from HubSpot into a WhatsApp chatbot. When a lead messages you, look up their record, check lifecycle stage and deal status, and reply with personalised context, all without leaving WhatsApp.

Published 22 June 2026  ·  8 min read  ·  CRM / Sales

Before following this guide, read the External API Request step foundation guide. It covers every field in the step interface so this guide can focus on HubSpot-specific values.

Legacy API keys are deprecated: use Private Apps

HubSpot removed the old hapikey-based API keys in 2023. All integrations now use Private App access tokens. If you have an older integration using hapikey= in the URL, it no longer works. This guide uses the current Private App method only.

Step 1: Create a HubSpot Private App and get your access token

A Private App is HubSpot's way of generating a scoped Bearer token for internal integrations. You configure exactly which permissions it has.

1
In HubSpot, click the Settings gear icon (top right). In the left sidebar go to Integrations > Private Apps.
2
Click Create a private app. Give it a name like "WA.Expert Bot" and an optional description.
3
Click the Scopes tab. Search for and add crm.objects.contacts.read. If you also need deals, add crm.objects.deals.read.
4
Click Create app (top right). A dialog shows your access token starting with pat-na1- or pat-eu1-. Copy it immediately.
Access token shown once only

HubSpot displays the full Private App token only once after creation. A masked version is visible later but the full token cannot be retrieved. If lost, click Actions > Rotate token in the Private Apps settings to generate a new one.

Official docs

HubSpot Private Apps: developers.hubspot.com/docs/api/private-apps

Step 2: Fill in the External API Request step

In your WA.Expert chatbot flow, collect the HubSpot contact ID from the customer and store it as {{contact_id}}. Then add an External API Request step:

External API Request Step — WA.Expert
Select Method
GET
Request URL
https://api.hubapi.com/crm/v3/objects/contacts/{{{{contact_id}}}}?properties=firstname,lastname,email,phone,lifecyclestage,hs_lead_status,company
Select Auth Type
No Auth (Bearer token in header below)
Header Parameters
AuthorizationBearer pat-na1-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Content-Typeapplication/json
Select Body Type
None (GET requests carry no body)
Choose Response Type
JSON

Field-by-field breakdown

FieldValueNotes
Select MethodGETReading an existing contact record.
Request URLhttps://api.hubapi.com/crm/v3/objects/contacts/{{{contact_id}}}?properties=firstname,lastname,...The ?properties= query string controls which fields are returned. Without it, only default properties come back. List each property name you need.
Select Auth TypeNo AuthThe Bearer token goes in the Authorization header below.
AuthorizationBearer pat-na1-xxx...Include the word 'Bearer' followed by a space, then your Private App token. EU accounts use pat-eu1-.
Content-Typeapplication/jsonStandard header for HubSpot API requests.
Select Body TypeNoneGET requests carry no body.
Choose Response TypeJSONHubSpot returns structured JSON.
Request only the properties you need

Without a ?properties= query parameter, HubSpot returns a minimal default set. Add the property internal names you need. For example: firstname, lastname, email, phone, lifecyclestage, hs_lead_status, company, hubspot_owner_id. Find property internal names in HubSpot Settings > Properties.

Step 3: Map the response to WhatsApp variables

A successful HubSpot contact response looks like this:

HubSpot CRM API v3 — GET /crm/v3/objects/contacts/{id} response
{
  "id": "12345",
  "properties": {
    "firstname": "Priya",
    "lastname": "Sharma",
    "email": "priya@example.com",
    "phone": "+919820000001",
    "company": "Sharma Textiles",
    "lifecyclestage": "lead",
    "hs_lead_status": "IN_PROGRESS",
    "createdate": "2026-06-15T10:30:00.000Z",
    "lastmodifieddate": "2026-06-20T14:00:00.000Z"
  },
  "createdAt": "2026-06-15T10:30:00.000Z",
  "updatedAt": "2026-06-20T14:00:00.000Z",
  "archived": false
}
All contact fields are inside properties, not at the top level

HubSpot wraps every contact's data inside a 'properties' object. Map your variables using properties.fieldname notation: properties.firstname, properties.lifecyclestage, etc. Only id, createdAt, and updatedAt are at the top level.

Map these response paths to variables in the External API Request step:

Variable nameResponse pathExample value
contact_id_hsid12345
first_nameproperties.firstnamePriya
last_nameproperties.lastnameSharma
emailproperties.emailpriya@example.com
companyproperties.companySharma Textiles
lifecycle_stageproperties.lifecyclestagelead
lead_statusproperties.hs_lead_statusIN_PROGRESS

Lifecycle stage values: subscriber, lead, marketingqualifiedlead, salesqualifiedlead, opportunity, customer, evangelist, other. Lead status values: NEW, OPEN, IN_PROGRESS, OPEN_DEAL, UNQUALIFIED, ATTEMPTED_TO_CONTACT, CONNECTED, BAD_TIMING.

Keep the WhatsApp reply in the free service window

If the contact messaged you first within the last 24 hours, your reply is a free service conversation. If initiating outbound follow-up from HubSpot data, use an approved Utility or Marketing template.

Contacts rarely know their HubSpot ID. Use the search endpoint to look them up by phone number or email. This is a POST request with a JSON body:

HubSpot — search contact by phone number
POST https://api.hubapi.com/crm/v3/objects/contacts/search
Authorization: Bearer pat-na1-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Content-Type: application/json

Body:
{
  "filterGroups": [{
    "filters": [{
      "propertyName": "phone",
      "operator": "EQ",
      "value": "+919820000001"
    }]
  }],
  "properties": ["firstname", "lastname", "lifecyclestage", "hs_lead_status"]
}

Response:
{
  "results": [{
    "id": "12345",
    "properties": {
      "firstname": "Priya",
      "lifecyclestage": "lead",
      "hs_lead_status": "IN_PROGRESS"
    }
  }],
  "total": 1
}

Map: results[0].properties.firstname, results[0].properties.lifecyclestage

Worked example: lead status bot

Chatbot flow — HubSpot contact lookup
Customer sends their phone number via WhatsApp.
WA.Expert stores it as {{customer_phone}}.

External API Request step (POST search):
POST https://api.hubapi.com/crm/v3/objects/contacts/search
Body: { "filterGroups": [{"filters": [{"propertyName":"phone","operator":"EQ","value":"{{customer_phone}}"}]}],
        "properties": ["firstname","lifecyclestage","hs_lead_status","company"] }

Response mapped:
first_name      = "Priya"
lifecycle_stage = "lead"
lead_status     = "IN_PROGRESS"
company         = "Sharma Textiles"

Bot replies:
"Hi Priya, your current status with us:
Account: Sharma Textiles
Stage: Lead
Status: In Progress

Your account manager will follow up shortly.
Reply URGENT if you need immediate attention."

Troubleshooting

SymptomLikely causeFix
401 UnauthorizedInvalid token or missing Bearer prefixCheck the Authorization header reads exactly 'Bearer pat-na1-YOUR_TOKEN'. Rotate the token in HubSpot Private Apps settings if needed.
403 ForbiddenToken lacks required scopeEdit the Private App in HubSpot (Settings > Private Apps), add crm.objects.contacts.read scope, then rotate the token to get a new one with updated permissions.
404 Not FoundContact ID does not existConfirm the contact ID is correct. Use the search endpoint to find the contact first if the ID is uncertain.
Properties missing from responseFields not requested in ?properties= queryAdd the property internal names to the ?properties= parameter in the URL. Without this, HubSpot returns a minimal default set.
Private Apps option missing in SettingsAccount does not support Private AppsSome legacy free HubSpot accounts cannot create Private Apps. Upgrading to Starter or using OAuth is the alternative.
429 Too Many RequestsRate limit hitHubSpot allows 100-400 requests/second depending on plan. Add retry logic with a delay. For the WA.Expert External API Request step, avoid calling HubSpot inside a loop.

Common questions

What is a HubSpot Private App and why do I need one?
+
A Private App is HubSpot's current method for generating API access tokens. The old hapikey method was deprecated in 2023. A Private App token is scoped to specific permissions, shown only once at creation, and starts with pat-na1- or pat-eu1-.
Where do I create a HubSpot Private App?
+
Settings > Integrations > Private Apps > Create a private app. Add crm.objects.contacts.read scope. Click Create app and copy the token before closing the dialog.
What HubSpot scope do I need for contact lookup?
+
crm.objects.contacts.read for reading contacts. Add crm.objects.deals.read for deals. Add crm.objects.contacts.write if you want to update contact properties from WhatsApp.
Can I search by phone number instead of contact ID?
+
Yes. Use POST /crm/v3/objects/contacts/search with a filter on the phone property. The customer's WhatsApp number can be used as the search value directly.
What is the difference between HubSpot API v3 and the 2026-03 date-versioned format?
+
HubSpot introduced date-based versioning in 2026 (/crm/objects/2026-03/contacts). The older /crm/v3/ paths continue to work until their end-of-life. For integrations built today, /crm/v3/ is safe and stable.
Does this incur extra WA.Expert charges?
+
The External API Request step counts as one automation action per call. On the Complete plan this is included. On Starter, extra action packs apply from Rs. 49 per 1,000 actions.

Connect HubSpot to WhatsApp today

Free trial, no credit card required. And if you ever get stuck, we are the only platform in India that answers you live on WhatsApp.

Start Free Trial → Book a Demo
1