Skip to main content

Customers API

Customer profile management, identity resolution, timeline, and notes.


Customer Profiles

List Customers

GET /customers

Query Parameters

ParameterTypeDescription
tenantIdstringTenant ID (required)
statusstringFilter: ACTIVE, INACTIVE, MERGED, DELETED
lifecycleStagestringFilter: SUBSCRIBER, LEAD, CUSTOMER, MEMBER, ADVOCATE, CHURNED
searchstringSearch by name, email, phone
segmentIdstringFilter by segment membership
engagementMinnumberMin engagement score (0-100)
churnRiskMinnumberMin churn risk (0-100)
emailOptInbooleanFilter by opt-in
skipnumberOffset (default: 0)
takenumberLimit (default: 25, max: 100)

Response: 200 OK

{
"data": [{
"id": "uuid",
"email": "john@example.com",
"firstName": "John",
"lastName": "Smith",
"status": "ACTIVE",
"engagementScore": 75,
"churnRiskScore": 15,
"lastActivityAt": "2025-12-14T10:00:00Z"
}],
"meta": { "total": 1250, "skip": 0, "take": 25, "hasMore": true }
}

Get Customer

GET /customers/:id

Response: 200 OK

{
"id": "uuid",
"tenantId": "tenant_123",
"email": "john@example.com",
"phoneNumber": "+27821234567",
"firstName": "John",
"lastName": "Smith",
"status": "ACTIVE",
"lifecycleStage": "MEMBER",
"membershipTier": "Gold",
"membershipStatus": "ACTIVE",
"handicap": 12.5,
"homeClubId": "club_123",
"homeClubName": "Randpark Golf Club",
"engagementScore": 75,
"engagementScoreAt": "2025-12-14T02:00:00Z",
"churnRiskScore": 15,
"churnRiskScoreAt": "2025-12-14T02:00:00Z",
"lifetimeValue": 250000,
"emailOptIn": true,
"smsOptIn": true,
"pushOptIn": false,
"lastActivityAt": "2025-12-14T10:00:00Z",
"lastBookingAt": "2025-12-10T06:30:00Z",
"createdAt": "2024-01-15T00:00:00Z",
"updatedAt": "2025-12-14T10:00:00Z"
}

Create Customer

POST /customers

Request Body

{
"tenantId": "tenant_123",
"email": "john@example.com",
"phoneNumber": "+27821234567",
"firstName": "John",
"lastName": "Smith",
"lifecycleStage": "LEAD"
}

Response: 201 Created


Update Customer

PATCH /customers/:id

Request Body

{
"firstName": "Jonathan",
"lastName": "Smith-Jones",
"homeClubId": "club_456"
}

Response: 200 OK


Merge Customers

Merges two customer profiles, combining all data into the winner profile.

POST /customers/:winnerId/merge

Request Body

{
"loserId": "uuid-to-merge"
}

Response: 200 OK

{
"winnerId": "uuid-winner",
"loserId": "uuid-loser",
"mergedFields": ["activities", "notes", "segmentMemberships"],
"mergedAt": "2025-12-14T10:00:00Z"
}

Note: The loser profile is marked with status MERGED and references the winner.


Identity Resolution

Resolve Customer

Finds or creates a customer profile based on identity keys.

GET /customers/resolve

Query Parameters

ParameterTypeDescription
tenantIdstringRequired
authUserIdstringIDP user ID
emailstringEmail
phonestringPhone (E.164 format)

Response: 200 OK

{
"profile": {
"id": "uuid",
"email": "john@example.com",
"firstName": "John",
"lastName": "Smith"
},
"resolution": {
"isNew": false,
"matchedBy": ["email"],
"confidence": 95
}
}

Resolution Priority:

  1. authUserId - 100% confidence
  2. email - 95% confidence
  3. phone - 90% confidence

Activity Timeline

Get Timeline

GET /customers/:id/activities

Query Parameters

ParameterTypeDescription
categoriesstring[]Filter by categories
startDatestringISO 8601 date
endDatestringISO 8601 date
skipnumberOffset
takenumberLimit

Categories:

  • MEMBERSHIP - Tier changes, renewals
  • BOOKING - Tee time bookings
  • COMMUNICATION - Messages sent/received
  • ENGAGEMENT - Email opens, clicks
  • FINANCIAL - Payments, invoices
  • GOLF - Scores, handicap updates
  • MARKETING - Campaign interactions
  • SOCIAL - Social media engagement
  • SYSTEM - Profile updates

Response: 200 OK

{
"data": [{
"id": "activity_123",
"type": "TEETIME_BOOKED",
"category": "BOOKING",
"title": "Tee Time Booked",
"description": "Booked for Bushwillow Course at 06:30",
"occurredAt": "2025-12-14T10:00:00Z",
"metadata": {
"clubName": "Randpark Golf Club",
"courseName": "Bushwillow Course",
"startTime": "2025-12-20T06:30:00Z"
}
}],
"meta": { "total": 45, "skip": 0, "take": 25 }
}

Add Activity

POST /customers/:id/activities

Request Body

{
"type": "NOTE_ADDED",
"category": "SYSTEM",
"title": "Manual Activity",
"description": "Customer called to inquire about membership",
"occurredAt": "2025-12-14T10:00:00Z",
"metadata": {
"source": "phone_call",
"duration": 300
}
}

Response: 201 Created


Customer Notes

List Notes

GET /customers/:id/notes

Query Parameters

ParameterTypeDescription
typestringFilter: GENERAL, SUPPORT, SALES, COMPLAINT

Response: 200 OK

{
"data": [{
"id": "note_123",
"content": "Customer interested in Gold membership upgrade",
"type": "SALES",
"isPinned": true,
"createdBy": "user_456",
"createdByName": "Sarah Admin",
"createdAt": "2025-12-14T10:00:00Z",
"updatedAt": "2025-12-14T10:00:00Z"
}]
}

Create Note

POST /customers/:id/notes

Request Body

{
"content": "Note content",
"type": "GENERAL",
"isPinned": false
}

Response: 201 Created


Update Note

PATCH /notes/:id

Request Body

{
"content": "Updated note content",
"isPinned": true
}

Response: 200 OK


Delete Note

DELETE /notes/:id

Response: 204 No Content