Audit VIP Zendesk tickets using a Claude Code skill
Install this skill
Download the skill archive and extract it into your .claude/skills/ directory.
vip-audit.skill.zipPrerequisites
This skill works with any agent that supports the Claude Code skills standard, including Claude Code, Claude Cowork, OpenAI Codex, and Google Antigravity.
- One of the agents listed above
- Zendesk account with API access enabled
- VIP customers organized into Zendesk Organizations with a "vip" tag
- Slack bot with
chat:writepermission, added to the target channel
Why a Claude Code skill?
The other approaches in this guide handle real-time VIP detection — triggers fire when a ticket is created. An Claude Code skill serves a different purpose: it's a safety net that audits recent tickets and catches any VIP tickets that slipped through.
That means you can say:
- "Audit recent tickets for missed VIP flags"
- "Which VIP organizations have open tickets right now?"
- "Post a summary of VIP ticket volume this week to #cx-leadership"
The skill contains workflow guidelines, API reference materials, and a message template that the agent reads on demand. When you invoke the skill, Claude reads these files, writes a script on the fly, runs it, and reports results. If you ask for something different next time — filtering by VIP tier, checking a specific organization, generating a VIP queue report — the agent adapts without you touching any code.
How it works
The skill directory has three parts:
SKILL.md— workflow guidelines telling the agent what steps to follow, which env vars to use, and what pitfalls to avoidreferences/— Zendesk API patterns (organizations, search, ticket update) so the agent calls the right APIs with the right parameterstemplates/— a Slack Block Kit template so alert messages are consistently formatted across runs
When invoked, the agent reads SKILL.md, consults the reference and template files as needed, writes a Python script, executes it, and reports what it found. The reference files act as guardrails — the agent knows exactly which endpoints to hit and what the responses look like, so it doesn't have to guess.
What is a Claude Code skill?
An Claude Code skill is a reusable command you add to your project that Claude Code can run on demand. Skills live in a .claude/skills/ directory and are defined by a SKILL.md file that tells the agent what the skill does, when to run it, and what tools it's allowed to use.
In this skill, the agent doesn't run a pre-written script. Instead, SKILL.md provides workflow guidelines and points to reference files — API documentation, message templates — that the agent reads to generate and execute code itself. This is the key difference from a traditional script: the agent can adapt its approach based on what you ask for while still using the right APIs and message formats.
Once installed, you can invoke a skill as a slash command (e.g., /zendesk-vip-audit), or the agent will use it automatically when you give it a task where the skill is relevant. Skills are portable — anyone who clones your repo gets the same commands.
Step 1: Create the skill directory
mkdir -p .claude/skills/zendesk-vip-audit/{templates,references}This creates the layout:
.claude/skills/zendesk-vip-audit/
├── SKILL.md # workflow guidelines + config
├── templates/
│ └── slack-alert.md # Block Kit template for VIP alerts
└── references/
└── zendesk-orgs-api.md # Zendesk organizations and tickets API patternsStep 2: Write the SKILL.md
Create .claude/skills/zendesk-vip-audit/SKILL.md:
---
name: zendesk-vip-audit
description: Audit recent Zendesk tickets for missed VIP flags and post alerts to Slack
disable-model-invocation: true
allowed-tools: Bash, Read
---
## Goal
Find open Zendesk tickets from VIP organizations that were not tagged as VIP. For each missed ticket, add the `vip` tag, set priority to Urgent, optionally assign to the VIP Support group, and post a Slack alert.
## Configuration
Read these environment variables:
- `ZENDESK_SUBDOMAIN` — Zendesk subdomain, e.g. "acme" for acme.zendesk.com (required)
- `ZENDESK_EMAIL` — Zendesk agent email for API auth (required)
- `ZENDESK_API_TOKEN` — Zendesk API token (required)
- `SLACK_BOT_TOKEN` — Slack bot token starting with xoxb- (required)
- `SLACK_CHANNEL_ID` — Slack channel ID starting with C (required)
## Workflow
1. Validate that all required env vars are set. If any are missing, print which ones and exit.
2. Fetch all organizations and filter to those tagged with "vip" to build a set of VIP org IDs. See `references/zendesk-orgs-api.md`.
3. Fetch groups to get the VIP Support group ID. See `references/zendesk-orgs-api.md`.
4. Search for open/pending tickets that do NOT have the `vip` tag. See `references/zendesk-orgs-api.md`.
5. For each ticket, check if its `organization_id` matches a VIP org. If yes:
a. Update the ticket: add `vip` tag (merged with existing tags), set priority to `urgent`, optionally set `group_id` to VIP Support.
b. Post a Slack alert using the format in `templates/slack-alert.md`.
6. Print a summary of how many missed VIP tickets were found and flagged.
## Important notes
- VIP status is determined by organization tags, not ticket tags. Check the ticket's `organization_id` against VIP org IDs.
- The Zendesk PUT endpoint replaces the entire tags array. Merge existing tags with the new `vip` tag before updating.
- Authentication uses Basic Auth with `email/token:api_token` format. The `/token` suffix after the email is required.
- `SLACK_CHANNEL_ID` must be the channel ID (starts with `C`), not the channel name.
- The Slack bot must be invited to the target channel or `chat.postMessage` will fail with `not_in_channel`.
- Use only Python standard library (`urllib.request`, `json`, `base64`) — no pip dependencies needed.
- This skill is a safety net behind the Zendesk trigger. It catches tickets that slipped through, not a replacement for real-time escalation.Understanding the SKILL.md
| Section | Purpose |
|---|---|
| Goal | Tells the agent what outcome to produce |
| Configuration | Which env vars to read and what defaults to use |
| Workflow | Numbered steps with pointers to reference files |
| Important notes | Non-obvious context that prevents common mistakes |
The allowed-tools: Bash, Read setting lets the agent both read reference files and execute code. The agent writes its own script based on the workflow steps and reference materials.
Step 3: Add reference files
references/zendesk-orgs-api.md
Create .claude/skills/zendesk-vip-audit/references/zendesk-orgs-api.md:
# Zendesk Organizations & Tickets API Reference
## Authentication
All Zendesk API requests use Basic Auth. The username is `email/token:api_token` (note the `/token` suffix).
```
Authorization: Basic base64(email/token:api_token)
```
Base URL: `https://{subdomain}.zendesk.com/api/v2`
## List organizations
Fetch all organizations to find VIP-tagged ones.
**Request:**
```
GET https://{subdomain}.zendesk.com/api/v2/organizations.json?per_page=100
Authorization: Basic <credentials>
```
**Response shape:**
```json
{
"organizations": [
{
"id": 12345,
"name": "Acme Corp",
"tags": ["vip", "enterprise"]
},
{
"id": 67890,
"name": "Small Co",
"tags": []
}
],
"next_page": null
}
```
Filter to organizations where `"vip"` is in the `tags` array to build a set of VIP org IDs.
Note: Paginate using `next_page` if you have more than 100 organizations.
## Search for untagged open tickets
Find tickets that don't have the `vip` tag.
**Request:**
```
GET https://{subdomain}.zendesk.com/api/v2/search.json?query=type:ticket status:open status:pending -tags:vip&per_page=100
Authorization: Basic <credentials>
```
**Response shape:**
```json
{
"results": [
{
"id": 48291,
"subject": "SSO login broken for our team",
"organization_id": 12345,
"tags": ["technical"],
"status": "open",
"priority": "normal"
}
],
"count": 47
}
```
The `organization_id` field links to the ticket requester's organization. Check this against VIP org IDs.
## Update a ticket
**Request:**
```
PUT https://{subdomain}.zendesk.com/api/v2/tickets/{ticket_id}.json
Authorization: Basic <credentials>
Content-Type: application/json
```
**Body:**
```json
{
"ticket": {
"tags": ["existing-tag", "vip"],
"priority": "urgent",
"group_id": 12345
}
}
```
Important: `tags` replaces the entire array. Merge existing tags with the new `vip` tag.
## List groups
```
GET https://{subdomain}.zendesk.com/api/v2/groups.json
```
Response: `{"groups": [{"id": 12345, "name": "VIP Support"}]}`
## Rate limits
~700 requests/minute on Professional plans. This audit uses 1 orgs call + 1 groups call + 1 search call + 1 PUT per flagged ticket.templates/slack-alert.md
Create .claude/skills/zendesk-vip-audit/templates/slack-alert.md:
# Slack VIP Alert Template
Use this Block Kit structure for each missed VIP ticket alert.
## Block Kit JSON
```json
{
"channel": "<SLACK_CHANNEL_ID>",
"text": "Missed VIP ticket #<ticket_id>: <subject>",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Missed VIP Ticket Flagged",
"emoji": true
}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Ticket:* <ticket_url|#ticket_id>"},
{"type": "mrkdwn", "text": "*Subject:* <subject>"},
{"type": "mrkdwn", "text": "*Organization:* <org_name>"},
{"type": "mrkdwn", "text": "*Priority:* Urgent (escalated)"}
]
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "This ticket was from a VIP org but wasn't tagged. It's been flagged and escalated."
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {"type": "plain_text", "text": "View in Zendesk"},
"url": "<ticket_url>",
"style": "danger"
}
]
}
]
}
```
## Notes
- The top-level `text` field is required by the Slack API as a fallback.
- Ticket URL format: `https://{subdomain}.zendesk.com/agent/tickets/{ticket_id}`
- Use the `danger` button style to visually signal that this ticket was missed.
- Include the organization name so agents know which VIP account is affected.Step 4: Test the skill
Invoke the skill conversationally:
/zendesk-vip-auditClaude will read the SKILL.md, check the reference files, write a script, run it, and report the results. A typical run looks like:
Loading VIP organizations...
Found 12 VIP organization(s)
Checking 47 untagged tickets...
#98234 "Cannot access billing portal" → flagged as VIP (Acme Corp)
#98251 "API rate limit question" → flagged as VIP (Widget Inc)
Flagged 2 missed VIP ticket(s) out of 47 checked.Because the agent generates code on the fly, you can also make ad hoc requests:
- "Which VIP organizations have open tickets right now?" — the agent generates a report
- "Audit tickets from the last 24 hours only" — the agent adjusts the search query
- "Post a VIP ticket volume summary to #cx-leadership" — the agent adapts the output format
The trigger handles instant escalation for properly tagged VIP organizations. This skill catches tickets that slipped through — usually because an organization's VIP tag was added after the ticket was already created, or because the trigger conditions didn't match. Run both for full coverage.
Step 5: Schedule it (optional)
Option A: Cron + Claude CLI
# Run every hour during business hours
0 8-18 * * 1-5 cd /path/to/your/project && claude -p "Run /zendesk-vip-audit" --allowedTools 'Bash(*)' 'Read(*)'Option B: GitHub Actions + Claude
name: VIP Audit
on:
schedule:
- cron: '0 13-22 * * 1-5' # 8 AM-5 PM ET, hourly
workflow_dispatch: {} # Manual trigger for testing
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
prompt: "Run /zendesk-vip-audit"
allowed_tools: "Bash(*),Read(*)"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
ZENDESK_SUBDOMAIN: ${{ secrets.ZENDESK_SUBDOMAIN }}
ZENDESK_EMAIL: ${{ secrets.ZENDESK_EMAIL }}
ZENDESK_API_TOKEN: ${{ secrets.ZENDESK_API_TOKEN }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}Option C: Cowork Scheduled Tasks
Claude Desktop's Cowork supports built-in scheduled tasks. Open a Cowork session, type /schedule, and configure the cadence — hourly, daily, weekly, or weekdays only. Each scheduled run has full access to your connected tools, plugins, and MCP servers.
Scheduled tasks only run while your computer is awake and Claude Desktop is open. If a run is missed, Cowork executes it automatically when the app reopens. For always-on scheduling, use GitHub Actions (Option B) instead. Available on all paid plans (Pro, Max, Team, Enterprise).
The Zendesk trigger handles instant escalation when VIP organizations are properly tagged. This audit skill catches tickets that slip through — usually because an organization's VIP tag was added after the ticket was already created, or because the trigger conditions didn't match. Run both for full coverage.
Troubleshooting
When to use this approach
- You want a safety net behind the Zendesk trigger to catch missed VIP tickets
- You want on-demand VIP queue reviews — "which VIP orgs have open tickets right now?"
- You're already using Claude Code and want skills that integrate with your workflow
- You want to run tasks in the background via Claude Cowork while focusing on other work
- You want conversational flexibility — audit specific time windows, filter by tier, or generate reports
When to switch approaches
- You need instant VIP escalation (under 1 second) → use Zendesk native triggers
- You want rich Slack messages with CRM data on every VIP ticket → use n8n
- You want zero-cost, zero-code VIP routing → use Zendesk native triggers
Common questions
Why not just rely on the Zendesk trigger?
The trigger handles 95%+ of cases. But tickets slip through when: (1) an organization's VIP tag is added after a ticket was already created, (2) a VIP customer submits from an unlinked email, or (3) the trigger conditions don't match edge cases. This skill catches the remaining 5%.
Does this use Claude API credits?
Yes. The agent reads skill files and generates code each time. Typical cost is $0.01-0.05 per invocation. The Zendesk and Slack APIs themselves are free.
Can I detect VIP status by criteria other than org tags?
Yes. Ask the agent to check organization custom fields, user tags, or even domain matching. The skill's reference files document the available API endpoints, and the agent adapts its approach based on what you ask for.
Cost
- Claude API — $0.01-0.05 per invocation (the agent reads files and generates code)
- Zendesk API — included in your plan, no per-call cost
- Slack API — included in all plans, no per-call cost
- GitHub Actions (if scheduled) — free tier includes 2,000 minutes/month
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.