GraphQL API
Full GraphQL schema for the CRM & Marketing Platform.
Endpoint
POST /graphql
Authentication
Include JWT token in Authorization header:
Authorization: Bearer <jwt_token>
Queries
type Query {
# Customers
customer(id: ID!): Customer
customers(
tenantId: String!
filter: CustomerFilter
pagination: PaginationInput
): CustomerConnection!
resolveCustomer(
tenantId: String!
email: String
phone: String
authUserId: ID
): ResolutionResult
# Timeline & Notes
customerTimeline(
customerId: ID!
filters: TimelineFilters
): ActivityConnection!
customerNotes(customerId: ID!, type: NoteType): [Note!]!
# Segments
segments(tenantId: String!, type: SegmentType): [Segment!]!
segment(id: ID!): Segment
segmentMembers(
segmentId: ID!
pagination: PaginationInput
): CustomerConnection!
# Campaigns
campaigns(
tenantId: String!
filter: CampaignFilter
): CampaignConnection!
campaign(id: ID!): Campaign
campaignStats(id: ID!): CampaignStats!
# Journeys
journeys(tenantId: String!, status: JourneyStatus): [Journey!]!
journey(id: ID!): Journey
journeySteps(journeyId: ID!): [JourneyStep!]!
journeyEnrollments(
journeyId: ID!
status: EnrollmentStatus
): JourneyEnrollmentConnection!
# Social
socialConnections(
tenantId: String!
platform: SocialPlatform
): [SocialConnection!]!
socialPosts(
tenantId: String!
filter: SocialPostFilter
): SocialPostConnection!
# Promotions
eventPromotions(tenantId: String!, clubId: String): [EventPromotion!]!
# Analytics
engagementAnalytics(tenantId: String!): EngagementAnalytics!
campaignAnalytics(
tenantId: String!
dateRange: DateRangeInput
): CampaignAnalytics!
journeyAnalytics(tenantId: String!): JourneyAnalytics!
socialAnalytics(
tenantId: String!
dateRange: DateRangeInput
): SocialAnalytics!
}
Mutations
type Mutation {
# Customers
createCustomer(input: CreateCustomerInput!): Customer!
updateCustomer(id: ID!, input: UpdateCustomerInput!): Customer!
mergeCustomers(winnerId: ID!, loserId: ID!): MergeResult!
# Notes
addNote(customerId: ID!, input: CreateNoteInput!): Note!
updateNote(id: ID!, input: UpdateNoteInput!): Note!
deleteNote(id: ID!): Boolean!
# Segments
createSegment(input: CreateSegmentInput!): Segment!
updateSegment(id: ID!, input: UpdateSegmentInput!): Segment!
deleteSegment(id: ID!): Boolean!
refreshSegment(id: ID!): RefreshResult!
syncSegmentToMessaging(id: ID!): SyncResult!
# Campaigns
createCampaign(input: CreateCampaignInput!): Campaign!
updateCampaign(id: ID!, input: UpdateCampaignInput!): Campaign!
scheduleCampaign(id: ID!, scheduledAt: DateTime!): Campaign!
pauseCampaign(id: ID!): Campaign!
resumeCampaign(id: ID!): Campaign!
cancelCampaign(id: ID!): Campaign!
# Journeys
createJourney(input: CreateJourneyInput!): Journey!
updateJourney(id: ID!, input: UpdateJourneyInput!): Journey!
addJourneyStep(journeyId: ID!, input: CreateJourneyStepInput!): JourneyStep!
updateJourneyStep(
journeyId: ID!
stepId: ID!
input: UpdateJourneyStepInput!
): JourneyStep!
deleteJourneyStep(journeyId: ID!, stepId: ID!): Boolean!
activateJourney(id: ID!): Journey!
pauseJourney(id: ID!): Journey!
archiveJourney(id: ID!): Journey!
enrollCustomerInJourney(journeyId: ID!, customerId: ID!): JourneyEnrollment!
exitCustomerFromJourney(journeyId: ID!, customerId: ID!): Boolean!
# Social
initiateSocialConnection(
input: InitiateSocialConnectionInput!
): OAuthResult!
completeSocialConnection(
input: CompleteSocialConnectionInput!
): SocialConnection!
disconnectSocial(id: ID!): Boolean!
createSocialPost(input: CreateSocialPostInput!): SocialPost!
updateSocialPost(id: ID!, input: UpdateSocialPostInput!): SocialPost!
scheduleSocialPost(id: ID!, scheduledAt: DateTime!): SocialPost!
publishSocialPost(id: ID!): SocialPost!
# Promotions
createEventPromotion(input: CreateEventPromotionInput!): EventPromotion!
updateEventPromotion(
id: ID!
input: UpdateEventPromotionInput!
): EventPromotion!
executeEventPromotion(id: ID!): ExecutePromotionResult!
}
Types
Customer Types
type Customer {
id: ID!
tenantId: String!
email: String
phoneNumber: String
firstName: String
lastName: String
fullName: String
status: CustomerStatus!
lifecycleStage: LifecycleStage!
membershipTier: String
membershipStatus: String
handicap: Float
homeClub: Club
engagementScore: Int
churnRiskScore: Int
lifetimeValue: Int
emailOptIn: Boolean!
smsOptIn: Boolean!
pushOptIn: Boolean!
lastActivityAt: DateTime
createdAt: DateTime!
updatedAt: DateTime!
# Relationships
activities(first: Int, after: String): ActivityConnection!
notes: [Note!]!
segments: [Segment!]!
journeyEnrollments: [JourneyEnrollment!]!
}
type CustomerConnection {
edges: [CustomerEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type CustomerEdge {
node: Customer!
cursor: String!
}
input CustomerFilter {
status: CustomerStatus
lifecycleStage: LifecycleStage
search: String
segmentId: ID
engagementMin: Int
engagementMax: Int
churnRiskMin: Int
churnRiskMax: Int
emailOptIn: Boolean
}
input CreateCustomerInput {
tenantId: String!
email: String
phoneNumber: String
firstName: String
lastName: String
lifecycleStage: LifecycleStage
}
input UpdateCustomerInput {
email: String
phoneNumber: String
firstName: String
lastName: String
lifecycleStage: LifecycleStage
}
type ResolutionResult {
profile: Customer!
resolution: Resolution!
}
type Resolution {
isNew: Boolean!
matchedBy: [String!]!
confidence: Int!
}
type MergeResult {
winner: Customer!
mergedFields: [String!]!
}
Activity Types
type Activity {
id: ID!
type: ActivityType!
category: ActivityCategory!
title: String!
description: String
occurredAt: DateTime!
metadata: JSON
sourceService: String
sourceEventId: String
}
type ActivityConnection {
edges: [ActivityEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
input TimelineFilters {
categories: [ActivityCategory!]
startDate: DateTime
endDate: DateTime
}
Note Types
type Note {
id: ID!
content: String!
type: NoteType!
isPinned: Boolean!
createdBy: String!
createdByName: String
createdAt: DateTime!
updatedAt: DateTime!
}
input CreateNoteInput {
content: String!
type: NoteType
isPinned: Boolean
}
input UpdateNoteInput {
content: String
type: NoteType
isPinned: Boolean
}
Segment Types
type Segment {
id: ID!
tenantId: String!
name: String!
description: String
type: SegmentType!
criteria: JSON
isActive: Boolean!
memberCount: Int!
lastRefreshedAt: DateTime
messagingSegmentId: String
lastSyncedAt: DateTime
createdAt: DateTime!
# Relationships
members(pagination: PaginationInput): CustomerConnection!
}
input CreateSegmentInput {
tenantId: String!
name: String!
description: String
type: SegmentType!
criteria: JSON
}
input UpdateSegmentInput {
name: String
description: String
criteria: JSON
isActive: Boolean
}
type RefreshResult {
segmentId: ID!
previousCount: Int!
newCount: Int!
added: Int!
removed: Int!
}
type SyncResult {
messagingSegmentId: String!
syncedCount: Int!
syncedAt: DateTime!
}
Campaign Types
type Campaign {
id: ID!
tenantId: String!
clubId: String
name: String!
description: String
type: CampaignType!
status: CampaignStatus!
channels: [Channel!]!
segment: Segment
scheduledAt: DateTime
startedAt: DateTime
completedAt: DateTime
targetCount: Int!
sentCount: Int!
deliveredCount: Int!
openedCount: Int!
clickedCount: Int!
openRate: Float
clickRate: Float
createdAt: DateTime!
}
type CampaignStats {
campaignId: ID!
targetCount: Int!
sentCount: Int!
deliveredCount: Int!
openedCount: Int!
clickedCount: Int!
convertedCount: Int!
unsubscribedCount: Int!
bouncedCount: Int!
deliveryRate: Float!
openRate: Float!
clickRate: Float!
conversionRate: Float!
byChannel: JSON
}
input CampaignFilter {
clubId: String
status: CampaignStatus
type: CampaignType
}
input CreateCampaignInput {
tenantId: String!
clubId: String
name: String!
description: String
type: CampaignType!
segmentId: ID
channels: [Channel!]!
emailTemplateId: String
smsTemplateId: String
timezone: String
}
Journey Types
type Journey {
id: ID!
tenantId: String!
name: String!
description: String
status: JourneyStatus!
triggerType: String!
triggerConfig: JSON
allowReentry: Boolean!
totalEnrolled: Int!
totalCompleted: Int!
totalExited: Int!
steps: [JourneyStep!]!
activatedAt: DateTime
createdAt: DateTime!
}
type JourneyStep {
id: ID!
stepNumber: Int!
type: JourneyStepType!
name: String
config: JSON!
nextStepId: ID
nextStepYesId: ID
nextStepNoId: ID
}
type JourneyEnrollment {
id: ID!
journey: Journey!
customer: Customer!
status: EnrollmentStatus!
currentStepNumber: Int
waitingUntil: DateTime
enrolledAt: DateTime!
completedAt: DateTime
steps: [JourneyEnrollmentStep!]!
}
type JourneyEnrollmentStep {
stepId: ID!
stepName: String
status: StepStatus!
startedAt: DateTime
completedAt: DateTime
}
input CreateJourneyInput {
tenantId: String!
name: String!
description: String
triggerType: String!
triggerConfig: JSON
allowReentry: Boolean
timezone: String
}
input CreateJourneyStepInput {
type: JourneyStepType!
name: String
config: JSON!
afterStepId: ID
}
Social Types
type SocialConnection {
id: ID!
tenantId: String!
clubId: String
platform: SocialPlatform!
accountId: String!
accountName: String!
accountType: String
isActive: Boolean!
permissions: [String!]!
tokenExpiry: DateTime
lastUsedAt: DateTime
createdAt: DateTime!
}
type SocialPost {
id: ID!
connection: SocialConnection!
content: String!
mediaUrls: [String!]!
hashtags: [String!]!
linkUrl: String
status: SocialPostStatus!
scheduledAt: DateTime
publishedAt: DateTime
platformPostId: String
platformUrl: String
likes: Int!
comments: Int!
shares: Int!
reach: Int!
error: String
createdAt: DateTime!
}
type OAuthResult {
authUrl: String!
state: String!
}
input InitiateSocialConnectionInput {
tenantId: String!
clubId: String!
platform: SocialPlatform!
redirectUri: String!
}
input CompleteSocialConnectionInput {
platform: SocialPlatform!
code: String!
state: String!
}
input CreateSocialPostInput {
tenantId: String!
connectionId: ID!
campaignId: ID
content: String!
mediaUrls: [String!]
linkUrl: String
hashtags: [String!]
}
Event Promotion Types
type EventPromotion {
id: ID!
tenantId: String!
clubId: String!
sourceType: PromotionSourceType!
sourceId: String!
autoPromote: Boolean!
channels: [Channel!]!
announceAt: DateTime
reminderDays: [Int!]!
segment: Segment
lastPromotedAt: DateTime
isActive: Boolean!
createdAt: DateTime!
}
type ExecutePromotionResult {
promotionId: ID!
executedAt: DateTime!
recipientCount: Int!
campaignId: ID
}
input CreateEventPromotionInput {
tenantId: String!
clubId: String!
sourceType: PromotionSourceType!
sourceId: String!
autoPromote: Boolean
channels: [Channel!]!
announceAt: DateTime
reminderDays: [Int!]
segmentId: ID
emailTemplateId: String
smsTemplateId: String
socialContent: String
}
Enums
enum CustomerStatus { ACTIVE, INACTIVE, MERGED, DELETED }
enum LifecycleStage { SUBSCRIBER, LEAD, CUSTOMER, MEMBER, ADVOCATE, CHURNED }
enum NoteType { GENERAL, SUPPORT, SALES, COMPLAINT }
enum SegmentType { STATIC, DYNAMIC, SMART }
enum CampaignType { ONE_TIME, RECURRING, TRIGGERED, JOURNEY }
enum CampaignStatus { DRAFT, SCHEDULED, ACTIVE, PAUSED, COMPLETED, CANCELLED }
enum JourneyStatus { DRAFT, ACTIVE, PAUSED, ARCHIVED }
enum JourneyStepType { TRIGGER, SEND, WAIT, CONDITION, SPLIT, UPDATE, END }
enum EnrollmentStatus { ACTIVE, COMPLETED, EXITED, FAILED }
enum StepStatus { PENDING, ACTIVE, COMPLETED, SKIPPED, FAILED }
enum SocialPlatform { FACEBOOK, INSTAGRAM, TWITTER, LINKEDIN, TIKTOK }
enum SocialPostStatus { DRAFT, SCHEDULED, PUBLISHING, PUBLISHED, FAILED }
enum Channel { EMAIL, SMS, PUSH, WHATSAPP, IN_APP, SOCIAL }
enum PromotionSourceType { COMPETITION, CLUB_EVENT, SPECIAL }
enum ActivityCategory { MEMBERSHIP, BOOKING, COMMUNICATION, ENGAGEMENT, FINANCIAL, GOLF, MARKETING, SOCIAL, SYSTEM }
Input Types
input PaginationInput {
first: Int
after: String
last: Int
before: String
}
input DateRangeInput {
startDate: DateTime!
endDate: DateTime!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
Scalars
scalar DateTime
scalar JSON