API details
| Property | Value |
|---|---|
| Endpoint | POST /growth-intelligence |
| Protocol | GraphQL over HTTP |
| Authentication | x-api-key header |
| Content-Type | application/json |
| Operation | query GetAccounts |
| Response format | JSON |
Account fields
Filter & sort reference
Use this table when choosing filters[].key and sort.key. It lists every path on Account (and nested objects) and whether the growth-intelligence account list allows it for filtering or sorting (see accountFieldByGraphQLKey in public-api-events). Paths with Filter or Sort set to No are still valid in GraphQL selections (for example acquisition.abuseRuleResult, activation.*) but cannot be used as filters[].key or sort.key until the registry exposes them. Invalid keys produce a GraphQL error.
| Category | Path | Filter | Sort | Type | Description | Example |
|---|---|---|---|---|---|---|
| Basic | createdAtCreated At | Yes | Yes | String! | ISO timestamp of account creation | "2024-01-15T10:30:00Z" |
| Basic | domainDomain | Yes | Yes | String! | Primary domain | "acme.com" |
| Basic | idID | Yes | No | String! | Unique account identifier | "acc_1234abcd" |
| Basic | nameName | Yes | Yes | String! | Account display name | "Acme Corp" |
| Basic | sourceSource | No | No | [String!]! | Data sources the account was ingested from (e.g. hubspot, stripe) | ["hubspot", "stripe"] |
| Acquisition | acquisition.abuseRuleResultAbuse Rule Result | No | No | [AbuseRuleResult!]! | Per-rule abuse check results | [{ "passed": true, "ruleId": "r1", "ruleName": "Domain check", "description": "..." }] |
| Acquisition | acquisition.abuseStatusAbuse Status | Yes | Yes | String! | Abuse classification result (clean, suspicious, blocked) | "clean" |
| Acquisition | acquisition.initialUtmCampaignInitial UTM Campaign | Yes | Yes | String! | First recorded UTM campaign | "brand_q1" |
| Acquisition | acquisition.initialUtmContentInitial UTM Content | Yes | Yes | String! | First recorded UTM content variant | "hero-cta" |
| Acquisition | acquisition.initialUtmMediumInitial UTM Medium | Yes | Yes | String! | First recorded UTM medium | "cpc" |
| Acquisition | acquisition.initialUtmSourceInitial UTM Source | Yes | Yes | String! | First recorded UTM source | "google" |
| Acquisition | acquisition.initialUtmTermInitial UTM Term | Yes | Yes | String! | First recorded UTM keyword term | "product analytics" |
| Acquisition | acquisition.timeToSignupDaysTime to Signup (Days) | Yes | Yes | Int! | Days from first touch to signup | 7 |
| Acquisition | acquisition.touchpointsToSignupTouchpoints to Signup | Yes | Yes | Int! | Marketing touchpoints before signup | 5 |
| Activation | activation.activatedOnActivated On | No | No | String | ISO timestamp of activation | "2024-02-01T08:00:00Z" |
| Activation | activation.championUserChampion User | No | No | String | Email of the account champion | "alice@acme.com" |
| Activation | activation.completionPercentageCompletion % | No | No | Float! | Percentage of journey steps completed | 85.0 |
| Activation | activation.currentStepCurrent Step | No | No | String! | Name of the current journey step | "invite_team" |
| Activation | activation.isDefaultIs Default | No | No | Boolean! | Whether this is the default journey | true |
| Activation | activation.journeyNameJourney Name | No | No | String! | Name of the activation journey | "Core Onboarding" |
| Activation | activation.lastUpdatedLast Updated | No | No | String! | ISO timestamp of last activation update | "2024-02-05T12:00:00Z" |
| Activation | activation.statusStatus | No | No | String! | completed | in_progress | not_started | "completed" |
| Activation | activation.timeSpentTime Spent | No | No | Float | Time spent on the activation journey (days) | 10.5 |
| Activation | activation.ttvTime to Value | No | No | Float | Days from signup to first value milestone | 14.0 |
| Monetization | monetization.arrARR | Yes | Yes | Float! | Annual recurring revenue | 3588.0 |
| Monetization | monetization.billingStatusBilling Status | Yes | Yes | String! | active | past_due | cancelled | trialing | "active" |
| Monetization | monetization.currencyCurrency | No | No | String! | Billing currency code (display only) | "USD" |
| Monetization | monetization.mrrMRR | Yes | Yes | Float! | Monthly recurring revenue | 299.0 |
| Monetization | monetization.nextDueDateNext Due Date | Yes | Yes | String! | Next billing due date (ISO timestamp) | "2024-03-01T00:00:00Z" |
| Monetization | monetization.planPlan | Yes | Yes | String! | Current subscription plan name | "pro" |
| Engagement | engagement.activityCountActivity Count | Yes | Yes | Int! | Total events in the current period | 1430 |
| Engagement | engagement.activityTrendActivity Trend | Yes | Yes | Float! | Ratio of current vs prior period activity. >1 = growth | 1.46 |
| Engagement | engagement.dailyActiveUsersDaily Active Users | Yes | Yes | Int! | Average DAU over the last 30 days | 5 |
| Engagement | engagement.isActiveIs Active | Yes | Yes | Boolean! | Whether account had activity in the last 30 days | true |
| Engagement | engagement.lastActiveAtLast Active At | No | No | String! | ISO timestamp of last recorded activity | "2024-01-20T15:45:00Z" |
| Engagement | engagement.monthlyActiveUsersMonthly Active Users | Yes | Yes | Int! | MAU for the current month | 20 |
| Engagement | engagement.previousActivityCountPrevious Activity Count | No | No | Int! | Total events in the prior period | 980 |
| Engagement | engagement.statusStatus | Yes | Yes | String! | Computed tier: Healthy | At Risk | Critical | New | Inactive | "Healthy" |
| Engagement | engagement.stickinessMonthlyMonthly Stickiness | Yes | Yes | Float! | DAU/MAU ratio (0–1) | 0.55 |
| Engagement | engagement.stickinessWeeklyWeekly Stickiness | Yes | Yes | Float! | DAU/WAU ratio (0–1). Higher = more habitual usage | 0.72 |
| Engagement | engagement.weeklyActiveUsersWeekly Active Users | Yes | Yes | Int! | WAU for the current week | 12 |
| Expansion | expansion.contractionMrrMovementContraction MRR Movement | Yes | Yes | Float! | Projected MRR loss from contraction signals | -50.0 |
| Expansion | expansion.contractionSignalCountContraction Signal Count | Yes | Yes | Int! | Number of negative contraction signals detected | 1 |
| Expansion | expansion.contractionTypesContraction Types | Yes | No | [String!]! | Signal types indicating churn risk (e.g. usage_drop) | ["usage_drop", "support_spike"] |
| Expansion | expansion.expansionMrrMovementExpansion MRR Movement | Yes | Yes | Float! | Projected MRR increase from expansion signals | 150.0 |
| Expansion | expansion.expansionSignalCountExpansion Signal Count | Yes | Yes | Int! | Number of positive expansion signals detected | 3 |
| Expansion | expansion.expansionTypesExpansion Types | Yes | No | [String!]! | Signal types driving expansion (e.g. seat_growth, usage_spike) | ["seat_growth", "feature_adoption"] |
| Firmographics | firmographics.annualRevenueAnnual Revenue | Yes | Yes | String! | Estimated annual revenue | "5000000" |
| Firmographics | firmographics.cityCity | Yes | Yes | String! | City | "San Francisco" |
| Firmographics | firmographics.countryCountry | Yes | Yes | String! | Country name | "United States" |
| Firmographics | firmographics.countryCodeCountry Code | Yes | Yes | String! | ISO 2-letter country code | "US" |
| Firmographics | firmographics.crunchbaseHandleCrunchbase Handle | Yes | No | String! | Crunchbase profile handle | "acme-corp" |
| Firmographics | firmographics.descriptionDescription | Yes | No | String! | Short company description | "Cloud-native analytics platform" |
| Firmographics | firmographics.domainDomain (Enriched) | Yes | Yes | String! | Enrichment-resolved primary domain | "acme.com" |
| Firmographics | firmographics.domainAliasesDomain Aliases | Yes | No | String! | Known domain aliases (comma-separated) | "acme.co,acme.io" |
| Firmographics | firmographics.emailAddressesEmail Addresses | Yes | No | String! | Known company email addresses | "hello@acme.com" |
| Firmographics | firmographics.emailProviderEmail Provider | Yes | Yes | String! | Company email provider | "google" |
| Firmographics | firmographics.employeeCountEmployee Count | Yes | Yes | String! | Headcount (numeric string) | "150" |
| Firmographics | firmographics.employeeCountRangeEmployee Count Range | No | No | String! | Headcount range bucket (display only) | "101-250" |
| Firmographics | firmographics.facebookHandleFacebook Handle | Yes | No | String! | Facebook page handle | "acmecorp" |
| Firmographics | firmographics.founderYearFounding Year | Yes | Yes | String! | Year company was founded | "2015" |
| Firmographics | firmographics.industryIndustry | Yes | Yes | String! | Industry classification | "Technology" |
| Firmographics | firmographics.industryGroupIndustry Group | Yes | Yes | String! | Industry group | "Technology" |
| Firmographics | firmographics.legalNameLegal Name | Yes | Yes | String! | Legal entity name | "Acme Corporation LLC" |
| Firmographics | firmographics.linkedinHandleLinkedIn Handle | Yes | No | String! | LinkedIn company handle | "acme-corp" |
| Firmographics | firmographics.locationLocation | Yes | Yes | String! | Full location string | "San Francisco, CA, US" |
| Firmographics | firmographics.logoLogo | No | No | String! | Company logo URL | "https://logo.clearbit.com/acme.com" |
| Firmographics | firmographics.marketCapMarket Cap | Yes | Yes | String! | Market capitalization | "1000000000" |
| Firmographics | firmographics.nameName (Enriched) | Yes | Yes | String! | Company name from enrichment data | "Acme Corporation" |
| Firmographics | firmographics.phonePhone | Yes | No | String! | Company phone number | "+1-415-555-0100" |
| Firmographics | firmographics.phoneNumbersPhone Numbers | Yes | No | String! | All known company phone numbers | "+1-415-555-0100,+1-800-555-0100" |
| Firmographics | firmographics.postalCodePostal Code | Yes | No | String! | Postal / ZIP code | "94105" |
| Firmographics | firmographics.raisedFunding Raised | Yes | Yes | String! | Total funding raised | "10000000" |
| Firmographics | firmographics.sectorSector | Yes | Yes | String! | Business sector | "Software" |
| Firmographics | firmographics.stateState | Yes | Yes | String! | State / province | "California" |
| Firmographics | firmographics.stateCodeState Code | Yes | Yes | String! | State / province abbreviation | "CA" |
| Firmographics | firmographics.streetAddressStreet Address | Yes | No | String! | Full street address | "123 Main St" |
| Firmographics | firmographics.streetNameStreet Name | Yes | No | String! | Street name | "Main St" |
| Firmographics | firmographics.streetNumberStreet Number | Yes | No | String! | Street number | "123" |
| Firmographics | firmographics.subIndustrySub-Industry | Yes | Yes | String! | Sub-industry classification | "SaaS" |
| Firmographics | firmographics.tagsTags | Yes | No | String! | Comma-separated company tags | "b2b,saas,analytics" |
| Firmographics | firmographics.techTech Stack | Yes | No | String! | Technology stack (comma-separated) | "React,Node.js,Postgres" |
| Firmographics | firmographics.techCategoriesTech Categories | Yes | No | String! | Technology category tags | "frontend,database,cloud" |
| Firmographics | firmographics.timeZoneTime Zone | Yes | Yes | String! | Company IANA time zone | "America/Los_Angeles" |
| Firmographics | firmographics.trafficRankTraffic Rank | Yes | Yes | String! | Alexa/similar web traffic rank | "45210" |
| Firmographics | firmographics.twitterHandleTwitter Handle | Yes | No | String! | Twitter/X handle | "@acmecorp" |
| Firmographics | firmographics.typeCompany Type | Yes | Yes | String! | private | public | nonprofit | government | "private" |
Input: GetAccountsRequest
All three input fields are optional — omit them to retrieve the first page of all
accounts. Combine filters, sort, and pagination
to build segmentation queries.
filters · optional · array
An array of filter objects. All filters are ANDed together: an account must satisfy every filter to appear in results. Each filter has three fields:
{
"key": "<dot-notation field path>",
"operator": "equals | not_equals | greater_than | less_than | greater_than_or_equal | less_than_or_equal",
"value": "<string value>"
}
The value is always a string; it is coerced server-side. Use keys from the
Account fields table where Filter is
Yes. Paths with Filter No are still queryable in GraphQL but cannot be used as
filters[].key.
Operators
| Operator | Symbol | Description | Example |
|---|---|---|---|
equals |
= | Exact match | key: "monetization.plan", value: "pro" |
not_equals |
≠ | Excludes the given value | key: "engagement.status", value: "Churned" |
greater_than |
> | Numeric or date comparison (exclusive) | key: "monetization.mrr", value: "500" |
less_than |
< | Numeric or date comparison (exclusive) | key: "monetization.mrr", value: "100" |
greater_than_or_equal |
≥ | Numeric or date comparison (inclusive) | key: "monetization.arr", value: "1200" |
less_than_or_equal |
≤ | Numeric or date comparison (inclusive) | key: "engagement.monthlyActiveUsers", value: "50" |
sort · optional · object
Sort by exactly one field per request. sort.key must be a path whose
Sort column is Yes in the Account fields
table (same rules as accountFieldByGraphQLKey).
{
"key": "<dot-notation path — Sort = Yes in Account fields table>",
"direction": "asc" | "desc"
}
Tip: Sort by monetization.mrr desc to see
highest-revenue accounts first, or engagement.activityTrend
asc to surface accounts with declining activity. Only paths with
Sort = Yes in the Account fields table are valid sort keys.
pagination · optional · object
Cursor-free page-based pagination. Defaults to page 1, size 10
if omitted.
{
"number": 1,
"size": 10
}
number— page number, starts at 1size— records per page, max 100
To iterate all results, increment number until the returned
account array is empty.
Example request
This example fetches Pro accounts with MRR above $200, ordered by highest MRR first, excluding accounts with a Churned engagement status.
GraphQL query
query GetAccounts($input: GetAccountsRequest!) {
getAccounts(input: $input) {
message
account {
id
name
domain
source
createdAt
acquisition {
abuseStatus
touchpointsToSignup
timeToSignupDays
initialUtmSource
abuseRuleResult {
passed
ruleId
ruleName
description
}
}
monetization {
plan
billingStatus
mrr
currency
}
engagement {
status
isActive
monthlyActiveUsers
activityTrend
}
expansion {
expansionSignalCount
contractionSignalCount
}
}
}
}
Variables (JSON)
{
"input": {
"filters": [
{
"key": "monetization.plan",
"operator": "equals",
"value": "pro"
},
{
"key": "engagement.status",
"operator": "not_equals",
"value": "Churned"
},
{
"key": "monetization.mrr",
"operator": "greater_than",
"value": "200"
}
],
"sort": {
"key": "monetization.mrr",
"direction": "desc"
},
"pagination": {
"number": 1,
"size": 25
}
}
}
cURL
Run this from your terminal to test the API (replace YOUR_API_KEY as needed).
curl --location 'https://api.app.thrivestack.ai/growth-intelligence' \
--header 'content-type: application/json' \
--header 'x-api-key: YOUR_API_KEY' \
--data '
{
"query": "query GetAccounts($input: GetAccountsRequest!) { getAccounts(input: $input) { message account { id name domain source createdAt acquisition { abuseStatus touchpointsToSignup timeToSignupDays initialUtmSource abuseRuleResult { passed ruleId ruleName description } } monetization { plan billingStatus mrr currency } engagement { status isActive monthlyActiveUsers activityTrend } expansion { expansionSignalCount contractionSignalCount } } } }",
"variables": {
"input": {
"filters": [
{
"key": "monetization.plan",
"operator": "equals",
"value": "pro"
},
{
"key": "engagement.status",
"operator": "not_equals",
"value": "Churned"
},
{
"key": "monetization.mrr",
"operator": "greater_than",
"value": "200"
}
],
"sort": {
"key": "monetization.mrr",
"direction": "desc"
},
"pagination": {
"number": 1,
"size": 25
}
}
}
}
'
Example response
The response wraps matching accounts in data.getAccounts.account[].
The message field is optional in the schema and may be "success"
or omitted depending on the server response.
{
"data": {
"getAccounts": {
"message": "success",
"account": [
{
"id": "acc_abc123",
"name": "Acme Corp",
"domain": "acme.com",
"source": ["hubspot", "stripe"],
"createdAt": "2024-01-15T10:30:00Z",
"acquisition": {
"abuseStatus": "clean",
"touchpointsToSignup": 4,
"timeToSignupDays": 2,
"initialUtmSource": "google",
"abuseRuleResult": [
{ "passed": true, "ruleId": "r_domain", "ruleName": "Domain check", "description": "Domain allowed" }
]
},
"monetization": {
"plan": "pro",
"billingStatus": "active",
"mrr": 299.0,
"currency": "USD"
},
"engagement": {
"status": "Healthy",
"isActive": true,
"monthlyActiveUsers": 22,
"activityTrend": 1.32
},
"expansion": {
"expansionSignalCount": 2,
"contractionSignalCount": 0
}
},
{
"id": "acc_def456",
"name": "Globex Inc",
"domain": "globex.io",
"source": ["stripe"],
"createdAt": "2024-02-01T14:00:00Z",
"acquisition": {
"abuseStatus": "clean",
"touchpointsToSignup": 2,
"timeToSignupDays": 0,
"initialUtmSource": "direct",
"abuseRuleResult": []
},
"monetization": {
"plan": "pro",
"billingStatus": "active",
"mrr": 249.0,
"currency": "EUR"
},
"engagement": {
"status": "At Risk",
"isActive": true,
"monthlyActiveUsers": 4,
"activityTrend": 0.61
},
"expansion": {
"expansionSignalCount": 0,
"contractionSignalCount": 1
}
}
]
}
}
}
Tips & best practices
- Filter values are always strings — the server coerces them to the correct type. Pass
"true"for booleans,"299.0"for numbers.- All filters are ANDed. To segment Pro accounts that are also healthy, add two separate filter objects rather than combining values.
- Registry vs GraphQL. The Account fields table mirrors
accountFieldByGraphQLKeyfor list filters/sort. You can still query response-only paths (for exampleactivation,acquisition.abuseRuleResult) in GraphQL when you need them on the wire.- Request only the fields you need. Omitting heavy objects like
firmographicsoracquisition.abuseRuleResultmeaningfully reduces response size.- Use
engagement.statusfor at-risk detection. Values are Healthy, At Risk, Critical, New, and Inactive.- Expansion signals are additive. Filter on
expansion.expansionSignalCountgreater_than"0"for upsell candidates, andexpansion.contractionSignalCountgreater_than"0"for churn risk.