Skip to content

Management API Reference

The Management API provides full CRUD access to every resource in your GrowthOS project. It is designed for server-side use only — never expose your secret key in client-side code.

Base URLhttps://api.growthos.io/v1
AuthenticationAuthorization: Bearer gos_sk_...
Content-Typeapplication/json
Rate Limit10–100 req/s depending on plan

Terminal window
# List your first 10 contacts
curl -X GET "https://api.growthos.io/v1/contacts?limit=10" \
-H "Authorization: Bearer gos_sk_live_your_secret_key" \
-H "Content-Type: application/json"

All list endpoints return paginated responses using cursor-based pagination. See the API Overview for details on pagination, error handling, and rate limiting.


contacts:read contacts:write

Contacts are the central entity in GrowthOS. Every interaction — events, campaigns, surveys, referrals — links back to a contact record in the Unified Contact Graph.

GET /v1/contacts?limit=25&segment_id=seg_abc&tag=enterprise

Query Parameters

ParameterTypeDescription
limitintegerItems per page (max 100, default 25)
cursorstringPagination cursor from previous response
segment_idstringFilter by segment membership
tagstringFilter by tag
created_afterISO 8601Contacts created after this date
created_beforeISO 8601Contacts created before this date

Response

{
"data": [
{
"id": "cntct_8x2m4k",
"email": "alice@example.com",
"external_id": "user_123",
"traits": {
"name": "Alice Chen",
"plan": "growth",
"company": "Acme Inc"
},
"tags": ["enterprise", "active"],
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-02-20T14:22:00Z"
}
],
"has_more": true,
"next_cursor": "eyJpZCI6ImNudGN0XzhiNGsiLCJ0cyI6MTcwOTcxMn0"
}
GET /v1/contacts/cntct_8x2m4k

Returns the full contact profile including traits, recent events, segment memberships, scores, and referral activity.

{
"id": "cntct_8x2m4k",
"email": "alice@example.com",
"external_id": "user_123",
"traits": {
"name": "Alice Chen",
"plan": "growth",
"company": "Acme Inc",
"signed_up_at": "2026-01-15T10:30:00Z"
},
"tags": ["enterprise", "active"],
"scores": {
"engagement": 82,
"lead": 65
},
"segments": ["seg_active_trial", "seg_enterprise"],
"referral_stats": {
"referrals_made": 7,
"conversions": 3
},
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-02-20T14:22:00Z"
}
PATCH /v1/contacts/cntct_8x2m4k
Content-Type: application/json
{
"traits": {
"plan": "scale",
"company_size": 50
},
"tags": ["enterprise", "active", "upgraded"]
}

Traits are merged — only the specified fields are updated. Existing traits not included in the request are preserved.

DELETE /v1/contacts/cntct_8x2m4k
POST /v1/contacts/cntct_8x2m4k/merge
Content-Type: application/json
{
"source_contact_id": "cntct_dup_9z3n",
"conflict_resolution": "prefer_target"
}

Merges the source contact into the target. All events, referrals, and campaign interactions from the source are reassigned. The source contact is deleted after merge.

GET /v1/contacts/cntct_8x2m4k/events?limit=50

Returns the event history for a specific contact, ordered by timestamp descending.

GET /v1/contacts/cntct_8x2m4k/segments

Returns all segments this contact currently belongs to, including both static and dynamic segment memberships.


segments:read segments:write

Segments are dynamic groups of contacts defined by filter rules. Membership is evaluated in real time — when a contact’s traits or event history change, their segment memberships update automatically.

POST /v1/segments
Content-Type: application/json
{
"name": "Active Trial Users",
"rules": {
"operator": "AND",
"conditions": [
{
"field": "traits.plan",
"op": "eq",
"value": "trial"
},
{
"field": "events.login",
"op": "count_gte",
"value": 3,
"window": "7d"
},
{
"field": "traits.signed_up_at",
"op": "gte",
"value": "2025-01-01"
}
]
}
}

