Claude Code Plugins

Community-maintained marketplace

Feedback

Zendesk Support REST API for managing tickets, users, organizations, and support operations. Use this skill to create tickets, manage users, search, and automate customer support workflows.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name zendesk
description Zendesk Support REST API for managing tickets, users, organizations, and support operations. Use this skill to create tickets, manage users, search, and automate customer support workflows.
vm0_secrets ZENDESK_API_TOKEN
vm0_vars ZENDESK_EMAIL, ZENDESK_SUBDOMAIN

Zendesk API

Manage customer support tickets, users, organizations, and support operations via the Zendesk Support REST API.

Official docs: https://developer.zendesk.com/api-reference/


When to Use

Use this skill when you need to:

  • Manage tickets - Create, update, search, and close support tickets
  • Handle users - Create end-users, agents, and manage user profiles
  • Organize accounts - Manage organizations and their members
  • Support groups - Create and manage agent groups for ticket routing
  • Search data - Find tickets, users, and organizations with powerful search
  • Bulk operations - Create or update multiple resources at once
  • Automate support - Build integrations and automate workflows
  • Track metrics - Access ticket data for reporting and analytics

Prerequisites

Getting Your API Token

⚠️ Important: You must enable Token Access before creating tokens.

  1. Log in to Zendesk Admin Center (admin access required)
  2. Navigate to Apps and integrationsAPIsZendesk API
  3. Click the Settings tab
  4. Under Token Access, toggle Enabled (this is required!)
  5. Click Add API token
  6. Enter a description (e.g., "VM0 Integration")
  7. Click Save and copy the token immediately (shown only once)
export ZENDESK_EMAIL="your-email@company.com"
export ZENDESK_API_TOKEN="your_api_token"
export ZENDESK_SUBDOMAIN="yourcompany"

Find Your Subdomain

Your subdomain is in your Zendesk URL:

https://yourcompany.zendesk.com
         ^^^^^^^^^^^
         subdomain

Verify Token

Test your credentials:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq '{count: .count, tickets: .tickets | length}

Expected response: Ticket count and list

Alternative verification (list users):

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq '.users[] | {id, name, email, role}

Note: The /users/me.json endpoint may return anonymous user for API token authentication. Use /tickets.json or /users.json to verify token validity.

✅ This skill has been tested and verified with a live Zendesk workspace. All core endpoints work correctly.


Important: When using $VAR in a command that pipes to another command, wrap the command containing $VAR in bash -c '...'. Due to a Claude Code bug, environment variables are silently cleared when pipes are used directly.

bash -c 'curl -s "https://api.example.com" -H "Authorization: Bearer $API_KEY"' | jq .

How to Use

All examples assume environment variables are set.

Base URL: https://{subdomain}.zendesk.com/api/v2/

Authentication: API Token via -u flag

-u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"

Note: The -u flag automatically handles Base64 encoding for you.


Core APIs

1. List Tickets

Get all tickets (paginated):

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq '.tickets[] | {id, subject, status, priority}

With pagination:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json?page=1&per_page=50" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq .

2. Get Ticket

Retrieve a specific ticket:

TICKET_ID="123"

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/${TICKET_ID}.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq .

3. Create Ticket

Create a new support ticket:

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "subject": "My printer is on fire!",
    "comment": {
      "body": "The smoke is very colorful."
    },
    "priority": "urgent"
  }
}

Then run:

bash -c 'curl -s -X POST "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

Create ticket with more details:

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "subject": "Need help with account",
    "comment": {
      "body": "I cannot access my account settings."
    },
    "priority": "high",
    "status": "open",
    "type": "problem",
    "tags": ["account", "access"]
  }
}

Then run:

bash -c 'curl -s -X POST "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

4. Update Ticket

Update an existing ticket:

TICKET_ID="123"

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "status": "solved",
    "comment": {
      "body": "Issue has been resolved. Thank you!",
      "public": true
    }
  }
}

Then run:

bash -c 'curl -s -X PUT "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/${TICKET_ID}.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

Change priority and assignee:

