AgentSkillsCN

Clients

当您需要管理HaloPSA客户时,可使用此技能:创建、更新、搜索或管理客户关系。本技能涵盖客户字段、站点/位置、联系人、客户类型,以及客户入驻流程,是MSP客户经理在HaloPSA中开展CRM工作的核心工具。

SKILL.md
--- frontmatter
description: >
  Use this skill when working with HaloPSA clients - creating, updating,
  searching, or managing customer relationships. Covers client fields,
  sites/locations, contacts, client types, and onboarding workflows.
  Essential for MSP account managers handling CRM in HaloPSA.
triggers:
  - halopsa client
  - halo client
  - halopsa customer
  - halo customer
  - client management halopsa
  - create client halopsa
  - halopsa site
  - halopsa location
  - halopsa contact
  - client onboarding halo
  - halopsa crm

HaloPSA Client Management

Overview

Clients (customers) are the foundation of HaloPSA. All tickets, contracts, assets, and invoices are associated with clients. Proper client data management is critical for accurate service delivery and billing.

Key Concepts

Client

The primary entity representing a customer organization.

FieldTypeRequiredDescription
idintSystemUnique identifier
namestring(255)YesOfficial company name
client_to_invoiceintNoParent company for billing
toplevel_idintNoTop-level parent in hierarchy
inactiveboolNoActive/inactive status
main_site_idintNoPrimary site reference

Client Contact Fields

FieldTypeRequiredDescription
emailaddressstringNoPrimary email
phonenumberstringNoMain phone
websitestringNoWebsite URL
accountmanager_idintNoAssigned account manager

Client Billing Fields

FieldTypeRequiredDescription
colourstringNoClient color code (hex)
notestextNoInternal notes
taxcodestringNoTax identifier
currency_codestringNoBilling currency
payment_termsintNoPayment terms (days)

Client Types

HaloPSA supports client classification through custom fields and categories. Common patterns:

TypeDescriptionUse Case
CustomerActive paying clientFull service
ProspectPotential customerSales pipeline
LeadMarketing qualifiedPre-sales
PartnerStrategic partnerCollaboration
VendorSupplierProcurement

Sites (Locations)

Sites represent physical locations for a client.

Site Fields

FieldTypeRequiredDescription
idintSystemUnique identifier
client_idintYesParent client
namestring(255)YesSite name
line1stringNoAddress line 1
line2stringNoAddress line 2
line3stringNoAddress line 3
line4stringNoCity
postcodestringNoPostal/ZIP code
countrystringNoCountry
phonenumberstringNoSite phone
main_siteboolNoIs primary site
inactiveboolNoActive status

Contacts (Users)

Contacts (also called Users in HaloPSA) are individuals at a client organization.

Contact Fields

FieldTypeRequiredDescription
idintSystemUnique identifier
client_idintYesAssociated client
site_idintNoAssociated site
namestring(255)YesFull name
firstnamestringNoFirst name
surnamestringNoLast name
emailaddressstringNoEmail address
phonenumberstringNoDirect phone
mobilenumberstringNoMobile phone
jobtitlestringNoJob title
inactiveboolNoActive status
isimportantcontactboolNoVIP flag

API Patterns

Creating a Client

http
POST /api/Client
Authorization: Bearer {token}
Content-Type: application/json
json
[
  {
    "name": "Acme Corporation",
    "emailaddress": "info@acme.example.com",
    "phonenumber": "555-123-4567",
    "website": "https://acme.example.com",
    "notes": "Enterprise client, premium support tier",
    "accountmanager_id": 101
  }
]

Response

json
{
  "clients": [
    {
      "id": 123,
      "name": "Acme Corporation",
      "emailaddress": "info@acme.example.com",
      "phonenumber": "555-123-4567",
      "inactive": false
    }
  ]
}

Searching Clients

Search by name:

http
GET /api/Client?search=acme

Active clients only:

http
GET /api/Client?inactive=false

By account manager:

http
GET /api/Client?accountmanager_id=101

Paginated with sorting:

http
GET /api/Client?page_no=1&page_size=50&order=name&orderdesc=false

Getting a Single Client

http
GET /api/Client/123

With additional details:

http
GET /api/Client/123?includesites=true&includeusers=true

Updating a Client

http
POST /api/Client
Authorization: Bearer {token}
Content-Type: application/json
json
[
  {
    "id": 123,
    "phonenumber": "555-987-6543",
    "website": "https://newsite.acme.example.com",
    "accountmanager_id": 102
  }
]

Creating a Site

