Automation Blog

Round Robin Assignment and Array Randomization in Zapier Code Steps

How to distribute items evenly across a list using round robin assignment, and how to randomly shuffle an array — both inside a Zapier JavaScript Code step, with persistent state for round robin tracking using Zapier Storage.

ZapierJavaScriptCode Steps

By Troy Tessalone · · 5 minutes

Automation Guide

A practical field guide from Automation Ace.

Round Robin Assignment and Array Randomization in Zapier Code Steps

Two common distribution patterns in Zapier workflows: round robin (assign each new item to the next person in sequence, cycling back to the start) and random selection (pick a random item from a list each time). Round robin requires persistent state across Zap runs — you need to remember which person was last assigned. Zapier Storage handles this. Random selection is stateless and simpler. Both are achievable entirely within a Code step.

Random Selection: Pick One Item from a List

The simplest version — randomly select one item from a comma-separated list on each Zap run:

const items = inputData.items.split(',').map(s => s.trim()).filter(Boolean);
// e.g. "Alice,Bob,Carol,Dave"

if (items.length === 0) throw new Error('No items to select from');

const randomIndex = Math.floor(Math.random() * items.length);
const selected = items[randomIndex];

output = {
  selected,
  index: String(randomIndex),
  total_items: String(items.length)
};

Shuffle an Entire Array (Fisher-Yates)

To randomize the order of all items (not just pick one), use the Fisher-Yates shuffle — the standard algorithm that produces a uniformly random permutation:

const items = inputData.items.split(',').map(s => s.trim()).filter(Boolean);

// Fisher-Yates shuffle — mutates a copy, not the original
const shuffled = [...items];
for (let i = shuffled.length - 1; i > 0; i--) {
  const j = Math.floor(Math.random() * (i + 1));
  [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; // swap
}

output = {
  shuffled: shuffled.join(','),
  first: shuffled[0] || '',
  second: shuffled[1] || '',
  count: String(shuffled.length)
};

Avoid .sort(() => Math.random() - 0.5) — it's a common but statistically biased shuffle. The Fisher-Yates algorithm above is the correct approach.

Round Robin: Stateless Version (Timestamp-Based)

If exact round robin distribution isn't critical — you just want a deterministic but rotating assignment — use the current timestamp modulo the list length:

const assignees = inputData.assignees.split(',').map(s => s.trim()).filter(Boolean);
// e.g. "alice@example.com,bob@example.com,carol@example.com"

if (assignees.length === 0) throw new Error('No assignees configured');

// Rotate based on current minute — changes every minute, cycles through list
const index = Math.floor(Date.now() / 60000) % assignees.length;
const assigned = assignees[index];

output = {
  assigned_to: assigned,
  index: String(index),
  assignee_count: String(assignees.length)
};

This is simple but imprecise — if multiple Zap runs happen within the same minute, they all get the same assignee. For true sequential round robin across runs, use Zapier Storage.

Round Robin: Stateful Version with Zapier Storage

For true round robin that remembers position across Zap runs, use the Zapier Storage API to persist the current index:

const assignees = inputData.assignees.split(',').map(s => s.trim()).filter(Boolean);
const storageSecret = inputData.storage_secret; // your Zapier Storage secret key
const storageKey = 'round_robin_index';

if (assignees.length === 0) throw new Error('No assignees configured');

// Read current index from Zapier Storage
const getResponse = await fetch(
  `https://store.zapier.com/api/records?secret=${storageSecret}`
);
const stored = await getResponse.json();
const currentIndex = parseInt(stored[storageKey] || '0', 10);

// Select the current assignee
const validIndex = currentIndex % assignees.length;
const assigned = assignees[validIndex];

// Increment and save the next index
const nextIndex = (validIndex + 1) % assignees.length;
await fetch('https://store.zapier.com/api/records', {
  method: 'POST',
  headers: { 'X-Secret': storageSecret },
  body: JSON.stringify({ [storageKey]: String(nextIndex) })
});

output = {
  assigned_to: assigned,
  current_index: String(validIndex),
  next_index: String(nextIndex),
  assignee_count: String(assignees.length)
};

Pass assignees as a comma-separated input field (e.g., "alice@co.com,bob@co.com,carol@co.com") and storage_secret as a static value from your Zapier Storage setup. The round robin cycles through the list in order, resetting to index 0 after the last assignee.

Round Robin with Multiple Keys (Per-Team or Per-Queue)

To maintain separate round robin counters for different categories — different teams, different record types — use distinct storage keys:

const team = inputData.team; // e.g. 'sales', 'support'
const storageKey = `round_robin_${team}`; // unique key per team

// ...same Storage read/write logic as above, using the dynamic key

Weighted Random Selection

To select randomly but with different probabilities (e.g., senior reps get more leads):

// Define assignees with weights (higher weight = more likely to be selected)
const pool = [
  { name: 'Alice', weight: 3 },  // Alice gets ~3x more assignments
  { name: 'Bob',   weight: 2 },
  { name: 'Carol', weight: 1 }
];

// Build a weighted array by repeating each item by its weight
const weighted = pool.flatMap(p => Array(p.weight).fill(p.name));

const selected = weighted[Math.floor(Math.random() * weighted.length)];

output = {
  assigned_to: selected,
  pool_size: String(weighted.length)
};
True round robin in Zapier requires persistent state — a counter that survives across Zap runs. Zapier Storage is the simplest way to implement this without an external database. For pure randomization without state, Math.random() with Fisher-Yates shuffle handles any distribution need. Both patterns are single Code step solutions that don't require additional Zap steps.

For Zapier Storage setup and other persistence patterns, see the Zapier Storage API guide. For general JavaScript array operations, see JavaScript array methods in Zapier Code steps. For help building a lead routing or assignment workflow, talk to Automation Ace.

ZapierJavaScriptCode Steps

Disclaimer: This article may include links to apps, products, or services. Some links may be affiliate links, which means Automation Ace may earn a commission at no extra cost to you.

Build Better Systems

Ready to automate with confidence?

Share your tools, process, and goals. Automation Ace can design the workflow, integration, AI assist, or code bridge that fits your business.

Start a Project