TICKET_ID="123"
ASSIGNEE_ID="456"

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "priority": "high",
    "assignee_id": ASSIGNEE_ID_PLACEHOLDER
  }
}

Then run:

sed -i '' "s/ASSIGNEE_ID_PLACEHOLDER/${ASSIGNEE_ID}/" /tmp/zendesk_request.json

bash -c 'curl -s -X PUT "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/${TICKET_ID}.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

5. Delete Ticket

Permanently delete a ticket:

TICKET_ID="123"

curl -s -X DELETE "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/${TICKET_ID}.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"

6. Create Multiple Tickets

Bulk create tickets:

Write to /tmp/zendesk_request.json:

{
  "tickets": [
    {
      "subject": "Ticket 1",
      "comment": {
        "body": "First ticket"
      }
    },
    {
      "subject": "Ticket 2",
      "comment": {
        "body": "Second ticket"
      }
    }
  ]
}

Then run:

bash -c 'curl -s -X POST "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/create_many.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

7. List Users

Get all users:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq '.users[] | {id, name, email, role}

8. Get Current User

Get authenticated user details:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users/me.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq .

9. Create User

Create an end-user:

Write to /tmp/zendesk_request.json:

{
  "user": {
    "name": "John Customer",
    "email": "john@example.com",
    "role": "end-user"
  }
}

Then run:

bash -c 'curl -s -X POST "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

Create an agent:

Write to /tmp/zendesk_request.json:

{
  "user": {
    "name": "Jane Agent",
    "email": "jane@company.com",
    "role": "agent"
  }
}

Then run:

bash -c 'curl -s -X POST "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

10. Update User

Update user information:

USER_ID="456"

Write to /tmp/zendesk_request.json:

{
  "user": {
    "name": "Updated Name",
    "phone": "+1234567890"
  }
}

Then run:

bash -c 'curl -s -X PUT "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users/${USER_ID}.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

11. Search Users

Search for users by query:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users/search.json?query=john" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq '.users[] | {id, name, email}

12. List Organizations

Get all organizations:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/organizations.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq '.organizations[] | {id, name, domain_names}

13. Create Organization

Create a new organization:

Write to /tmp/zendesk_request.json:

{
  "organization": {
    "name": "Acme Inc",
    "domain_names": ["acme.com", "acmeinc.com"],
    "details": "Important customer"
  }
}

Then run:

bash -c 'curl -s -X POST "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/organizations.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

14. Update Organization

Update organization details:

ORG_ID="789"

Write to /tmp/zendesk_request.json:

{
  "organization": {
    "name": "Acme Corporation",
    "notes": "Premium customer since 2020"
  }
}

Then run:

bash -c 'curl -s -X PUT "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/organizations/${ORG_ID}.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

15. List Groups

Get all agent groups:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/groups.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq '.groups[] | {id, name}

16. Create Group

Create a new agent group:

Write to /tmp/zendesk_request.json:

{
  "group": {
    "name": "Support Team"
  }
}

Then run:

bash -c 'curl -s -X POST "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/groups.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

17. Search API

Search for open tickets:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/search.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -G --data-urlencode "query=type:ticket status:open"' | jq '.results[] | {id, subject, status}

Search for high priority tickets:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/search.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -G --data-urlencode "query=type:ticket priority:high"' | jq '.results[]

Search tickets with keywords:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/search.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -G --data-urlencode "query=type:ticket urgent issue"' | jq '.results[]

Search users by email domain:

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/search.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -G --data-urlencode "query=type:user email:*@acme.com"' | jq '.results[]

18. Get Ticket Comments

List all comments on a ticket:

TICKET_ID="123"

bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/${TICKET_ID}/comments.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}"' | jq '.comments[] | {id, body, author_id, public}

19. Assign Ticket to Group

Assign a ticket to a group:

TICKET_ID="123"
GROUP_ID="456"

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "group_id": GROUP_ID_PLACEHOLDER
  }
}

Then run:

sed -i '' "s/GROUP_ID_PLACEHOLDER/${GROUP_ID}/" /tmp/zendesk_request.json

