Freshdesk Contacts & Companies

SkillSearch

Freshdesk 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.

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, or autotask-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-assets and halopsa-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

FieldTypeRequiredDescription
idIntegerSystemAuto-generated unique identifier
nameStringYesFull name
emailStringOne of email/phone/mobilePrimary email
phoneStringOne of email/phone/mobileLandline
mobileStringOne of email/phone/mobileMobile number
company_idIntegerNoAssociated company
job_titleStringNoRole at the company
tagsArrayNoFree-form labels

A contact must have at least one of email, phone, mobile, twitter_id, or unique_external_id.

Contact Operations

ActionEndpointNotes
ListGET /api/v2/contactsFilter with email, mobile, phone, company_id, updated_since
GetGET /api/v2/contacts/{id}Single contact
SearchGET /api/v2/search/contacts?query="..."Query language; 300-result cap
CreatePOST /api/v2/contactsname + one contact channel required
UpdatePUT /api/v2/contacts/{id}Partial update
MergePOST /api/v2/contacts/mergeCombine duplicates into a primary
Make agentPUT /api/v2/contacts/{id}/make_agentConvert 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

FieldTypeRequiredDescription
idIntegerSystemAuto-generated unique identifier
nameStringYesCompany name (unique)
domainsArrayNoEmail domains used to auto-associate contacts
descriptionStringNoNotes about the company
noteStringNoInternal note
health_scoreStringNoAccount health indicator
account_tierStringNoService tier

Company Operations

ActionEndpointNotes
ListGET /api/v2/companiesPaginated with page / per_page
GetGET /api/v2/companies/{id}Single company
SearchGET /api/v2/search/companies?query="..."Query language; 300-result cap
CreatePOST /api/v2/companiesname required and unique
UpdatePUT /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:

  1. Start from the ticket — a ticket carries requester_id and, when set, company_id. Read the ticket first.
  2. Resolve the contactGET /api/v2/contacts/{requester_id} (or search by email if you only have an address). This yields the contact's company_id, job_title, and contact channels.
  3. Resolve the companyGET /api/v2/companies/{company_id} for the organization's domains, account_tier, and health_score.
  4. Use domains to disambiguate — if a contact has no company_id, match the email domain against company domains to infer the right account.
  5. 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

ErrorCauseResolution
400 Validation failedMissing name or contact channel; duplicate company nameSupply required fields; pick a unique company name
404 Not foundUnknown contact/company IDRe-list or re-search to confirm
409 ConflictEmail/company already existsSearch for and reuse the existing record
403 ForbiddenAPI key lacks scopeCheck agent permissions (especially for make_agent)

Best Practices

  • Search before creating — avoid duplicate contacts by checking email first; let ticket creation auto-create only when intentional.
  • Maintain company domains — accurate domains let Freshdesk auto-associate new contacts to the right company.

Related Skills

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