Contacts Guide
This guide provides examples and information on how to interact with the Contacts endpoints of our REST API.
Contact Data Structure
A contact object follows this general structure:
interface Contact {
GTID: string; // Unique GroupTrack contact identifier
firstName?: string | null; // Contact's first name
lastName?: string | null; // Contact's last name
fullName?: string | null; // Contact's full name
emailAddress?: string | null; // Contact's email address
phoneNumber?: string | null; // Contact's phone number
bioText?: string | null; // Contact's biography or bio text
statusLabel?: string | null; // Current status label for the contact
assignedTeamMember?: string | null; // Team member assigned to this contact
addedAt?: Date | null; // Timestamp when contact was added
updatedAt?: Date | null; // Timestamp when contact was last updated
pipelines?: Pipeline[]; // Array of pipelines the contact is in
tagSets?: TagSet[]; // Array of tag sets associated with the contact
}
interface Pipeline {
pipelineUID: string; // Unique identifier for the pipeline
nickName?: string; // Custom name for the pipeline
addedAt?: Date; // When the contact was added to this pipeline
stage?: Stage | null; // Current stage information
responses?: QuestionResponse[]; // Answers to pipeline questions
}
interface TagSet {
tagSetUID: string; // Unique identifier for the tag set
name?: string; // Name of the tag set
tags?: Tag[]; // Array of tags within this set
}
interface Tag {
tagID: string; // Unique identifier for the tag
name: string; // Name of the tag
remoteID?: string | number | null; // Remote system ID for the tag (if from external integration)
}
interface Stage {
stageUID?: string | null; // Unique identifier for the stage
name?: string; // Name of the stage
remoteID?: string | number | null; // Remote system ID for the stage (if from external integration)
updatedAt?: Date | null; // Timestamp when stage was last updated
}
interface QuestionResponse {
question: string; // The question text
answer: string; // The answer text
}
interface Source {
source: string; // Platform name (e.g., Instagram, Facebook)
username?: string; // User's username on that platform
userID?: string; // User's ID on that platform
dmThreadID?: string; // Direct message thread ID
messageRequestStatus?: string; // Status of message requests
}
Searching Contacts
You can search for contacts using various filters. Below are a list of available filters:
For detailed information on how to use these filters and available comparators, see Searching Guide.
Usage Examples
# Search for contacts by first name
GET "/contacts?filter[firstName]=John"
GET "/contacts?filter[firstName][eq]=John"
# Search for contacts added after a specific date
GET "/contacts?filter[addedAt][gt]=2025-01-01"
# Search for contacts with a specific email using like comparison
GET "/contacts?filter[emailAddress][like]=example.com"
# Search for contacts that have a pipeline assigned
GET "/contacts?filter[pipelines][exists]"
GET "/contacts?filter[pipelines][exists]=true"
Contact Filters
| Filter Keys | Type | Description | Comparators |
|---|---|---|---|
| Contact Properties | |||
addedAt | Datetime | When the contact was added | eq, neq, exists, lt, lte, gt, gte |
updatedAt | Datetime | When the contact was last updated | eq, neq, exists, lt, lte, gt, gte |
assignedTeamMember | Text | The contact's assigned team member | eq, neq, exists, like |
bioText | Text | The contact's biography/bio text | eq, neq, exists, like |
emailAddress | Text | The contact's email address | eq, neq, exists, like |
firstName | Text | The contact's first name | eq, neq, exists, like |
fullName | Text | The contact's full name | eq, neq, exists, like |
GTID | Text | The contact's GroupTrack ID | eq, neq, exists, like |
lastName | Text | The contact's last name | eq, neq, exists, like |
phoneNumber | Text | The contact's phone number | eq, neq, exists, like |
teamUID | Text | The contact's team UID | eq, neq, exists, like |
| Pipelines | |||
pipelines | Object | The contact's pipelines/groups | exists |
pipeline.addedAt | Datetime | When the contact was added to the pipeline | eq, neq, exists, lt, lte, gt, gte |
pipeline.nickName | Text | The pipeline's nickname | eq, neq, exists, like |
pipeline.pipelineUID | Text | The pipeline's UID | eq, neq, exists, like |
| Pipeline Question Responses | |||
responses | Object | The contact's pipeline question responses | exists |
response.answer | Text | The response's answer text | eq, neq, exists, like |
response.question | Text | The response's question text | eq, neq, exists, like |
| Pipeline Stages | |||
stage.name | Text | The stage's name | eq, neq, exists, like |
stage.remoteID | Text | The stage's remote ID | eq, neq, exists, like |
stage.stageUID | Text | The stage's UID | eq, neq, exists, like |
stage.updatedAt | Datetime | When the stage was last updated | eq, neq, exists, lt, lte, gt, gte |
| Contact's Sources | |||
sources | Object | The contact's sources (social media, etc.) | exists |
source.dmThreadID | Text | The source's direct message thread ID | eq, neq, exists, like |
source.source | Text | The source's platform (e.g., Instagram) | eq, neq, exists, like |
source.userID | Text | The source's user ID | eq, neq, exists, like |
source.username | Text | The source's username | eq, neq, exists, like |
| Contact's Tag Sets | |||
tagSet.connectionUID | Text | The tag set's connection UID | eq, neq, exists, like |
tagSet.name | Text | The tag set's name | eq, neq, exists, like |
tagSet.tagSetUID | Text | The tag set's UID | eq, neq, exists, like |
| Contact's Tags | |||
tag.name | Text | The tag's name | eq, neq, exists, like |
tag.remoteID | Text | The tag's remote ID | eq, neq, exists, like |
tag.tagID | Text | The tag's ID | eq, neq, exists, like |
Related Data
Tasks and activities are associated with contacts via their GTID.
Contact Notes
Notes are stored as activities with a type of "note".
So, to get a contact's notes, you need to search the activities with the same GTID and have a type of "note".
const {data: notes, error: search_error} = await fetch(
`/activities?filter[GTID]=${GTID}&filter[type]=note`
).then(response => response.json());
if (search_error){
// deal with error
}
for (let note of notes){
// do something with each
}