bash -c 'curl -s -X PUT "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/${TICKET_ID}.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

20. Bulk Update Tickets

Update multiple tickets at once:

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "status": "solved"
  }
}

Then run:

bash -c 'curl -s -X PUT "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/update_many.json?ids=123,124,125" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json' | jq .

Common Workflows

Create Ticket and Assign to Agent

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "subject": "New issue",
    "comment": {
      "body": "Need help"
    }
  }
}

Then run:

# Create ticket
TICKET_RESPONSE=$(curl -s -X POST "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json)

TICKET_ID=$(echo $TICKET_RESPONSE | jq -r '.ticket.id')

# Assign to agent
ASSIGNEE_ID="789"

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "assignee_id": ASSIGNEE_ID_PLACEHOLDER,
    "status": "open"
  }
}

Then run:

sed -i '' "s/ASSIGNEE_ID_PLACEHOLDER/${ASSIGNEE_ID}/" /tmp/zendesk_request.json

curl -s -X PUT "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/${TICKET_ID}.json" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json

Find and Close Old Tickets

# Search for old open tickets (30+ days)
OLD_TICKETS="$(bash -c 'curl -s "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/search.json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -G --data-urlencode "query=type:ticket status:open created<30"' | jq -r '.results[].id' | paste -sd "," -)"

Write to /tmp/zendesk_request.json:

{
  "ticket": {
    "status": "closed"
  }
}

Then run:

# Bulk close them
curl -s -X PUT "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/update_many.json?ids=${OLD_TICKETS}" -H "Content-Type: application/json" -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" -d @/tmp/zendesk_request.json

Search Query Syntax

Ticket Search Operators

  • type:ticket - Search tickets only
  • status:open - Filter by status (open, pending, solved, closed)
  • priority:high - Filter by priority (low, normal, high, urgent)
  • assignee:name - Find tickets assigned to specific agent
  • group:name - Find tickets in specific group
  • tags:keyword - Search by tag
  • created>2024-01-01 - Created after date
  • created<30 - Created in last 30 days
  • "exact phrase" - Search exact text

User Search Operators

  • type:user - Search users only
  • role:agent - Filter by role (end-user, agent, admin)
  • email:*@domain.com - Search by email domain
  • name:john - Search by name

Combining Operators

Use spaces for AND logic:

query=type:ticket status:open priority:high

Rate Limits

Plan Requests/Minute
Team 200
Growth 400
Professional 400
Enterprise 700
Enterprise Plus 2,500

Special Limits:

  • Update Ticket: 30 updates per 10 minutes per user per ticket
  • Account-wide ceiling: 100,000 requests/minute

Rate Limit Headers

X-Rate-Limit: 700                    # Your account's limit
X-Rate-Limit-Remaining: 685          # Requests remaining
Retry-After: 45                      # Seconds to wait if exceeded

Handling Rate Limits

# Use curl retry flags
curl "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json" \
  -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" \
  --retry 3 --retry-delay 5

Guidelines

  1. Enable API token access first: In Admin Center, ensure Token Access is enabled before using tokens
  2. Always use HTTPS: TLS 1.2+ required
  3. Monitor rate limits: Check X-Rate-Limit-Remaining header
  4. Use bulk operations: create_many, update_many endpoints save API calls
  5. Implement exponential backoff: Honor Retry-After header on 429 responses
  6. Paginate large datasets: Default limit is 100, max per_page is 100
  7. Secure your tokens: Store in environment variables, never in code
  8. Use specific searches: Narrow queries with filters to reduce response size
  9. Verify with reliable endpoints: Use /tickets.json or /users.json to test tokens (not /users/me.json)
  10. Status values: open, pending, hold, solved, closed
  11. Priority values: low, normal, high, urgent
  12. User roles: end-user, agent, admin (need agent or admin role for API access)
  13. Ticket types: problem, incident, question, task
  14. Authentication format: email/token:api_token (curl -u handles encoding)
  15. New workspaces: Fresh Zendesk accounts come with sample tickets for testing

API Reference