Response

{
"id": "seg_t7k2m",
"name": "Active Trial Users",
"rules": { "..." : "..." },
"contact_count": 1243,
"created_at": "2026-02-23T10:00:00Z",
"updated_at": "2026-02-23T10:00:00Z"
}
OperatorDescriptionExample
eqEqualstraits.plan eq "trial"
neqNot equalstraits.status neq "churned"
gt, gte, lt, lteNumeric / date comparisonstraits.mrr gte 100
containsString containstraits.email contains "@acme.com"
existsField is presenttraits.phone exists
not_existsField is absenttraits.company not_exists
count_gte, count_lteEvent count in time windowevents.login count_gte 3 in "7d"
inValue in listtraits.plan in ["growth", "scale"]

Rules can be nested with AND / OR operators for complex conditions.

GET /v1/segments
GET /v1/segments/seg_t7k2m

Returns the segment definition along with the current member count.

PATCH /v1/segments/seg_t7k2m
Content-Type: application/json
{
"name": "Active Trial Users (Updated)",
"rules": {
"operator": "AND",
"conditions": [
{ "field": "traits.plan", "op": "eq", "value": "trial" },
{ "field": "events.login", "op": "count_gte", "value": 5, "window": "7d" }
]
}
}
DELETE /v1/segments/seg_t7k2m
GET /v1/segments/seg_t7k2m/contacts?limit=50

Returns paginated contacts that currently match the segment’s filter rules.

POST /v1/segments/seg_t7k2m/estimate
Content-Type: application/json
{
"rules": {
"operator": "AND",
"conditions": [
{ "field": "traits.plan", "op": "eq", "value": "trial" },
{ "field": "events.login", "op": "count_gte", "value": 10, "window": "30d" }
]
}
}

Response

{
"estimated_count": 487,
"total_contacts": 12500,
"percentage": 3.9
}

Preview the contact count for a set of rules without creating or modifying a segment. Useful for testing filter rules before saving.


referrals:read referrals:write

Manage referral programs, generate shareable links, track conversions, and view leaderboards.

POST /v1/referrals/programs
Content-Type: application/json
{
"name": "Friend Referral Program",
"reward_type": "credit",
"reward_amount": 20,
"reward_currency": "USD",
"referee_reward": {
"type": "discount",
"amount": 15,
"currency": "USD"
},
"tiers": [
{ "referrals": 5, "bonus": 50 },
{ "referrals": 10, "bonus": 150 },
{ "referrals": 25, "bonus": 500 }
],
"limits": {
"max_referrals_per_contact": 100,
"conversion_window_days": 30
},
"status": "active"
}
GET /v1/referrals/programs
GET /v1/referrals/programs/ref_prog_abc

Returns the program configuration along with aggregate stats (total links, conversions, total rewards issued).

PATCH /v1/referrals/programs/ref_prog_abc
Content-Type: application/json
{
"reward_amount": 25,
"limits": {
"max_referrals_per_contact": 50
}
}
GET /v1/referrals/programs/ref_prog_abc/links?limit=50

Returns all referral links generated for a specific program.

POST /v1/referrals/links
Content-Type: application/json
{
"program_id": "ref_prog_abc",
"contact_id": "cntct_8x2m4k",
"channel": "email"
}

Response

{
"id": "ref_link_x7k2",
"code": "ALICE-ACME-7K2",
"url": "https://yourapp.com/r/ALICE-ACME-7K2",
"program_id": "ref_prog_abc",
"contact_id": "cntct_8x2m4k",
"conversions": 0,
"created_at": "2026-02-23T10:00:00Z"
}
GET /v1/referrals/links/ALICE-ACME-7K2
GET /v1/referrals/links/ALICE-ACME-7K2/conversions

Returns all conversions attributed to this referral link, including the referred contact and conversion timestamp.

