Alert Slack before Zendesk SLA breaches using n8n

medium complexityCost: $0-24/moRecommended

Prerequisites

Prerequisites
  • n8n instance (cloud or self-hosted)
  • Zendesk API credentials: agent email and API token (Admin Center → Apps and integrations → APIs → Zendesk API)
  • Your Zendesk subdomain (the acme part of acme.zendesk.com)
  • Slack Bot Token with chat:write scope
  • Slack channel ID for SLA alerts (right-click channel → View channel details → copy the ID at the bottom)

Overview

This workflow runs on a 15-minute schedule, fetches all open tickets from Zendesk, retrieves SLA metrics for each, and filters for tickets approaching their breach deadline. When a ticket's remaining SLA time drops below your warning threshold, the workflow posts a Slack Block Kit alert with the ticket details, time remaining, and a direct link to the ticket. This gives your team 15-minute precision on SLA warnings — far tighter than the hourly variance of native Zendesk automations.

Step 1: Set up Zendesk credentials in n8n

Create a new credential in n8n:

  • Type: Zendesk API
  • Subdomain: your Zendesk subdomain (e.g., acme)
  • Email: your Zendesk agent email
  • API Token: your Zendesk API token

Zendesk API auth uses the format {'{'}email{'}'}/token:{'{'}api_token{'}'} as the username with Basic auth. n8n handles this automatically when you use the Zendesk credential type.

Step 2: Add a Schedule Trigger

Add a Schedule Trigger node as the workflow entry point:

  • Trigger Interval: Every 15 minutes

This gives you four checks per hour — enough to catch most approaching breaches with time for agents to act.

Step 3: Fetch open tickets

Add an HTTP Request node to search for open, pending, and new tickets:

  • Method: GET
  • URL: https://{'{'}your-subdomain{'}'}.zendesk.com/api/v2/search.json?query=type:ticket status:open status:pending status:new&per_page=100
  • Authentication: Predefined Credential Type → Zendesk API
  • Credential: Select your Zendesk credential

This returns all active tickets that could have SLA timers running.

Pagination for large queues

The Zendesk search API returns up to 100 results per page. If you have more than 100 open tickets, add a Loop node to paginate using the next_page URL from the response. For most teams, 100 results captures the active queue.

Step 4: Loop through tickets to get metrics

Add a SplitInBatches node to iterate over each ticket from the search results.

Then add an HTTP Request node inside the loop to fetch SLA metrics for each ticket:

  • Method: GET
  • URL: https://{'{'}your-subdomain{'}'}.zendesk.com/api/v2/tickets/{'{'}$json.id{'}'}/metrics.json
  • Authentication: Predefined Credential Type → Zendesk API
  • Credential: Select your Zendesk credential

This endpoint returns the ticket's SLA timing data including reply_time_in_minutes and full_resolution_time_in_minutes, each with business and calendar sub-objects containing target, elapsed, and is_completed fields.

Step 5: Merge and filter for approaching breaches

After the loop completes, add a Code node to check which tickets are approaching their SLA deadline:

const metrics = $input.all();
const warnings = [];
const WARN_MINUTES = 60; // Alert 60 minutes before breach
 
for (const item of metrics) {
  const m = item.json.ticket_metric;
  if (!m) continue;
 
  const ticketId = m.ticket_id;
 
  // Check reply time SLA
  const replyBreach = m.reply_time_in_minutes?.business;
  if (replyBreach && !replyBreach.is_completed) {
    const target = replyBreach.target;
    const elapsed = replyBreach.elapsed;
    const remaining = target - elapsed;
    if (remaining > 0 && remaining <= WARN_MINUTES) {
      warnings.push({
        ticketId,
        metric: 'First Reply Time',
        remainingMinutes: remaining,
        target,
      });
    }
  }
 
  // Check resolution time SLA
  const resolutionBreach = m.full_resolution_time_in_minutes?.business;
  if (resolutionBreach && !resolutionBreach.is_completed) {
    const target = resolutionBreach.target;
    const elapsed = resolutionBreach.elapsed;
    const remaining = target - elapsed;
    if (remaining > 0 && remaining <= WARN_MINUTES) {
      warnings.push({
        ticketId,
        metric: 'Resolution Time',
        remainingMinutes: remaining,
        target,
      });
    }
  }
}
 
