Automated case routing using custom properties for service tier management

Our support team was drowning in manual ticket routing. We have three service tiers (Premium, Standard, Basic) with different SLA requirements, and agents were spending significant time each day manually reviewing new tickets and assigning them to the appropriate queue based on the customer’s service level.

The manual process was error-prone - tickets sometimes got routed to wrong queues, priority customers weren’t always getting the fast response they paid for, and during high-volume periods, tickets could sit unassigned for hours. We needed to automate the routing based on customer service tier while maintaining flexibility for special cases.

Here’s how we implemented automated case routing using HubSpot workflows and custom properties:


// Custom properties created:
service_tier (dropdown: Premium/Standard/Basic)
sla_response_time (number: hours)
ticket_priority_score (calculated field)

The workflow automatically assigns tickets to tier-specific queues, sets priority levels, and triggers escalation notifications when SLAs are at risk. Since implementation, our average first response time improved by 45% and SLA compliance went from 78% to 96%.

The priority score was tricky. We ended up creating a workflow that calculates it based on multiple inputs: service tier (40% weight), issue category (30%), customer lifetime value (20%), and time since last contact (10%). The workflow runs on ticket creation and updates the priority score property, which then feeds into the routing logic. Took some tuning to get the weights right but it’s working well now.

I’ll walk through the complete implementation since several people asked for details:

Custom Property Setup:

We created several custom properties on the ticket object to support the routing logic:

  1. service_tier (Dropdown): Premium, Standard, Basic

    • Synced from company property via workflow
    • Updated automatically when customer upgrades/downgrades
  2. sla_response_time (Number): Response time in hours

    • Premium: 2 hours
    • Standard: 8 hours
    • Basic: 24 hours
    • Set automatically based on service_tier
  3. ticket_priority_score (Number, 0-100): Calculated priority

    • Determines routing and escalation behavior
    • Calculated by scoring workflow (see below)
  4. sla_deadline (Date/Time): When SLA response is due

    • Calculated as ticket_created_date + sla_response_time
    • Used for escalation triggers
  5. override_routing (Checkbox): Manual routing flag

    • Allows agents to bypass automation for special cases
    • Tickets with this checked go to manual review queue
  6. escalation_triggered (Checkbox): Tracks if escalation sent

    • Prevents duplicate escalation notifications
    • Reset when ticket is assigned

Workflow-Based Routing:

We built this as a master workflow with branching logic rather than separate workflows per tier. This made it easier to maintain consistent logic and add new tiers. The workflow structure:


// Workflow: Automated Ticket Routing
// Trigger: Ticket created or updated
// Enrollment: When ticket_status = New AND assigned_to = null

1. Check if override_routing = true
   → If yes: Add to 'Manual Review' queue, exit

2. Sync service_tier from company to ticket
   → Copy company.service_tier to ticket.service_tier

3. Set SLA response time based on tier
   → If service_tier = Premium: Set sla_response_time = 2
   → If service_tier = Standard: Set sla_response_time = 8
   → If service_tier = Basic: Set sla_response_time = 24

4. Calculate SLA deadline
   → Set sla_deadline = ticket_created_date + sla_response_time hours

5. Calculate priority score (see scoring logic below)

6. Route to appropriate queue based on priority score
   → Score 80-100: Premium queue (regardless of tier)
   → Score 60-79: Standard queue
   → Score 0-59: Basic queue

Priority Score Calculation:

The priority score workflow runs immediately after ticket creation and weighs multiple factors:


// Priority Scoring Logic
// Base score starts at 50

1. Service Tier Component (40% weight, 0-40 points):
   → Premium tier: +40 points
   → Standard tier: +20 points
   → Basic tier: +0 points

2. Issue Category Component (30% weight, 0-30 points):
   → Security Incident: +30 points (auto-escalate)
   → Service Outage: +30 points (auto-escalate)
   → Billing Issue: +20 points
   → Feature Request: +5 points
   → General Question: +10 points

3. Customer Value Component (20% weight, 0-20 points):
   → If company.lifetime_value > $50k: +20 points
   → If company.lifetime_value > $20k: +15 points
   → If company.lifetime_value > $5k: +10 points
   → Else: +5 points

4. Recency Component (10% weight, 0-10 points):
   → If last_contact_date < 7 days ago: +10 points
   → If last_contact_date < 30 days ago: +5 points
   → Else: +0 points