POST /v1/referrals/conversions
Content-Type: application/json
{
"link_code": "ALICE-ACME-7K2",
"referred_contact_id": "cntct_new_9z3n",
"conversion_event": "subscription_started",
"metadata": {
"plan": "growth",
"value": 49.00
}
}

Use this endpoint for server-side conversion tracking when automatic detection is not sufficient (for example, offline conversions or custom qualification criteria).

GET /v1/referrals/leaderboard?program_id=ref_prog_abc&limit=10

Response

{
"data": [
{
"rank": 1,
"contact_id": "cntct_8x2m4k",
"email": "alice@example.com",
"referrals": 23,
"conversions": 18,
"tier": "gold"
},
{
"rank": 2,
"contact_id": "cntct_b4k9m",
"email": "bob@example.com",
"referrals": 15,
"conversions": 11,
"tier": "silver"
}
],
"program_id": "ref_prog_abc",
"has_more": true,
"next_cursor": "eyJyYW5rIjoyLCJpZCI6ImNudGN0X2I0azltIn0"
}

campaigns:read campaigns:write

GrowthOS supports two campaign types:

Lifecycle Campaigns

Event-triggered email sequences. Define a trigger event (e.g., signup_completed), delay, and a sequence of emails that send automatically when a contact matches the criteria.

Broadcast Campaigns

One-time sends to a specific segment. Ideal for announcements, product launches, and newsletters.

POST /v1/campaigns
Content-Type: application/json
{
"name": "Onboarding Sequence",
"type": "lifecycle",
"trigger": {
"event": "signup_completed",
"segment_id": "seg_new_users"
},
"steps": [
{
"delay": "0m",
"subject": "Welcome to Acme!",
"template_id": "tmpl_welcome_01"
},
{
"delay": "2d",
"subject": "Getting started with your dashboard",
"template_id": "tmpl_onboard_02"
},
{
"delay": "5d",
"subject": "Have you tried referrals?",
"template_id": "tmpl_onboard_03"
}
]
}
GET /v1/campaigns?type=lifecycle&status=active
GET /v1/campaigns/cmpgn_abc123
PATCH /v1/campaigns/cmpgn_abc123
Content-Type: application/json
{
"name": "Onboarding Sequence v2",
"steps": [
{
"delay": "0m",
"subject": "Welcome aboard!",
"template_id": "tmpl_welcome_02"
}
]
}
POST /v1/campaigns/cmpgn_abc123/activate

Starts the campaign. For lifecycle campaigns, new contacts matching the trigger will begin receiving emails. For broadcast campaigns, sends begin at the scheduled time (or immediately if no scheduled_at is set).

POST /v1/campaigns/cmpgn_abc123/pause

Pauses a running campaign. No new emails will be sent. Contacts already mid-sequence retain their position and will resume from where they left off when reactivated.

POST /v1/campaigns/cmpgn_abc123/test
Content-Type: application/json
{
"email": "test@yourteam.com",
"step_index": 0
}

Sends a preview of a specific campaign step to the given email address. Does not affect campaign stats.

GET /v1/campaigns/cmpgn_abc123/stats

Response

{
"campaign_id": "cmpgn_abc123",
"status": "active",
"stats": {
"sent": 4520,
"delivered": 4480,
"opened": 2150,
"clicked": 890,
"bounced": 40,
"unsubscribed": 12,
"open_rate": 0.48,
"click_rate": 0.20,
"bounce_rate": 0.009,
"unsubscribe_rate": 0.003
},
"updated_at": "2026-02-23T12:00:00Z"
}

surveys:read surveys:write

Create and manage NPS, CSAT, and custom surveys with configurable triggers and frequency caps.

POST /v1/surveys
Content-Type: application/json
{
"name": "Post-Trial NPS",
"type": "nps",
"question": "How likely are you to recommend us to a friend or colleague?",
"follow_up": "What could we do better?",
"trigger": {
"segment_id": "seg_trial_ended",
"event": "trial_expired",
"delay": "1h"
},
"frequency_cap": {
"max_surveys_per_contact": 1,
"cooldown_days": 90
},
"status": "draft"
}