if (warnings.length === 0) return [];
return warnings.map(w => ({ json: w }));

This node outputs only the tickets that are within 60 minutes of breaching their SLA. If no tickets are at risk, the workflow stops here.

Adjust WARN_MINUTES to match your team's needs

60 minutes works for most teams, but high-priority tickets with tight SLAs might need 120 minutes of lead time. You can also make this dynamic — check the ticket priority and use a longer threshold for urgent tickets.

Step 6: Enrich with ticket details

Add another HTTP Request node to fetch the full ticket details for each warning (subject, requester, assignee):

  • Method: GET
  • URL: https://{'{'}your-subdomain{'}'}.zendesk.com/api/v2/tickets/{'{'}$json.ticketId{'}'}.json
  • Authentication: Predefined Credential Type → Zendesk API

Merge the ticket subject, assignee name, and priority into the warning object using a Set node or a short Code node.

Step 7: Send Slack Block Kit alerts

Add an HTTP Request node to post the Slack message:

  • Method: POST
  • URL: https://slack.com/api/chat.postMessage
  • Authentication: Header Auth
  • Header Name: Authorization
  • Header Value: Bearer YOUR_SLACK_BOT_TOKEN
  • Body Content Type: JSON
  • Body:
{
  "channel": "SLA_CHANNEL_ID",
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "SLA Breach Warning"
      }
    },
    {
      "type": "section",
      "fields": [
        {"type": "mrkdwn", "text": "*Ticket:* #{{ $json.ticketId }}"},
        {"type": "mrkdwn", "text": "*Subject:* {{ $json.subject }}"},
        {"type": "mrkdwn", "text": "*SLA Metric:* {{ $json.metric }}"},
        {"type": "mrkdwn", "text": "*Time Remaining:* {{ $json.remainingMinutes }} min"}
      ]
    },
    {
      "type": "section",
      "fields": [
        {"type": "mrkdwn", "text": "*Assignee:* {{ $json.assignee }}"},
        {"type": "mrkdwn", "text": "*Priority:* {{ $json.priority }}"}
      ]
    },
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
          "text": {"type": "plain_text", "text": "View Ticket"},
          "url": "https://{{ $json.subdomain }}.zendesk.com/agent/tickets/{{ $json.ticketId }}",
          "style": "danger"
        }
      ]
    }
  ]
}

Replace SLA_CHANNEL_ID with your Slack channel ID and YOUR_SLACK_BOT_TOKEN with your bot token (or use n8n credentials).

Step 8: Activate and test

  1. Set a temporary SLA policy with a short target (e.g., 15-minute first reply) for testing
  2. Create a test ticket and leave it unanswered
  3. Run the workflow manually and verify the Slack alert appears
  4. Check that the Block Kit message renders correctly with the ticket link, time remaining, and assignee
  5. Toggle the workflow to Active
Test with a short SLA target

Create a test SLA policy with a 15-minute first reply target and assign it to a test ticket via a trigger condition (e.g., tag "sla-test"). This lets you see the full warning flow in minutes instead of waiting hours.

Rate limits with large ticket volumes

This workflow makes one API call per ticket to fetch metrics. If you have 500+ open tickets, this can approach Zendesk's rate limit of roughly 700 requests per minute. For large volumes, batch the ticket IDs and use the GET /api/v2/ticket_metrics/show_many endpoint to fetch metrics in bulk instead of one by one.

Cost

  • n8n Cloud Starter: $0-24/mo depending on execution volume. Each run triggers ~3 node executions per ticket (search + metrics + Slack). 50 open tickets checked every 15 minutes = roughly 9,000 executions/month.
  • n8n self-hosted: Free. You provide the infrastructure.
  • Zendesk API: Included in your plan. Rate limits apply but are generous for typical ticket volumes.
  • Slack API: Free for posting messages.

Need help implementing this?

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