Ingest API
High-volume, low-latency. Accepts events, identifies contacts, and powers embedded widgets. Uses write-only keys safe to expose in client-side code.
GrowthOS is API-first. Every feature you see in the dashboard is backed by a public API endpoint — there are no hidden internal routes. If the UI can do it, your code can do it.
This means you can:
GrowthOS splits its API surface into two distinct APIs, each optimized for its use case.
Ingest API
High-volume, low-latency. Accepts events, identifies contacts, and powers embedded widgets. Uses write-only keys safe to expose in client-side code.
Management API
Full CRUD on all resources. Create campaigns, define segments, query analytics, manage settings. Uses secret keys with granular permission scopes. Server-side only.
| Aspect | Ingest API | Management API |
|---|---|---|
| Base URL | ingest.growthos.io/v1 | api.growthos.io/v1 |
| Auth | Write Key (client-safe) | Secret Key + Scopes |
| Rate Limit | 1,000 req/s per key | 100 req/s per key |
| Use Case | Track, Identify, Page, Group | CRUD, Query, Admin |
| Safe for client? | Yes | No — server-side only |
| Response style | Minimal (ACK) | Full resource payloads |
| Idempotency | Built-in via message_id | Via Idempotency-Key header |
GrowthOS uses URL-path versioning. The current version is /v1/.
/v2/)When a version is deprecated:
Sunset HTTP header appears on all responses from the deprecated version, containing the retirement date410 GoneRate limits are enforced per API key and vary by plan tier.
| Plan | Ingest API | Management API |
|---|---|---|
| Free | 100 req/s | 10 req/s |
| Growth | 500 req/s | 50 req/s |
| Scale | 1,000 req/s | 100 req/s |
Every response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Retry-After | Seconds to wait (only on 429 responses) |
HTTP/1.1 429 Too Many RequestsX-RateLimit-Limit: 100X-RateLimit-Remaining: 0X-RateLimit-Reset: 1709712000Retry-After: 12Content-Type: application/json
{ "error": { "code": "rate_limited", "message": "Rate limit exceeded. Retry after 12 seconds.", "details": [] }, "request_id": "req_abc123def456"}All errors follow a consistent JSON envelope, making it straightforward to build generic error handling.
{ "error": { "code": "validation_error", "message": "Field 'email' is required.", "details": [ { "field": "email", "reason": "required", "message": "Email address must be provided for contact identification." } ] }, "request_id": "req_7x9k2m4p1n"}| Code | Meaning | When |
|---|---|---|
200 | OK | Successful read or update |
201 | Created | Resource successfully created |
400 | Bad Request | Malformed JSON or invalid parameters |
401 | Unauthenticated | Missing or invalid API key |
403 | Forbidden | Valid key but insufficient scopes |
404 | Not Found | Resource does not exist |
409 | Conflict | Duplicate resource or version conflict |
422 | Unprocessable Entity | Valid JSON but fails business logic validation |
429 | Rate Limited | Too many requests — check Retry-After |
500 | Internal Server Error | Something broke on our end — retry is safe |
All list endpoints use cursor-based pagination for consistent performance regardless of dataset size.
| Parameter | Type | Default | Description |
|---|---|---|---|
cursor | string | (none) | Opaque cursor from a previous response |
limit | integer | 25 | Number of items to return (max: 100) |
{ "data": [ { "id": "cntct_abc", "email": "alice@example.com" }, { "id": "cntct_def", "email": "bob@example.com" } ], "has_more": true, "next_cursor": "eyJpZCI6ImNudGN0X2RlZiJ9"}To fetch the next page, pass next_cursor as the cursor parameter:
GET /v1/contacts?cursor=eyJpZCI6ImNudGN0X2RlZiJ9&limit=25JavaScript SDK
Wraps both Ingest and Management APIs. Auto-batches events, handles retries, and provides TypeScript types. Works in browser and Node.js.
Web Components
Drop-in embeddable widgets for referral forms, waitlist signups, survey popups, and social proof toasts. Framework-agnostic — works with React, Vue, Svelte, or plain HTML.
Server SDKs
Node.js — available now. Python and Go — planned. All server SDKs use the Management API with secret key auth.
REST Direct
No SDK needed — call the REST API directly from any language. All endpoints accept and return JSON with standard HTTP conventions.
npm install @growthos/sdkyarn add @growthos/sdk<script src="https://cdn.growthos.io/sdk/v1/growthos.min.js"></script>import GrowthOS from '@growthos/sdk';
// Client-side — uses Ingest APIconst gos = GrowthOS.init({ writeKey: 'gos_wk_your_write_key',});
gos.identify('user_123', { email: 'alice@example.com', plan: 'growth',});
gos.track('Feature Activated', { feature: 'referral_program',});