Freshdesk Contacts & Companies
SkillSearchFreshdesk contacts and companies: contact fields and the required contact-channel rule, contact CRUD plus merge and make_agent, company fields and domain-based auto-association, search and autocomplete lookups, and the MSP workflow of resolving a ticket requester to a contact and then to its parent company through the Freshdesk REST API v2.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Freshdesk Contacts & Companies skill
What this skill tells your AI
The instructions your AI receives, as published by wyre-ai/msp-claude-plugins in msp-claude-plugins/freshdesk/freshdesk/skills/contacts-companies/SKILL.md and read by ahel’s review.
Overview
In Freshdesk, contacts are the people who raise tickets (requesters) and
companies group those contacts into the organizations an MSP serves.
Resolving a ticket's requester to a contact, and that contact to its company,
is the foundation for account-level context, SLA association, and reporting.
This skill covers contact and company operations through tools named
freshdesk_contacts_<action> and freshdesk_companies_<action>.
Anti-triggers
In Freshdesk a contact is a customer who raises tickets; an agent
is your own helpdesk staff. freshdesk_contacts_make_agent crosses that
line permanently — it consumes a licensed seat and grants access to every
ticket in the account, so it is not a labelling change.
- Technician rosters and team capacity — this skill only converts a
contact into an agent. For looking up who your technicians are and
which teams they sit in, the PSA carries the richer model; use
halopsa-agents. - The same customer in another system — a HaloPSA client, a
ConnectWise company, or an Autotask company is a different record with
different required fields; use
halopsa-clients,connectwise-psa-companies, orautotask-crm. Do not assume IDs or domains map across. - Assets, sites, or contracts belonging to the customer — Freshdesk
companies carry no CMDB or billing model; use
halopsa-assetsandhalopsa-contracts. - Anything about the customer's tickets — listing, replying, or
triaging is
freshdesk-ticketing; this skill resolves who the requester is.
Contacts
Key Contact Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | Integer | System | Auto-generated unique identifier |
name | String | Yes | Full name |
email | String | One of email/phone/mobile | Primary email |
phone | String | One of email/phone/mobile | Landline |
mobile | String | One of email/phone/mobile | Mobile number |
company_id | Integer | No | Associated company |
job_title | String | No | Role at the company |
tags | Array | No | Free-form labels |
A contact must have at least one of email, phone, mobile, twitter_id,
or unique_external_id.
Contact Operations
| Action | Endpoint | Notes |
|---|---|---|
| List | GET /api/v2/contacts | Filter with email, mobile, phone, company_id, updated_since |
| Get | GET /api/v2/contacts/{id} | Single contact |
| Search | GET /api/v2/search/contacts?query="..." | Query language; 300-result cap |
| Create | POST /api/v2/contacts | name + one contact channel required |
| Update | PUT /api/v2/contacts/{id} | Partial update |
| Merge | POST /api/v2/contacts/merge | Combine duplicates into a primary |
| Make agent | PUT /api/v2/contacts/{id}/make_agent | Convert a contact into an agent |
Create a Contact
{
"name": "John Smith",
"email": "john.smith@acme.com",
"company_id": 5001,
"job_title": "Office Manager"
}
Search Contacts
GET /api/v2/search/contacts?query="email:'john.smith@acme.com'"
The query language wraps the expression in double quotes and quotes string values. Search returns up to 30 results per page and a maximum of 10 pages (300 records).
Merge Duplicate Contacts
POST /api/v2/contacts/merge
{
"primary_contact_id": 1001,
"secondary_contact_ids": [1002, 1003]
}
Tickets and history from the secondary contacts are re-pointed at the primary. Confirm which record should be primary before merging — merges are not easily reversible.
Make a Contact an Agent
PUT /api/v2/contacts/{id}/make_agent
Converts a customer contact into a Freshdesk agent. This is a privileged, billing-affecting change — flag it explicitly before invoking.
Companies
Key Company Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | Integer | System | Auto-generated unique identifier |
name | String | Yes | Company name (unique) |
domains | Array | No | Email domains used to auto-associate contacts |
description | String | No | Notes about the company |
note | String | No | Internal note |
health_score | String | No | Account health indicator |
account_tier | String | No | Service tier |
Company Operations
| Action | Endpoint | Notes |
|---|---|---|
| List | GET /api/v2/companies | Paginated with page / per_page |
| Get | GET /api/v2/companies/{id} | Single company |
| Search | GET /api/v2/search/companies?query="..." | Query language; 300-result cap |
| Create | POST /api/v2/companies | name required and unique |
| Update | PUT /api/v2/companies/{id} | Partial update |
Search Companies
GET /api/v2/search/companies?query="name:'Acme'"
You can also locate a company by an autocomplete-style name lookup:
GET /api/v2/companies/autocomplete?name=Acme
Resolving Requester -> Contact -> Company
A core MSP workflow is enriching a ticket with full account context:
- Start from the ticket — a ticket carries
requester_idand, when set,company_id. Read the ticket first. - Resolve the contact —
GET /api/v2/contacts/{requester_id}(or search byemailif you only have an address). This yields the contact'scompany_id,job_title, and contact channels. - Resolve the company —
GET /api/v2/companies/{company_id}for the organization'sdomains,account_tier, andhealth_score. - Use domains to disambiguate — if a contact has no
company_id, match the email domain against companydomainsto infer the right account. - Cache reference data — companies and frequent contacts change rarely; cache lookups within a session to stay under the per-minute rate limit.
Ticket #4821
requester_id: 1001 -> Contact "John Smith" (john.smith@acme.com)
company_id: 5001
-> Company "Acme Corporation"
domains: ["acme.com"], tier: "Gold"
Error Handling
| Error | Cause | Resolution |
|---|---|---|
| 400 Validation failed | Missing name or contact channel; duplicate company name | Supply required fields; pick a unique company name |
| 404 Not found | Unknown contact/company ID | Re-list or re-search to confirm |
| 409 Conflict | Email/company already exists | Search for and reuse the existing record |
| 403 Forbidden | API key lacks scope | Check agent permissions (especially for make_agent) |
Best Practices
- Search before creating — avoid duplicate contacts by checking
emailfirst; let ticket creation auto-create only when intentional. - Maintain company domains — accurate
domainslet Freshdesk auto-associate new contacts to the right company.
Related Skills
- Freshdesk Ticketing - Tickets reference requesters and companies
- Freshdesk API Patterns - Search query language and pagination
- Freshdesk SLA & Business Hours - Company/tier-driven SLA association
Signals
- GitHub stars
- 45
- Forks
- 24
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
freshdesk-contacts-companies- Source
- github.com/wyre-ai/msp-claude-plugins