API details
| Property | Value |
|---|---|
| Endpoint | POST /growth-intelligence |
| Protocol | GraphQL over HTTP |
| Authentication | x-api-key header |
| Content-Type | application/json |
| Operation | query GetUsers |
| Response format | JSON |
User fields
Use this reference when choosing filters[].key and sort.key. It lists paths on User (and nested objects) and whether filtering or sorting is allowed.
account.* is returned in query results but is not in that registry yet for filter/sort.
Basic
| Path | Label | Filter | Sort | Type | Description | Example |
|---|---|---|---|---|---|---|
id | User ID | Yes | No | String! | Unique user identifier | "usr_abc123" |
name | Name (user) | Yes | Yes | String! | User display name | "Alice Johnson" |
email | Yes | Yes | String! | User email address | "alice@acme.com" |
Account
| Path | Label | Filter | Sort | Type | Description | Example |
|---|---|---|---|---|---|---|
account | Accounts | No | No | [UserAccount!] | CRM accounts linked to the user (empty array or null when none). Matches repeated account rows from the accounts service. | [] |
account.id | Account ID | No | No | String! | Id on each element of account[] (not a separate filter path; use User fields table for filter keys). | "acc_xyz789" |
account.name | Account name | No | No | String! | Display name on each account[] element. | "Acme Corp" |
account.source | Account source | No | No | String! | Source stream on each account[] element. | "ThriveStack" |
account.timestamp | Account timestamp | No | No | String! | Association timestamp on each account[] element. | "2024-01-10T09:00:00Z" |
Status
| Path | Label | Filter | Sort | Type | Description | Example |
|---|---|---|---|---|---|---|
enriched | Enriched | Yes | Yes | Boolean! | Whether enrichment data is available | true |
softDeleted | Soft deleted | Yes | Yes | Boolean! | Whether the user is soft-deleted | false |
source | Source | Yes | Yes | String! | User data source stream | "ThriveStack" |
timeToHardDelete | Time to hard delete | Yes | Yes | Float! | Days remaining until permanent deletion | 25.5 |
tracked | Tracked | Yes | Yes | Boolean! | Whether a creation event was received | true |
Acquisition
| Path | Label | Filter | Sort | Type | Description | Example |
|---|---|---|---|---|---|---|
acquisition.abuseRuleResult | Abuse rule result | No | No | [AbuseRuleResult!]! | Per-rule abuse evaluation (query only) | [{ "passed": true, "ruleId": "r1" }] |
acquisition.abuseStatus | Abuse status | Yes | Yes | String! | Abuse classification | "clean" |
acquisition.initialUtmCampaign | Initial UTM campaign | Yes | Yes | String! | UTM campaign from first touch | "spring-launch" |
acquisition.initialUtmContent | Initial UTM content | Yes | Yes | String! | UTM content from first touch | "hero" |
acquisition.initialUtmMedium | Initial UTM medium | Yes | Yes | String! | UTM medium from first touch | "cpc" |
acquisition.initialUtmSource | Initial UTM source | Yes | Yes | String! | UTM source from first touch | "google" |
acquisition.initialUtmTerm | Initial UTM term | Yes | Yes | String! | UTM term from first touch | "product" |
acquisition.isInvited | Is invited | Yes | Yes | Boolean! | Whether user was invited by another user | true |
acquisition.signedUpOn | Signed up on | Yes | Yes | String! | Signup date (ISO) | "2024-01-10T09:00:00Z" |
acquisition.timeToSignupDays | Time to signup (days) | Yes | Yes | Float! | Days from first touch to signup | 4.5 |
acquisition.touchpointsToSignup | Touchpoints to signup | Yes | Yes | Int! | Marketing touchpoints before signup | 3 |
Engagement
| Path | Label | Filter | Sort | Type | Description | Example |
|---|---|---|---|---|---|---|
engagement.isActive | Is active | Yes | Yes | Boolean! | Active in last 30 days | true |
engagement.lastActiveAt | Last active at | Yes | Yes | String! | Last activity timestamp | "2024-01-22T11:30:00Z" |
engagement.latestSigninTimestamp | Latest sign-in | Yes | Yes | String! | Most recent sign-in timestamp | "2024-01-22T08:45:00Z" |
engagement.totalSignIns | Total sign-ins | Yes | Yes | Int! | Cumulative sign-in count | 47 |
Demographics
| Path | Label | Filter | Sort | Type | Description | Example |
|---|---|---|---|---|---|---|
demographics.avatar | Avatar | Yes | No | String! | Avatar URL | "https://cdn.example.com/a.png" |
demographics.city | City | Yes | Yes | String! | City | "San Francisco" |
demographics.country | Country | Yes | Yes | String! | Country | "United States" |
demographics.countryCode | Country code | Yes | Yes | String! | ISO country code | "US" |
demographics.emailProvider | Email provider | Yes | Yes | String! | Email provider domain | "gmail.com" |
demographics.employmentDomain | Employment domain | Yes | Yes | String! | Employer company domain | "acme.com" |
demographics.employmentName | Employment name | Yes | Yes | String! | Company the user works at | "Acme Corp" |
demographics.employmentRole | Employment role | No | No | String! | Broad job role / function | "product" |
demographics.employmentSeniority | Employment seniority | Yes | Yes | String! | Seniority level | "senior" |
demographics.employmentSubRole | Employment sub-role | Yes | Yes | String! | Granular job sub-role | "pm" |
demographics.employmentTitle | Employment title | Yes | Yes | String! | Job title | "Head of Product" |
demographics.facebookHandle | Facebook handle | Yes | No | String! | Facebook handle | "alice.j" |
demographics.firstName | First name | Yes | Yes | String! | First name (enriched) | "Alice" |
demographics.fullName | Full name | Yes | Yes | String! | Full name from enrichment | "Alice Johnson" |
demographics.githubHandle | GitHub handle | Yes | No | String! | GitHub username | "alice" |
demographics.lastName | Last name | Yes | Yes | String! | Last name (enriched) | "Johnson" |
demographics.linkedinHandle | LinkedIn handle | Yes | No | String! | LinkedIn profile handle | "in/alice" |
demographics.location | Location | No | No | String! | Full location string | "San Francisco, CA" |
demographics.phone | Phone | Yes | No | String! | Phone number(s) | "+1-415-555-0199" |
demographics.state | State | Yes | Yes | String! | State / province | "California" |
demographics.stateCode | State code | Yes | Yes | String! | State code | "CA" |
demographics.timeZone | Time zone | Yes | Yes | String! | IANA time zone | "America/Los_Angeles" |
demographics.twitterHandle | Twitter handle | Yes | No | String! | Twitter/X handle | "@alice" |
Input: GetUsersRequest
All three input fields are optional — omit them to retrieve the first page of all users. Combine filters, sort, and pagination to build segments.
filters · optional · array
An array of filter objects. All filters are ANDed: a user must satisfy every filter. Each object has:
{
"key": "",
"operator": "equals | not_equals | greater_than | less_than | greater_than_or_equal | less_than_or_equal",
"value": ""
}
value is always a string and is coerced server-side.
Operators
| Operator | Symbol | Description | Example |
|---|---|---|---|
equals | = | Exact match | key: "acquisition.abuseStatus", value: "clean" |
not_equals | ≠ | Excludes the given value | key: "engagement.isActive", value: "false" |
greater_than | > | Numeric or date comparison (exclusive) | key: "engagement.totalSignIns", value: "10" |
less_than | < | Numeric or date comparison (exclusive) | key: "engagement.totalSignIns", value: "3" |
greater_than_or_equal | ≥ | Numeric or date comparison (inclusive) | key: "engagement.totalSignIns", value: "5" |
less_than_or_equal | ≤ | Numeric or date comparison (inclusive) | key: "engagement.totalSignIns", value: "100" |
sort · optional · object
Sort by exactly one field per request. sort.key must be a path whose Sort column is Yes in the User fields table above.
{
"key": "",
"direction": "asc" | "desc"
}
Tip: Sort by engagement.totalSignIns desc for most active users, acquisition.signedUpOn desc for newest signups, or demographics.employmentSeniority asc by seniority.
pagination · optional · object
Page-based pagination. Defaults to page 1, size 10 if omitted. size max 100.
{
"number": 1,
"size": 25
}
Increment number until the returned user array is empty.
Example request
Active users with more than 5 sign-ins and clean abuse status, ordered by sign-in count descending.
GraphQL query
query GetUsers($input: GetUsersRequest!) {
getUsers(input: $input) {
message
user {
id
name
email
account {
id
name
source
timestamp
}
source
tracked
enriched
softDeleted
timeToHardDelete
acquisition {
signedUpOn
isInvited
abuseStatus
touchpointsToSignup
timeToSignupDays
initialUtmSource
initialUtmMedium
initialUtmCampaign
initialUtmTerm
initialUtmContent
}
engagement {
isActive
lastActiveAt
totalSignIns
latestSigninTimestamp
}
demographics {
firstName
lastName
employmentTitle
employmentRole
employmentSeniority
city
country
timeZone
}
}
}
}
Variables (JSON)
{
"input": {
"filters": [
{ "key": "engagement.isActive", "operator": "equals", "value": "true" },
{ "key": "engagement.totalSignIns", "operator": "greater_than", "value": "5" },
{ "key": "acquisition.abuseStatus", "operator": "equals", "value": "clean" }
],
"sort": { "key": "engagement.totalSignIns", "direction": "desc" },
"pagination": { "number": 1, "size": 25 }
}
}
cURL
curl --location 'https://api.app.thrivestack.ai/growth-intelligence' \\
--header 'content-type: application/json' \\
--header 'x-api-key: YOUR_API_KEY' \\
--data '{
"query": "query GetUsers($input: GetUsersRequest!) { getUsers(input: $input) { message user { id name email } } }",
"variables": {
"input": {
"filters": [
{ "key": "engagement.isActive", "operator": "equals", "value": "true" },
{ "key": "engagement.totalSignIns", "operator": "greater_than", "value": "5" },
{ "key": "acquisition.abuseStatus", "operator": "equals", "value": "clean" }
],
"sort": { "key": "engagement.totalSignIns", "direction": "desc" },
"pagination": { "number": 1, "size": 25 }
}
}
}'
Example response
Matching users are under data.getUsers.user (array). message may be "success" or omitted depending on the server.
{
"data": {
"getUsers": {
"message": "success",
"user": [
{
"id": "usr_abc123",
"name": "Alice Johnson",
"email": "alice@acme.com",
"account": [
{ "id": "acc_xyz789", "name": "Acme Corp", "source": "ThriveStack", "timestamp": "2024-01-10T09:00:00Z" }
],
"source": "ThriveStack",
"tracked": true,
"enriched": true,
"softDeleted": false,
"timeToHardDelete": 0,
"acquisition": {
"signedUpOn": "2024-01-10T09:00:00Z",
"isInvited": true,
"abuseStatus": "clean",
"touchpointsToSignup": 3,
"timeToSignupDays": 4.5,
"initialUtmSource": "google",
"initialUtmMedium": "cpc",
"initialUtmCampaign": "spring-launch"
},
"engagement": {
"isActive": true,
"lastActiveAt": "2024-01-22T11:30:00Z",
"totalSignIns": 47,
"latestSigninTimestamp": "2024-01-22T08:45:00Z"
},
"demographics": {
"firstName": "Alice",
"lastName": "Johnson",
"employmentTitle": "Head of Product",
"employmentRole": "product",
"employmentSeniority": "senior",
"city": "San Francisco",
"country": "United States",
"timeZone": "America/Los_Angeles"
}
}
]
}
}
}
Tips and best practices
- Filter values are always strings — use
"true"/"false"for booleans and numeric strings for numbers; the server coerces them. - All filters are ANDed. Use separate filter objects for each condition (e.g. active and 10+ sign-ins).
- Account on the user record: query
account { id name source timestamp }as a list ofUserAccount.account.*is not filterable/sortable in the current user-list registry; preferemail,demographics.employmentDomain, or other fields, then narrow client-side if needed. - Organic power users: e.g.
acquisition.isInvitedequals"false"with highengagement.totalSignIns. - Paginate by incrementing
pagination.numberuntiluseris empty.