LanguageENES
DestinationsAvailable on Starter

Send leads to HubSpot

Connect a private app's service key, map the fields, and every new lead becomes a contact.

Updated 2026-09-11View .md

What you need

A private app's service key -- the token HubSpot issues on the app's own Auth tab. HubSpot → Settings → Integrations → Private apps → create an app → Auth → copy it. It starts with pat-.

It must be granted these eight scopes:

Scope
Why
crm.objects.contacts.write
Create or update the contact. Without it nothing can be sent.
crm.objects.contacts.read
Find the contact first, so one person stays one record.
crm.schemas.contacts.read
List the contact properties you map onto.
crm.schemas.contacts.write
Create a new contact property from the route builder.
crm.objects.companies.read / .write
HubSpot associates a contact with a company by itself; without these a contact write can fail on the association.
crm.schemas.companies.read / .write
List and create company properties.

Routes that land on a Deal need crm.objects.deals.read and crm.objects.deals.write; a route that lands on a Ticket needs tickets. The read is not optional: the route builder lists the object's properties before you can map onto them, and a token with only the write fails on that first list with "HubSpot accepted the token but the private app is missing the deals-read scope".

A Personal Access Key is not this. A HubSpot developer account issues a key carrying developer.* and cms.* scopes and, at most, CRM read; it cannot be granted crm.objects.contacts.write, so no lead could ever be written with it however new it is. The credential has to come from a private app inside the CRM portal you want the leads in.

Connect and route

  1. In Destinations, connect HubSpot with the token.
  2. Create a route: pick the object (usually Contact) and which widget's leads it takes. Leave the widget empty and it takes every lead.
  3. Map the fields. Auto-map fills in what it is confident about; check it and fix the rest.

One route per widget, and so one per form

A route's scope is a widget. Leave it on all widgets and the route takes every lead; pin it to one and it takes only that widget's.

That is also how two forms reach two places, because a widget runs one form: its lead capture names the form it asks, so choosing the widget chooses the form. A contact form on one widget and a demo request on another are two routes, each to its own destination. Two forms on the same widget is not a thing you can set up -- swap the widget's form and you have changed which form it asks.

Choosing a widget does one more thing: the mapper's left column shows the questions that form asks, instead of every question every form in the workspace asks. So a route built for the demo request is not mapped against the contact form's fields, and the questions on screen are the ones a visitor will actually be asked. Leave the route on all widgets and you get all of them, which is right -- the route takes leads from all of them.

One consequence worth knowing: a lead captured by the assistant in conversation carries the widget it came from, so a widget-scoped route takes it like any other. A lead pushed through the API with no widget is taken only by a route with no widget.

How a lead arrives

Contacts are matched by email, so the same person filling in a form twice updates one record rather than creating two.

A field with nothing behind it is left out of the request rather than sent empty, because an empty value would overwrite what HubSpot already knows about that person.

Check it before a visitor does

  • Check connection on the account re-asks HubSpot whether the stored token still works and records the answer with today's date. A token that has been revoked, rotated or whose app was uninstalled comes back from HubSpot as "expired 20703 day(s) ago" -- that number is the age of the unix epoch, not a fact about your token, so we translate it.
  • Send sample lead creates one invented contact through this route, so you can see exactly what arrives. It uses the same mapping a real lead uses. It is not stored as a lead and does not count against your plan; the dispatch log marks it as a sample.

When it fails

The dispatch log under the routes shows every attempt, what we sent and what HubSpot answered. Common answers:

  • 401 or 403. The token was revoked, or it lacks a scope. The connection is marked with an error.
  • A property does not exist. Create it in HubSpot, or use New field in the route dialog.
  • A required property is missing. The lead had nothing for it. Either map another source or make the property optional in HubSpot.

Network problems and HubSpot outages are retried five times over about two hours. A rejected request is not retried, because sending the same wrong thing again will not fix it.

Send chatbot leads to HubSpotEvery captured lead becomes a contact