Survey types: nps (0-10 scale), csat (1-5 scale), custom (flexible question types).

GET /v1/surveys
GET /v1/surveys/srvy_abc123
PATCH /v1/surveys/srvy_abc123
Content-Type: application/json
{
"question": "How likely are you to recommend Acme to a colleague?",
"trigger": {
"delay": "2h"
}
}
POST /v1/surveys/srvy_abc123/activate

Begins delivering the survey to contacts matching the trigger criteria.

GET /v1/surveys/srvy_abc123/responses?limit=50

Response

{
"data": [
{
"id": "resp_7k2m",
"contact_id": "cntct_8x2m4k",
"score": 9,
"comment": "Love the referral feature!",
"category": "promoter",
"responded_at": "2026-02-22T15:30:00Z"
},
{
"id": "resp_3n5p",
"contact_id": "cntct_b4k9m",
"score": 6,
"comment": "Email editor could be better",
"category": "passive",
"responded_at": "2026-02-22T16:10:00Z"
}
],
"has_more": true,
"next_cursor": "eyJpZCI6InJlc3BfM241cCJ9"
}
GET /v1/surveys/srvy_abc123/stats

Response

{
"survey_id": "srvy_abc123",
"total_sent": 500,
"total_responses": 210,
"response_rate": 0.42,
"nps_score": 47,
"breakdown": {
"promoters": 130,
"passives": 52,
"detractors": 28
},
"average_score": 7.8,
"updated_at": "2026-02-23T12:00:00Z"
}

waitlists:read waitlists:write

Manage viral waitlists with built-in referral mechanics — contacts move up the queue by referring friends.

POST /v1/waitlists
Content-Type: application/json
{
"name": "Pro Plan Early Access",
"slug": "pro-early-access",
"referral_boost": 3,
"auto_approve": false,
"welcome_email_template_id": "tmpl_wl_welcome"
}

The referral_boost field determines how many positions a contact moves up per successful referral.

GET /v1/waitlists/wl_abc123
GET /v1/waitlists/wl_abc123/entries?limit=50

Response

{
"data": [
{
"id": "wl_entry_7k2m",
"contact_id": "cntct_8x2m4k",
"email": "alice@example.com",
"position": 1,
"referral_count": 12,
"status": "waiting",
"joined_at": "2026-01-10T08:00:00Z"
},
{
"id": "wl_entry_3n5p",
"contact_id": "cntct_b4k9m",
"email": "bob@example.com",
"position": 2,
"referral_count": 8,
"status": "waiting",
"joined_at": "2026-01-11T09:30:00Z"
}
],
"total_entries": 3420,
"has_more": true,
"next_cursor": "eyJwb3MiOjIsImlkIjoid2xfZW50cnlfM241cCJ9"
}
POST /v1/waitlists/wl_abc123/entries
Content-Type: application/json
{
"email": "charlie@example.com",
"traits": {
"name": "Charlie Park",
"source": "partner_referral"
}
}
POST /v1/waitlists/wl_abc123/entries/wl_entry_7k2m/approve

Approves a single entry and sends the invite email. The entry’s status changes from waiting to approved.

POST /v1/waitlists/wl_abc123/entries/approve-batch
Content-Type: application/json
{
"count": 50,
"order": "position"
}

Approves the top N entries by position. All approved contacts receive their invite email.


webhooks:read webhooks:write

Register HTTP endpoints to receive real-time event notifications from GrowthOS. All webhook payloads are signed with HMAC-SHA256 for verification. See Authentication for signature verification details.

