Outcome. New tickets are split into queues by pipeline or category and each queue rotates assignment evenly across its rep pool, so no ticket sits unowned.
Workflow mapEnrollment, branches and actions at a glance
flowchart TD
A[Ticket created, queue known] --> B{Ticket queue value?}
B -->|billing| C[Rotate to Billing pool]
B -->|technical| D[Rotate to Technical pool]
B -->|general| E[Rotate to General pool]
B -->|blank / unknown| F[Notify support ops + add to Needs manual triage list]
C --> G[Set routed date, notify new owner]
D --> G
E --> G
When to use it / when not to
- Use it when support has 2+ reps per queue (billing, technical, general) and tickets currently get triaged by hand.
- Use it when tickets come in faster than a manager can eyeball and assign them one by one.
- Do not use it if a queue has a single rep. Use a plain
Set property value(ticket owner) action instead, see Variants. - Do not use it for VIP or named accounts that need a fixed owner. Exclude those first with a list-based suppression, see tickets-sla-020.
Prerequisites
- Property:
Ticket queue(internal nameticket_queue), object ticket, field type dropdown select, options matching your queues (for examplebilling,technical,general). Why: this is the field the branch logic reads. Populate it via a support form hidden field, a chatflow routing question, or a workflow that infers it from subject/category (see tickets-sla-007 or tickets-sla-023 for the classification logic upstream of this workflow). - A rotation pool per queue: either an active HubSpot Team per queue,
or a manually maintained list of reps. Why:
Rotate record to ownerneeds a defined, static set of owners to rotate across. - Confirm every rep in a rotation pool has an active seat. A deactivated rep in the list is skipped by the rotate record owner action and shows with a red border in routing rules, so the rotation keeps working on the remaining active seats (https://knowledge.hubspot.com/user-management/remove-hubspot-users).
- A connected support inbox and at least one ticket pipeline already in use, so tickets exist to test against.
- Property:
Ticket routed date(internal nameticket_routed_date), object ticket, field type date picker. Why: it stamps the moment a ticket was routed, used for SLA timing and rotation reporting.
Enrollment
- Trigger type: event-based.
- Criteria:
Ticket createdANDTicket queue is known(value present). - Re-enrollment: off. A ticket should not re-roll owner assignment every time an unrelated property changes; unintended reassignment mid-conversation confuses the customer and the rep.
- Suppression: static list
VIP accounts - manual ticket assignmentexcluded via enrollment filterAssociated company not in list.
Steps
- If/then branch:
Ticket queueisbilling- Rotate record to owner: pool = Billing team rotation
- Set property value:
Ticket routed date= current date - Send internal email notification to: ticket owner, subject "New ticket assigned: {{ticket.subject}}"
- If/then branch:
Ticket queueistechnical- Same 3 actions as above, pool = Technical team rotation
- If/then branch:
Ticket queueisgeneral- Same 3 actions as above, pool = General team rotation
- Else branch (queue unknown or blank)
- Send internal email notification to support ops distribution owner: "Ticket with no queue value: {{ticket.hs_object_id}}"
- Add to static list: "Needs manual triage"
Known pitfalls
Rotate record to ownerrotates evenly at the moment it fires. Adding or removing a rep from a pool does not rebalance tickets already assigned.- If
Ticket queueis set by a chatflow routing question, it only fires for chat-originated tickets. Email and form-originated tickets need a separate classification step upstream, or they land in the Else branch. - Re-enrollment left on will re-roll an already-assigned, already-worked ticket to a new owner the next time queue is edited. Keep it off unless reassignment is the intent.
- Rotation pools built as manual lists do not update when someone joins or leaves the team. Review membership monthly, or use an active HubSpot Team as the pool where the tier allows it.
- Business hours are not applied automatically. A ticket created at 2 a.m. still rotates immediately unless you add a business-hours condition, see tickets-sla-016.
Test plan
- Create 3 test tickets, one per queue value, via the support form or by setting the property manually.
- Open workflow history (Automation > Workflows > this workflow > History tab) and confirm each ticket enrolled within a minute.
- Check each ticket record's timeline for the owner assignment event and confirm it matches the expected pool.
- Confirm the internal email notification arrived in the assigned rep's inbox.
- Create one ticket with
Ticket queueleft blank and confirm it lands in the "Needs manual triage" list with the ops notification sent.
Variants
- Single rep per queue: replace
Rotate record to ownerwithSet property value(ticket owner = fixed rep). - Chat-originated tickets only: trigger on
Ticket createdfiltered toTicket source = Chat, skip the queue property and route directly by chatflow inbox. - Weighted by current open-ticket load instead of even split: see the weighted rotation pattern in lead-routing-014.
Build spec
trigger:
type: event-based
event: ticket_created
criteria:
- ticket_queue: is_known
reenrollment: false
suppression_list: "VIP accounts - manual ticket assignment"
branches:
- condition: ticket_queue == "billing"
actions:
- type: rotate_record_to_owner
pool: "Billing team rotation"
- type: set_property_value
property: ticket_routed_date
value: current_date
- type: send_internal_email_notification
to: ticket_owner
subject: "New ticket assigned: {{ticket.subject}}"
- condition: ticket_queue == "technical"
actions: [same_as_above, pool: "Technical team rotation"]
- condition: ticket_queue == "general"
actions: [same_as_above, pool: "General team rotation"]
- condition: else
actions:
- type: send_internal_email_notification
to: support_ops_owner
subject: "Ticket with no queue value: {{ticket.hs_object_id}}"
- type: add_to_static_list
list: "Needs manual triage"



