skills/freshdesk-api/SKILL.md
Expert in Freshdesk helpdesk API for building integrations, extracting support data, managing tickets/contacts/companies, and automating support workflows. Use when working with Freshdesk, building helpdesk integrations, analyzing support ticket data, or creating customer support applications.
npx skillsauth add ckorhonen/claude-skills freshdesk-apiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build integrations with Freshdesk's helpdesk platform using their REST API v2. Manage support tickets, contacts, companies, agents, and automate workflows. The API supports full CRUD operations on all major resources with filtering, pagination, and embedded data.
# Set environment variable
export FRESHDESK_API_KEY="your-api-key-here"
export FRESHDESK_DOMAIN="yourcompany" # From yourcompany.freshdesk.com
curl for HTTP requestsjq for JSON parsing (brew install jq on macOS)https://{domain}.freshdesk.com/api/v2/
Replace {domain} with your Freshdesk subdomain (e.g., acme for acme.freshdesk.com).
Freshdesk uses HTTP Basic Authentication with your API key as the username and X as the password.
# Using -u flag (username:password)
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets"
# Using Authorization header
curl -H "Authorization: Basic $(echo -n "$FRESHDESK_API_KEY:X" | base64)" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets"
Always include:
Content-Type: application/json
curl -u "$FRESHDESK_API_KEY:X" \
-H "Content-Type: application/json" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets"
curl -u "$FRESHDESK_API_KEY:X" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"subject": "Support needed",
"description": "Details of the issue...",
"email": "[email protected]",
"priority": 2,
"status": 2
}' \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets"
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/contacts/12345"
# Search by status and priority
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/search/tickets?query=\"status:2 AND priority:3\""
| Endpoint | Description |
|----------|-------------|
| /tickets | Create, list, update, delete tickets |
| /contacts | Manage customer contacts |
| /companies | Manage company/organization records |
| /agents | View and manage support agents |
| /groups | Manage agent groups |
| /conversations | Ticket replies, notes, forwards |
| /time_entries | Time tracking on tickets |
| /surveys/satisfaction_ratings | Customer satisfaction data |
| /products | Product catalog management |
| /business_hours | Business hours configuration |
| /email_configs | Email settings |
| /sla_policies | SLA policy management |
| /canned_responses | Pre-defined response templates |
| /ticket_fields | Custom ticket fields |
See references/tickets-api.md for detailed ticket operations. See references/contacts-companies.md for contact/company management.
| Version | Limit | |---------|-------| | API v1 | 1000 calls/hour | | API v2 | Per-minute, plan-based | | Trial Plans | 50 calls/minute |
Every response includes:
| Header | Description |
|--------|-------------|
| X-Ratelimit-Total | Total calls allowed per minute |
| X-Ratelimit-Remaining | Calls remaining this minute |
| X-Ratelimit-Used-CurrentRequest | Credits used by this request |
#!/usr/bin/env bash
# Retry with exponential backoff for 429 errors
max_retries=3
retry_count=0
while [ "$retry_count" -lt "$max_retries" ]; do
response=$(curl -s -w "\n%{http_code}" -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets")
http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')
if [ "$http_code" = "200" ]; then
echo "$body"
exit 0
elif [ "$http_code" = "429" ]; then
delay=$((2 ** retry_count))
echo "Rate limited. Retrying in ${delay}s..." >&2
sleep "$delay"
retry_count=$((retry_count + 1))
else
echo "Error: HTTP $http_code" >&2
echo "$body" >&2
exit 1
fi
done
echo "Max retries exceeded" >&2
exit 1
Some operations consume multiple API credits:
include= parameter): +1 credit per include?include=requester,company costs 3 credits total| Parameter | Default | Max | Description |
|-----------|---------|-----|-------------|
| page | 1 | - | Page number (1-indexed) |
| per_page | 30 | 100 | Results per page |
page=1
while true; do
response=$(curl -s -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets?page=$page&per_page=100")
count=$(echo "$response" | jq length)
if [ "$count" -eq 0 ]; then
break
fi
echo "$response" | jq '.[] | {id, subject, status}'
page=$((page + 1))
done
Responses include a Link header for navigation:
Link: <https://domain.freshdesk.com/api/v2/tickets?page=2>; rel="next"
Common filters available on list endpoints:
| Parameter | Example | Description |
|-----------|---------|-------------|
| filter | new_and_my_open | Pre-defined filter |
| requester_id | 12345 | Filter by requester |
| company_id | 67890 | Filter by company |
| updated_since | 2024-01-01T00:00:00Z | Modified after date |
# New and open tickets assigned to me
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets?filter=new_and_my_open"
# All unresolved tickets
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets?filter=all_unresolved"
# Tickets updated in last 30 days
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets?updated_since=2024-11-01T00:00:00Z"
Embed related objects to reduce API calls:
# Include requester and company with ticket
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets/123?include=requester,company"
# Include stats with ticket list
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets?include=stats"
Available includes for tickets: requester, company, stats, conversations, description
The Search API enables complex queries across tickets, contacts, and companies.
curl -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/search/tickets?query=\"<query>\""
# Tickets with specific status and priority
"status:2 AND priority:3"
# Tickets from a specific requester
"requester_email:'[email protected]'"
# Tickets created in date range
"created_at:>'2024-01-01' AND created_at:<'2024-02-01'"
# Tickets with specific tag
"tag:'urgent'"
# Tickets assigned to specific agent
"agent_id:12345"
# Full-text search in subject and description
"~'password reset'"
| Operator | Description |
|----------|-------------|
| AND | Both conditions must match |
| OR | Either condition matches |
| : | Equals |
| :> | Greater than |
| :< | Less than |
| ~ | Full-text search |
| Value | Status | |-------|--------| | 2 | Open | | 3 | Pending | | 4 | Resolved | | 5 | Closed |
| Value | Priority | |-------|----------| | 1 | Low | | 2 | Medium | | 3 | High | | 4 | Urgent |
| Value | Source | |-------|--------| | 1 | Email | | 2 | Portal | | 3 | Phone | | 7 | Chat | | 8 | Mobihelp | | 9 | Feedback Widget | | 10 | Outbound Email |
| Code | Meaning | Action | |------|---------|--------| | 200 | Success | Process response | | 201 | Created | Resource created successfully | | 204 | No Content | Delete successful | | 400 | Bad Request | Check request body/params | | 401 | Unauthorized | Verify API key | | 403 | Forbidden | Check permissions | | 404 | Not Found | Verify resource ID | | 409 | Conflict | Resource already exists | | 429 | Rate Limited | Wait and retry | | 500 | Server Error | Retry with backoff |
{
"description": "Validation failed",
"errors": [
{
"field": "email",
"message": "It should be a valid email address.",
"code": "invalid_value"
}
]
}
Freshdesk can send webhook notifications on ticket events. Configure webhooks in Admin → Automations → Webhooks.
{
"freshdesk_webhook": {
"ticket_id": 12345,
"ticket_subject": "Support needed",
"ticket_status": "Open",
"ticket_priority": "Medium",
"ticket_requester_email": "[email protected]",
"triggered_event": "ticket_created"
}
}
See references/webhooks-automation.md for detailed webhook setup.
include parameter - Reduce API calls by embedding dataper_page=100 for bulk operationsYYYY-MM-DDTHH:MM:SSZ| Language | Package | Install |
|----------|---------|---------|
| Python | python-freshdesk | pip install python-freshdesk |
| Node.js | node-freshdesk-api | npm install node-freshdesk-api |
| Ruby | freshdesk-ruby | gem install freshdesk |
| PHP | Official samples | See Freshdesk docs |
| Java | Official samples | See Freshdesk docs |
See references/sdk-examples.md for detailed code examples.
#!/usr/bin/env bash
# Export all tickets to tickets.json
page=1
echo "[" > tickets.json
first=true
while true; do
response=$(curl -s -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/tickets?page=$page&per_page=100&include=description")
count=$(echo "$response" | jq length)
[ "$count" -eq 0 ] && break
if [ "$first" = true ]; then
first=false
else
echo "," >> tickets.json
fi
echo "$response" | jq '.[]' | paste -sd ',' - >> tickets.json
page=$((page + 1))
sleep 0.5 # Respect rate limits
done
echo "]" >> tickets.json
echo "Exported $((page - 1)) pages of tickets"
#!/usr/bin/env bash
# Import contacts from contacts.csv (name,email,company_id)
while IFS=, read -r name email company_id; do
curl -s -u "$FRESHDESK_API_KEY:X" \
-H "Content-Type: application/json" \
-X POST \
-d "{\"name\":\"$name\",\"email\":\"$email\",\"company_id\":$company_id}" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/contacts"
sleep 0.5
done < contacts.csv
# Get resolution time stats for closed tickets this month
curl -s -u "$FRESHDESK_API_KEY:X" \
"https://$FRESHDESK_DOMAIN.freshdesk.com/api/v2/search/tickets?query=\"status:5 AND created_at:>'2024-12-01'\"" \
| jq '[.results[] | .stats.resolved_at as $r | .created_at as $c |
(($r | fromdateiso8601) - ($c | fromdateiso8601)) / 3600] |
{count: length, avg_hours: (add / length)}'
For detailed endpoint documentation:
documentation
Create or expand an Idea.md / IDEA.md file from a rough description, existing repo, conversation history, notes, or other early-stage product inputs. Use when the user asks to "write an Idea.md", "turn this into an idea file", "capture this product idea", "expand this concept", or wants a repo-grounded concept brief before validation, PRD, or implementation work.
development
Write structured implementation plans from specs or requirements before touching code. Use when given a spec, requirements doc, or feature description, when user says "plan this out", "write a plan for", "how should we implement", or before starting any multi-step coding task.
testing
Expert guidance for video editing with ffmpeg, encoding best practices, and quality optimization. Use when working with video files, transcoding, remuxing, encoding settings, color spaces, or troubleshooting video quality issues.
development
Opinionated constraints for building better interfaces with agents. Use when building UI components, implementing animations, designing layouts, reviewing frontend accessibility, or working with Tailwind CSS, motion/react, or accessible primitives like Radix/Base UI.