http
POST /api/Site
Authorization: Bearer {token}
Content-Type: application/json
json
[
  {
    "client_id": 123,
    "name": "Acme HQ",
    "line1": "123 Main Street",
    "line2": "Suite 500",
    "line4": "Springfield",
    "postcode": "62701",
    "country": "United States",
    "phonenumber": "555-123-4567",
    "main_site": true
  }
]

Creating a Contact (User)

http
POST /api/Users
Authorization: Bearer {token}
Content-Type: application/json
json
[
  {
    "client_id": 123,
    "site_id": 456,
    "name": "John Smith",
    "firstname": "John",
    "surname": "Smith",
    "emailaddress": "john.smith@acme.example.com",
    "phonenumber": "555-123-4568",
    "mobilenumber": "555-987-6543",
    "jobtitle": "IT Director",
    "isimportantcontact": true
  }
]

Searching Contacts

Contacts for a client:

http
GET /api/Users?client_id=123

Search by email:

http
GET /api/Users?search=john.smith@acme.example.com

Active contacts only:

http
GET /api/Users?inactive=false&client_id=123

Client Hierarchy

HaloPSA supports parent-child client relationships:

Setting Up Hierarchy

json
[
  {
    "id": 124,
    "name": "Acme West Branch",
    "client_to_invoice": 123,
    "toplevel_id": 123
  }
]

Hierarchy Use Cases

  • Franchise operations - Parent company, individual locations
  • Multi-site organizations - Headquarters with branch offices
  • Billing consolidation - Invoice parent, service children

Common Workflows

Client Onboarding

  1. Create client record

    • Set name and contact information
    • Assign account manager
    • Configure billing settings
  2. Create primary site

    • Add main location address
    • Set as main_site
  3. Create primary contact

    • Add key stakeholder
    • Set as important contact
    • Verify email address
  4. Set up contract

    • Link to client
    • Define service levels
    • Configure billing
  5. Deploy assets (if applicable)

    • Link devices to client
    • Associate with site

Contact Management

javascript
async function onboardContact(clientId, contactData) {
  // 1. Check for existing contact by email
  const existing = await searchUsers({
    client_id: clientId,
    search: contactData.emailaddress
  });

  if (existing.length > 0) {
    console.log('Contact already exists:', existing[0].id);
    return existing[0];
  }

  // 2. Create new contact
  const contact = await createUser({
    client_id: clientId,
    ...contactData
  });

  // 3. Send welcome email (if configured)
  if (contactData.send_welcome) {
    await sendWelcomeEmail(contact.id);
  }

  return contact;
}

Client Deactivation

When a client churns:

  1. Mark client inactive

    json
    [{ "id": 123, "inactive": true }]
    
  2. Close open tickets

    • Resolve or cancel pending tickets
    • Document reason
  3. End contracts

    • Update contract end dates
    • Process final billing
  4. Update assets

    • Return or reassign devices
    • Update RMM status

Error Handling

Common API Errors

CodeMessageResolution
400Name is requiredClient must have a name
400Invalid client_idParent client doesn't exist
400Duplicate emailContact email already in use
404Client not foundVerify client ID
409Cannot delete - has related recordsDeactivate instead

Validation Patterns

javascript
function validateClient(client) {
  const errors = [];

  if (!client.name || client.name.trim() === '') {
    errors.push('Client name is required');
  }

  if (client.emailaddress && !isValidEmail(client.emailaddress)) {
    errors.push('Invalid email format');
  }

  if (client.website && !isValidUrl(client.website)) {
    errors.push('Invalid website URL');
  }

  return {
    isValid: errors.length === 0,
    errors
  };
}

Best Practices

  1. Standardize naming - Use consistent company name formats
  2. Verify before creating - Always search first to prevent duplicates
  3. Maintain data quality - Regular audits of contact information
  4. Use classifications - Categorize clients for reporting
  5. Track account managers - Assign for accountability
  6. Keep contacts current - Deactivate departed employees
  7. Document relationships - Use notes for key account information
  8. Set up hierarchy correctly - Proper parent-child for billing

Data Quality Queries

Find clients without contacts

http
GET /api/Client?hasusers=false&inactive=false

Find contacts without email

http
GET /api/Users?emailaddress=null&inactive=false

Find duplicate client names

javascript
async function findDuplicateClients() {
  const clients = await fetchAllClients();
  const names = {};
  const duplicates = [];

  clients.forEach(client => {
    const normalized = client.name.toLowerCase().trim();
    if (names[normalized]) {
      duplicates.push({
        name: client.name,
        ids: [names[normalized], client.id]
      });
    } else {
      names[normalized] = client.id;
    }
  });

  return duplicates;
}

Related Skills