POST /v1/webhooks/endpoints
Content-Type: application/json
{
"url": "https://yourserver.com/webhooks/growthos",
"events": [
"contact.created",
"contact.updated",
"referral.converted",
"survey.response.created",
"campaign.email.bounced"
],
"secret": "whsec_your_signing_secret"
}
GET /v1/webhooks/endpoints
PATCH /v1/webhooks/endpoints/whep_abc123
Content-Type: application/json
{
"events": [
"contact.created",
"referral.converted"
]
}
DELETE /v1/webhooks/endpoints/whep_abc123
GET /v1/webhooks/endpoints/whep_abc123/logs?limit=25

Response

{
"data": [
{
"id": "wh_log_9z3n",
"event": "referral.converted",
"status": "delivered",
"http_status": 200,
"attempt": 1,
"delivered_at": "2026-02-23T10:05:00Z",
"response_time_ms": 142
},
{
"id": "wh_log_5p7q",
"event": "contact.created",
"status": "failed",
"http_status": 500,
"attempt": 3,
"next_retry_at": "2026-02-23T11:00:00Z",
"delivered_at": null,
"response_time_ms": 5002
}
],
"has_more": true,
"next_cursor": "eyJpZCI6IndoX2xvZ181cDdxIn0"
}

Failed deliveries are retried with exponential backoff (up to 5 attempts over 24 hours).

POST /v1/webhooks/endpoints/whep_abc123/test
Content-Type: application/json
{
"event": "contact.created"
}

Sends a synthetic test event to your endpoint so you can verify your integration is working correctly.


analytics:read

Query aggregated analytics data across your project. The analytics API is read-only.

POST /v1/analytics/query
Content-Type: application/json
{
"type": "event_count",
"event": "signup_completed",
"interval": "day",
"from": "2026-02-01",
"to": "2026-02-23",
"filters": {
"traits.plan": "growth"
},
"group_by": "traits.source"
}

Response

{
"type": "event_count",
"data": [
{ "date": "2026-02-01", "groups": { "organic": 45, "referral": 23, "paid": 18 } },
{ "date": "2026-02-02", "groups": { "organic": 52, "referral": 28, "paid": 15 } }
],
"total": 1420
}

Supported query types: event_count, unique_contacts, funnel, cohort_retention.

GET /v1/analytics/overview

Response

{
"total_contacts": 12500,
"contacts_30d": 1830,
"events_today": 4520,
"events_avg_daily": 3800,
"active_campaigns": 6,
"nps_score": 47,
"referral_conversion_rate": 0.23
}
GET /v1/analytics/events?limit=50&event=signup_completed

Returns recent events in reverse chronological order. Filterable by event name, contact, and date range.

GET /v1/analytics/funnels/fnl_abc123

Returns step-by-step conversion rates for a defined funnel.

GET /v1/analytics/cohorts/chrt_abc123

Returns retention data for a defined cohort, with weekly or monthly buckets.


settings:read settings:write

Manage project configuration and API keys.

GET /v1/settings

Response

{
"project_id": "proj_abc123",
"name": "Acme Growth",
"domain": "acme.com",
"timezone": "America/New_York",
"default_from_email": "growth@acme.com",
"created_at": "2025-06-01T00:00:00Z"
}
PATCH /v1/settings
Content-Type: application/json
{
"timezone": "Europe/London",
"default_from_email": "hello@acme.com"
}
GET /v1/settings/keys

Returns all API keys for the project. Secret key values are redacted — only the last four characters are shown.

{
"data": [
{
"id": "key_8x2m4k",
"name": "Backend Service",
"type": "secret",
"key_hint": "...4k9m",
"scopes": ["contacts:read", "contacts:write", "campaigns:read"],
"created_at": "2026-01-01T00:00:00Z",
"last_used_at": "2026-02-23T09:45:00Z"
}
]
}
POST /v1/settings/keys
Content-Type: application/json
{
"name": "Analytics Dashboard",
"scopes": ["analytics:read", "contacts:read"]
}

Response

