# HubSpot integration via Zapier

Removes the "ConstructConnect has a native HubSpot connector" objection.
We use Zapier as the bridge — same end result, no proprietary integration
to maintain, customer gets the flexibility of a Zap they own.

> **Estimated setup time:** 8 minutes one-time. Recurring cost: $0
> on Zapier's free tier (100 tasks/month is more than enough for
> a typical 50-row weekly delivery).

## What you'll end up with

Every Monday morning (or whenever your delivery webhook fires), each
new permit becomes a HubSpot **Contact** + **Company** record + an
optional **Deal** in your pipeline, tagged with `source = shovel-radar`.

You search HubSpot for `source = shovel-radar AND created_at > last_monday`
to see the week's new leads. Or assign them to a sales-rep round-robin
via HubSpot's built-in workflow.

## The Zap

### Step 1 — Trigger

- App: **Webhooks by Zapier**
- Event: **Catch Hook**
- Copy the webhook URL Zapier gives you (`https://hooks.zapier.com/...`)
  → paste it into your Shovel Radar dashboard at **Account → Webhook URL**

### Step 2 — Filter (optional)

- App: **Filter by Zapier**
- Only continue if: `delivery.row_count` is **greater than 0**

  (Stops empty deliveries from cluttering HubSpot.)

### Step 3 — Loop over permit rows

- App: **Looping by Zapier**
- Loop input: `delivery.permits` (or whatever field name your custom
  delivery includes — see Shovel Radar's `/integrations/` for the
  canonical schema)

### Step 4 — Search HubSpot for an existing contact

- App: **HubSpot**
- Event: **Find Contact**
- Lookup field: `email` (use the permit's `phone` if no email — HubSpot
  will create a phone-only contact)
- If not found → continue to Step 5 (create)
- If found → continue to Step 6 (update)

### Step 5 — Create HubSpot Contact

- App: **HubSpot**
- Event: **Create Contact**
- Map fields:
  | HubSpot Field   | Permit field                  |
  |---|---|
  | First Name      | (parse from applicant)         |
  | Last Name       | (parse from applicant)         |
  | Company         | applicant or contractor        |
  | Phone           | phone (if present)             |
  | Address         | address                        |
  | City            | city                           |
  | Lifecycle Stage | `lead`                         |
  | Source          | `shovel-radar`                 |
  | Notes / Description | `Permit: {permit_id} · Scope: {description[:120]} · Cost: ${cost}` |

### Step 6 — Create HubSpot Deal (optional but recommended)

- App: **HubSpot**
- Event: **Create Deal**
- Map fields:
  | Deal Field   | Permit field |
  |---|---|
  | Deal Name    | `{applicant} — {scope_short}` |
  | Pipeline     | (your sales pipeline ID)       |
  | Stage        | `appointment_scheduled` (or your "new lead" stage) |
  | Amount       | `cost` × your typical close % (or just cost) |
  | Associated Contact | from Step 5 |
  | Deal Source  | `shovel-radar`                 |

### Step 7 — Tag for round-robin (optional)

- App: **HubSpot**
- Event: **Update Contact**
- Add tag: `unassigned-permit-lead`

  HubSpot's own workflow can then watch for that tag and assign to
  next rep in your team queue.

## Testing

1. In your Shovel Radar dashboard, click "Send test webhook" (you'll
   need to add this button — see `api/v1/portal_action.py` for the
   pattern, action=`test_webhook`).
2. Zapier shows the payload in the "Test" section of your trigger step.
3. Run a single record through the rest of the Zap.
4. Confirm HubSpot has a new contact / deal in the right pipeline.

## Common gotchas

- **HubSpot field permissions** — your HubSpot user account must have
  "Create" permissions on Contacts + Deals. Ask your admin if you're
  on a team account.
- **HubSpot rate limits** — free HubSpot allows 250 API calls/day,
  Starter 500k/day. A 50-row delivery uses 50-100 calls, well within
  limits.
- **Phone-only contacts** — HubSpot treats `email` as the primary
  identifier. To dedupe properly when many permits have no email,
  add a `permit_id` custom property and dedupe on that instead.
- **Currency** — Shovel Radar's `cost` is in CAD. If your HubSpot
  default is USD, add a conversion step (or set the Deal Currency
  field explicitly to CAD).

## Cost

| Tier | Monthly cost | Sufficient for |
|---|---|---|
| Zapier Free | $0 | 100 tasks/month = ~25 permits/week if you skip the deal step |
| Zapier Starter | $20 USD | 750 tasks/month = ~180 permits/week |
| HubSpot Free | $0 | 1,000 contacts total — fine for 6-12 months |
| HubSpot Starter | $15 USD | 5 users, 1,000 marketing contacts |

**Net:** $0/mo if you stay under 100 weekly permits + use HubSpot Free.

## What we deliberately don't build (and why)

Shovel Radar will NOT ship a "native HubSpot connector" any time soon.
Reasons:
- Zapier already covers 95% of customer use cases at no marginal
  cost to us
- A native connector means maintaining HubSpot's API contract forever
  (they change it ~yearly)
- Customers who want deeper integration (custom HubSpot properties,
  bidirectional sync) need a real systems integrator, not a SaaS
  vendor's pre-built tool

If a customer's HubSpot use case truly outgrows Zapier, escalate to
matthew@shovelradar.com — sometimes a one-off custom script is the
right answer.
