Round-robin route HubSpot leads and notify reps in Slack using Zapier

low complexityCost: $20-50/mo

Prerequisites

Prerequisites
  • Zapier account (Professional plan or higher for Code by Zapier)
  • HubSpot account connected to Zapier via OAuth
  • Slack workspace connected to Zapier
  • A mapping of HubSpot owner IDs to Slack user IDs

Why Zapier?

Zapier is the simplest setup for round-robin routing if you already have an account. Storage by Zapier provides a built-in key-value store for the round-robin counter — no external database needed. The main trade-off is cost: this is a 7-task Zap requiring the Professional plan ($29.99/mo), and polling delay of 1-15 minutes means it's not truly instant.

For teams that prioritize simplicity over speed, this is a solid choice.

How it works

  • New Contact trigger fires when a lead arrives in HubSpot
  • Filter skips contacts that already have an owner assigned
  • Storage by Zapier reads the current round-robin counter
  • Code by Zapier selects the next rep from the roster and calculates the new counter value
  • Storage by Zapier writes the updated counter
  • HubSpot Update Contact sets the owner
  • Slack Send DM notifies the assigned rep

Step 1: Set up the HubSpot trigger

Create a new Zap. Choose HubSpot as the trigger:

  • Trigger event: New Contact
  • Additional Properties to Retrieve: firstname, lastname, email, company, jobtitle, hubspot_owner_id
Don't forget additional properties

HubSpot's Zapier trigger returns minimal fields by default. Without adding properties to retrieve, your Slack notification will be blank.

Step 2: Filter out already-assigned contacts

Add a Filter step:

  • Condition: hubspot_owner_id → Does not exist

This prevents re-assigning contacts that were already routed by another workflow or manually assigned.

Step 3: Round-robin with Storage by Zapier

Add a Storage by Zapier step to track the round-robin counter:

  • Action: Get Value
  • Key: round_robin_index
  • Default: 0

Then add a Code by Zapier step to calculate the assignment:

  • Language: JavaScript
  • Input Data:
    • currentIndex -> Value from Storage step
const reps = [
  { name: "Alice", hubspotOwnerId: "12345678", slackUserId: "U01AAAA" },
  { name: "Bob",   hubspotOwnerId: "23456789", slackUserId: "U02BBBB" },
  { name: "Carol", hubspotOwnerId: "34567890", slackUserId: "U03CCCC" },
  { name: "Dave",  hubspotOwnerId: "45678901", slackUserId: "U04DDDD" },
];
 
const index = parseInt(inputData.currentIndex || '0');
const rep = reps[index % reps.length];
const nextIndex = (index + 1) % reps.length;
 
output = [{
  repName: rep.name,
  hubspotOwnerId: rep.hubspotOwnerId,
  slackUserId: rep.slackUserId,
  nextIndex: nextIndex,
}];

Then add another Storage by Zapier step:

  • Action: Set Value
  • Key: round_robin_index
  • Value: {{nextIndex}} from the Code step
Why Storage by Zapier?

Zapier Zaps are stateless -- each run is independent. Storage by Zapier provides a simple key-value store that persists across runs, perfect for tracking which rep is next.

Step 4: Update the contact owner in HubSpot

Add a HubSpot action:

  • Action event: Update Contact
  • Contact: Use the contact ID from the trigger step
  • Contact Owner: {{hubspotOwnerId}} from the Code step

Step 5: Send a Slack DM to the assigned rep

Add a Slack action:

  • Action event: Send Direct Message
  • User: {{slackUserId}} from the Code step
  • Message Text:
🆕 *New Lead Assigned to You*
*{{firstname}} {{lastname}}* — {{jobtitle}} at {{company}}
Email: {{email}}
<https://app.hubspot.com/contacts/YOUR_PORTAL_ID/contact/{{hs_object_id}}|View in HubSpot>

Step 6: Test and publish

  1. Click Test on each step
  2. Verify the HubSpot contact owner was updated
  3. Verify the Slack DM was received by the correct rep
  4. Turn the Zap On

Limitations

  • Polling delay: Zapier polls HubSpot every 1-15 minutes depending on your plan. Not truly instant.
  • Race conditions: If two contacts arrive in the same polling cycle, both Code steps may read the same counter value before either writes back. In practice this is rare and self-corrects on the next assignment.
  • Storage by Zapier counts as a step, so this is a 5-step Zap (trigger + filter + storage read + code + storage write + HubSpot update + Slack = 7 tasks).

Troubleshooting

Common questions

How many leads can I route per month on the Professional plan?

Professional gives 750 tasks/mo. Each lead uses 7 tasks (trigger + filter + storage read + code + storage write + HubSpot update + Slack). That's roughly 107 leads/month. Team plan ($69.99/mo) gives 2,000 tasks for ~285 leads/month.

Is there a race condition risk with Storage by Zapier?

Yes, but it's rare. If two contacts arrive in the same polling cycle, both Code steps may read the same counter before either writes back. In practice, this happens infrequently and self-corrects on the next assignment. For guaranteed fairness, use the Code + Cron approach with atomic Redis counter updates.

Can I use Zapier Paths instead of a Code step for the routing logic?

For a small team (2-3 reps), you could use Paths with conditions based on the counter value. But it doesn't scale — each new rep adds another Path branch. The Code step with an array lookup is cleaner and easier to maintain.

Cost

  • Professional plan: $29.99/mo minimum. Each new lead = 7 tasks (one per step).
  • Team plan: $69.99/mo if you need more tasks or faster polling.

Looking to scale your AI operations?

We build and optimize automation systems for mid-market businesses. Let's discuss the right approach for your team.