{
"id": "key_new_7k2m",
"name": "Analytics Dashboard",
"key": "gos_sk_live_abc123def456...",
"scopes": ["analytics:read", "contacts:read"],
"created_at": "2026-02-23T10:00:00Z"
}
DELETE /v1/settings/keys/key_8x2m4k

Revoked keys enter a 24-hour grace period before permanent deactivation. See Authentication for details on key rotation.


A complete reference of all Management API endpoints.

MethodEndpointDescription
GET/v1/contactsList contacts
GET/v1/contacts/:idGet contact profile
PATCH/v1/contacts/:idUpdate contact traits
DELETE/v1/contacts/:idSoft-delete contact
POST/v1/contacts/:id/mergeMerge duplicate contacts
GET/v1/contacts/:id/eventsContact event history
GET/v1/contacts/:id/segmentsContact segment memberships
MethodEndpointDescription
POST/v1/segmentsCreate segment
GET/v1/segmentsList segments
GET/v1/segments/:idGet segment with member count
PATCH/v1/segments/:idUpdate segment rules
DELETE/v1/segments/:idDelete segment
GET/v1/segments/:id/contactsList contacts in segment
POST/v1/segments/:id/estimatePreview segment count
MethodEndpointDescription
POST/v1/referrals/programsCreate referral program
GET/v1/referrals/programsList programs
GET/v1/referrals/programs/:idGet program details
PATCH/v1/referrals/programs/:idUpdate program
GET/v1/referrals/programs/:id/linksList program links
POST/v1/referrals/linksGenerate referral link
GET/v1/referrals/links/:codeLookup link by code
GET/v1/referrals/links/:code/conversionsLink conversions
POST/v1/referrals/conversionsRecord manual conversion
GET/v1/referrals/leaderboardTop referrers leaderboard
MethodEndpointDescription
POST/v1/campaignsCreate campaign
GET/v1/campaignsList campaigns
GET/v1/campaigns/:idGet campaign
PATCH/v1/campaigns/:idUpdate campaign
POST/v1/campaigns/:id/activateStart campaign
POST/v1/campaigns/:id/pausePause campaign
POST/v1/campaigns/:id/testSend test email
GET/v1/campaigns/:id/statsCampaign statistics
MethodEndpointDescription
POST/v1/surveysCreate survey
GET/v1/surveysList surveys
GET/v1/surveys/:idGet survey
PATCH/v1/surveys/:idUpdate survey
POST/v1/surveys/:id/activateActivate survey
GET/v1/surveys/:id/responsesList responses
GET/v1/surveys/:id/statsAggregate stats
MethodEndpointDescription
POST/v1/waitlistsCreate waitlist
GET/v1/waitlists/:idGet waitlist
GET/v1/waitlists/:id/entriesList entries
POST/v1/waitlists/:id/entriesAdd entry manually
POST/v1/waitlists/:id/entries/:entry_id/approveApprove entry
POST/v1/waitlists/:id/entries/approve-batchBatch approve
MethodEndpointDescription
POST/v1/webhooks/endpointsRegister endpoint
GET/v1/webhooks/endpointsList endpoints
PATCH/v1/webhooks/endpoints/:idUpdate endpoint
DELETE/v1/webhooks/endpoints/:idDelete endpoint
GET/v1/webhooks/endpoints/:id/logsDelivery logs
POST/v1/webhooks/endpoints/:id/testSend test event
MethodEndpointDescription
POST/v1/analytics/queryFlexible analytics query
GET/v1/analytics/overviewDashboard overview
GET/v1/analytics/eventsEvent stream
GET/v1/analytics/funnels/:idFunnel analysis
GET/v1/analytics/cohorts/:idCohort retention
MethodEndpointDescription
GET/v1/settingsGet project settings
PATCH/v1/settingsUpdate settings
GET/v1/settings/keysList API keys
POST/v1/settings/keysCreate API key
DELETE/v1/settings/keys/:idRevoke API key