Agent skill
zendesk
Zendesk API for customer support. Use when user mentions "Zendesk", "support ticket", "customer service", or help desk.
Install this agent skill to your Project
npx add-skill https://github.com/vm0-ai/vm0-skills/tree/main/zendesk
SKILL.md
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.
- Log in to Zendesk Admin Center (admin access required)
- Navigate to Apps and integrations → APIs → Zendesk API
- Click the Settings tab
- Under Token Access, toggle Enabled (this is required!)
- Click Add API token
- Enter a description (e.g., "VM0 Integration")
- 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:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" | jq '{count: .count, tickets: .tickets | length}
Expected response: Ticket count and list
Alternative verification (list users):
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/users.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv 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.
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 "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)"
Note: The -u flag automatically handles Base64 encoding for you.
Core APIs
1. List Tickets
Get all tickets (paginated):
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" | jq '.tickets[] | {id, subject, status, priority}
With pagination:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets.json?page=1&per_page=50" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)"
2. Get Ticket
Retrieve a specific ticket:
TICKET_ID="123"
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/${TICKET_ID}.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)"
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:
curl -s -X POST "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
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:
curl -s -X POST "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
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:
curl -s -X PUT "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/${TICKET_ID}.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
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
curl -s -X PUT "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/${TICKET_ID}.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
5. Delete Ticket
Permanently delete a ticket:
TICKET_ID="123"
curl -s -X DELETE "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/${TICKET_ID}.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv 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:
curl -s -X POST "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/create_many.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
7. List Users
Get all users:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/users.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" | jq '.users[] | {id, name, email, role}
8. Get Current User
Get authenticated user details:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/users/me.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)"
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:
curl -s -X POST "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/users.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
Create an agent:
Write to /tmp/zendesk_request.json:
{
"user": {
"name": "Jane Agent",
"email": "jane@company.com",
"role": "agent"
}
}
Then run:
curl -s -X POST "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/users.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
10. Update User
Update user information:
USER_ID="456"
Write to /tmp/zendesk_request.json:
{
"user": {
"name": "Updated Name",
"phone": "+1234567890"
}
}
Then run:
curl -s -X PUT "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/users/${USER_ID}.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
11. Search Users
Search for users by query:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/users/search.json?query=john" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" | jq '.users[] | {id, name, email}
12. List Organizations
Get all organizations:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/organizations.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv 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:
curl -s -X POST "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/organizations.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
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:
curl -s -X PUT "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/organizations/${ORG_ID}.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
15. List Groups
Get all agent groups:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/groups.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv 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:
curl -s -X POST "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/groups.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
17. Search API
Search for open tickets:
Write to /tmp/zendesk_query.txt:
type:ticket status:open
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/search.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -G --data-urlencode "query@/tmp/zendesk_query.txt" | jq '.results[] | {id, subject, status}
Search for high priority tickets:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/search.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -G --data-urlencode "query@/tmp/zendesk_query.txt" | jq '.results[]
Search tickets with keywords:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/search.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -G --data-urlencode "query@/tmp/zendesk_query.txt" | jq '.results[]
Search users by email domain:
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/search.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -G --data-urlencode "query@/tmp/zendesk_query.txt" | jq '.results[]
18. Get Ticket Comments
List all comments on a ticket:
TICKET_ID="123"
curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/${TICKET_ID}/comments.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv 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
curl -s -X PUT "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/${TICKET_ID}.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
20. Bulk Update Tickets
Update multiple tickets at once:
Write to /tmp/zendesk_request.json:
{
"ticket": {
"status": "solved"
}
}
Then run:
curl -s -X PUT "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/update_many.json?ids=123,124,125" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
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://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv 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://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/${TICKET_ID}.json" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
Find and Close Old Tickets
# Search for old open tickets (30+ days)
OLD_TICKETS="$(curl -s "https://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/search.json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -G --data-urlencode "query@/tmp/zendesk_query.txt" | 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://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets/update_many.json?ids=${OLD_TICKETS}" -H "Content-Type: application/json" -u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" -d @/tmp/zendesk_request.json
Search Query Syntax
Ticket Search Operators
type:ticket- Search tickets onlystatus:open- Filter by status (open, pending, solved, closed)priority:high- Filter by priority (low, normal, high, urgent)assignee:name- Find tickets assigned to specific agentgroup:name- Find tickets in specific grouptags:keyword- Search by tagcreated>2024-01-01- Created after datecreated<30- Created in last 30 days"exact phrase"- Search exact text
User Search Operators
type:user- Search users onlyrole:agent- Filter by role (end-user, agent, admin)email:*@domain.com- Search by email domainname: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://$(printenv ZENDESK_SUBDOMAIN).zendesk.com/api/v2/tickets.json" \
-u "$(printenv ZENDESK_EMAIL)/token:$(printenv ZENDESK_API_TOKEN)" \
--retry 3 --retry-delay 5
Guidelines
- Enable API token access first: In Admin Center, ensure Token Access is enabled before using tokens
- Always use HTTPS: TLS 1.2+ required
- Monitor rate limits: Check
X-Rate-Limit-Remainingheader - Use bulk operations:
create_many,update_manyendpoints save API calls - Implement exponential backoff: Honor
Retry-Afterheader on 429 responses - Paginate large datasets: Default limit is 100, max per_page is 100
- Secure your tokens: Store in environment variables, never in code
- Use specific searches: Narrow queries with filters to reduce response size
- Verify with reliable endpoints: Use
/tickets.jsonor/users.jsonto test tokens (not/users/me.json) - Status values: open, pending, hold, solved, closed
- Priority values: low, normal, high, urgent
- User roles: end-user, agent, admin (need agent or admin role for API access)
- Ticket types: problem, incident, question, task
- Authentication format: email/token:api_token (curl -u handles encoding)
- New workspaces: Fresh Zendesk accounts come with sample tickets for testing
API Reference
- Main Documentation: https://developer.zendesk.com/api-reference/
- Tickets API: https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/
- Users API: https://developer.zendesk.com/api-reference/ticketing/users/users/
- Organizations API: https://developer.zendesk.com/api-reference/ticketing/organizations/organizations/
- Groups API: https://developer.zendesk.com/api-reference/ticketing/groups/groups/
- Search API: https://developer.zendesk.com/documentation/ticketing/using-the-zendesk-api/searching-with-the-zendesk-api/
- Rate Limits: https://developer.zendesk.com/api-reference/introduction/rate-limits/
- Authentication: https://developer.zendesk.com/api-reference/introduction/security-and-auth/
- Admin Center: https://www.zendesk.com/admin/
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
brave-search
Brave Search API for web search. Use when user says "search web", "Brave search", or asks to "find on web" without specifying Google.
supadata
Supadata API for YouTube/web data. Use when user mentions "Supadata", "YouTube data", "channel stats", or web scraping data.
roadmap-planning
Build and prioritize product roadmaps using scoring models like RICE, ICE, and value-effort matrices. Activate when creating a product roadmap, prioritizing features, sequencing initiatives, mapping dependencies, balancing team capacity, choosing between Now/Next/Later or quarterly planning, or communicating roadmap tradeoffs to executives and stakeholders.
qdrant
Qdrant API for vector search. Use when user mentions "Qdrant", "vector database", "semantic search", or embeddings storage.
calendly
Calendly scheduling API. Use when user mentions "Calendly", "calendly.com", "schedule a meeting", "booking link", "event types", or asks about interview scheduling.
stripe
Stripe API for payments. Use when user mentions "Stripe", "payment", "subscription", "billing", "invoice", or asks about payment processing.
Didn't find tool you were looking for?