Skip to main content

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 KeysTypeDescriptionComparators
Contact Properties
addedAtDatetimeWhen the contact was addedeq, neq, exists, lt, lte, gt, gte
updatedAtDatetimeWhen the contact was last updatedeq, neq, exists, lt, lte, gt, gte
assignedTeamMemberTextThe contact's assigned team membereq, neq, exists, like
bioTextTextThe contact's biography/bio texteq, neq, exists, like
emailAddressTextThe contact's email addresseq, neq, exists, like
firstNameTextThe contact's first nameeq, neq, exists, like
fullNameTextThe contact's full nameeq, neq, exists, like
GTIDTextThe contact's GroupTrack IDeq, neq, exists, like
lastNameTextThe contact's last nameeq, neq, exists, like
phoneNumberTextThe contact's phone numbereq, neq, exists, like
teamUIDTextThe contact's team UIDeq, neq, exists, like
Pipelines
pipelinesObjectThe contact's pipelines/groupsexists
pipeline.addedAtDatetimeWhen the contact was added to the pipelineeq, neq, exists, lt, lte, gt, gte
pipeline.nickNameTextThe pipeline's nicknameeq, neq, exists, like
pipeline.pipelineUIDTextThe pipeline's UIDeq, neq, exists, like
Pipeline Question Responses
responsesObjectThe contact's pipeline question responsesexists
response.answerTextThe response's answer texteq, neq, exists, like
response.questionTextThe response's question texteq, neq, exists, like
Pipeline Stages
stage.nameTextThe stage's nameeq, neq, exists, like
stage.remoteIDTextThe stage's remote IDeq, neq, exists, like
stage.stageUIDTextThe stage's UIDeq, neq, exists, like
stage.updatedAtDatetimeWhen the stage was last updatedeq, neq, exists, lt, lte, gt, gte
Contact's Sources
sourcesObjectThe contact's sources (social media, etc.)exists
source.dmThreadIDTextThe source's direct message thread IDeq, neq, exists, like
source.sourceTextThe source's platform (e.g., Instagram)eq, neq, exists, like
source.userIDTextThe source's user IDeq, neq, exists, like
source.usernameTextThe source's usernameeq, neq, exists, like
Contact's Tag Sets
tagSet.connectionUIDTextThe tag set's connection UIDeq, neq, exists, like
tagSet.nameTextThe tag set's nameeq, neq, exists, like
tagSet.tagSetUIDTextThe tag set's UIDeq, neq, exists, like
Contact's Tags
tag.nameTextThe tag's nameeq, neq, exists, like
tag.remoteIDTextThe tag's remote IDeq, neq, exists, like
tag.tagIDTextThe tag's IDeq, neq, exists, like

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
}