Final score = Sum of all components (0-100 scale)

This scoring system ensures that truly urgent issues get prioritized regardless of service tier. For example, a security incident from a Basic tier customer would score around 80 (0+30+10+5=85) and get routed to the Premium queue for immediate attention.

SLA Tracking and Escalation:

We use a separate escalation workflow that monitors tickets approaching their SLA deadline:


// Workflow: SLA Escalation Monitor
// Trigger: Scheduled daily at 9 AM, 1 PM, 5 PM
// Enrollment: All open tickets where assigned_to = null

1. Calculate time remaining until SLA deadline
   → time_remaining = sla_deadline - current_time

2. Escalation triggers:
   → If time_remaining < 1 hour AND escalation_triggered = false:
      - Send urgent notification to support manager
      - Add ticket to 'SLA Risk' view
      - Set escalation_triggered = true

   → If time_remaining < 25% of sla_response_time:
      - Send warning notification to queue owner
      - Increase priority score by 20 points
      - Re-run routing workflow (may move to higher queue)

Handling Edge Cases:

To Brian’s question about edge cases, we handle several scenarios:

  1. VIP Override: Certain companies have ‘vip_account’ flag that automatically adds 30 points to priority score, ensuring Premium queue routing regardless of official service tier.

  2. After-Hours Routing: We added time-based logic:

    • Tickets created outside business hours (6 PM - 8 AM, weekends) get queued
    • Premium tier tickets still route immediately (we have 24/7 coverage for Premium)
    • Standard/Basic tickets get a ‘pending_business_hours’ status and route at 8 AM next business day
    • This prevents overnight queue buildup and allows for better load balancing
  3. Manual Override: The override_routing checkbox gives agents flexibility for unusual situations without breaking automation.

  4. Auto-Escalate Categories: Security incidents and service outages automatically route to Premium queue with manager notification, regardless of customer tier.

Results After 6 Months:

  • First Response Time: Improved from average 6.2 hours to 3.4 hours (45% improvement)
  • SLA Compliance: Increased from 78% to 96%
  • Manual Routing Time: Reduced from 2-3 hours/day to ~20 minutes/day (reviewing exceptions only)
  • Customer Satisfaction: CSAT scores improved from 3.8 to 4.3 (out of 5)
  • Agent Efficiency: Agents handle 30% more tickets due to reduced routing overhead
  • Missed SLAs: Down from 22% to 4% of tickets

Lessons Learned:

  1. Tuning Takes Time: We adjusted the priority scoring weights three times in the first month based on actual results. Start conservative and iterate.

  2. Exception Handling is Critical: Don’t over-automate. The override mechanism is used on 8% of tickets and prevents automation from becoming a constraint.

  3. Transparency Matters: We created a dashboard showing routing decisions and priority scores so agents understand why tickets go where they do. This built trust in the system.

  4. Monitor Edge Cases: We review all manually overridden tickets weekly to identify patterns that should be incorporated into automation rules.

  5. SLA Escalation is Key: The automation handles routing, but the escalation workflow ensures nothing falls through the cracks. This combination is what drove our SLA compliance improvement.

To Tom’s question about maintainability: The single master workflow with branching logic has been much easier to maintain than separate workflows would have been. When we added a new ‘Enterprise’ tier last month, it was a simple matter of adding one more branch to the existing logic rather than creating and testing an entirely new workflow.

The system isn’t perfect - we still have manual review for about 8% of tickets - but it’s transformed our support operations from reactive chaos to proactive management. The time saved on manual routing has been reinvested in improving response quality and proactive customer outreach.

We implemented something similar last year but ran into issues with edge cases - VIP customers who technically have Standard tier but need Premium treatment, or urgent issues from Basic tier customers that still need fast response. How do you handle overrides and exceptions without breaking the automation?

The calculated priority score approach is smart. We’ve been manually setting priorities and it’s inconsistent across agents. One thing I’m wondering - how do you handle tickets that come in outside business hours? Do they get routed immediately or do you queue them for next business day?

Love the SLA compliance improvement. Did you build separate workflows for each service tier, or one master workflow with branching logic? We’re trying to decide which approach is more maintainable long-term. Also curious how you handle SLA tracking - are you using HubSpot’s native SLA features or custom properties?

This is great! How did you handle the calculated priority score? We’re looking at similar automation but struggling with how to weigh different factors (service tier, issue type, customer value) into a single routing decision.