Skip to main content

growth-loop-sdk

Python SDK for growth-loop.dev — Claude Code-native product analytics for vibe-coded SaaS. The Python module name is growth; the PyPI distribution is growth-loop-sdk.

Pairs with @growth-loop/mcp-server so Claude Code can ask your funnels, retention, and revenue questions directly with citations.

Install

pip install growth-loop-sdk
# or
uv add growth-loop-sdk

Requires Python 3.10+.

Quick start

import os
from growth import Growth, GrowthOptions

growth = Growth(GrowthOptions(
    api_key=os.environ["GROWTH_KEY"],
    host=os.environ.get("GROWTH_HOST", "https://api.growth-loop.dev"),
    environment=os.environ.get("APP_ENV", "production"),
    release=os.environ.get("GIT_COMMIT_SHA"),
))

# Anywhere in your app:
growth.track("signup_completed", {"plan": "pro"})

The SDK runs a background worker thread; on atexit it flushes pending events automatically. On serverless platforms (Lambda, Cloud Run) call growth.flush() before the request handler returns.

FastAPI

from fastapi import APIRouter
from growth import growth_span, growth_step
from growth_setup import growth      # the singleton from above

router = APIRouter()

@router.post("/checkout")
@growth_span(growth, "checkout", distinct_id=lambda body: body.user_id)
async def checkout(body: CheckoutBody):
    # automatically emits checkout.started / .completed / .failed
    # with duration_ms and error metadata
    return await stripe.charge(body)

@router.post("/signup")
@growth_step(growth, "signup_completed", distinct_id=lambda body: body.user_id)
async def signup(body: SignupBody):
    return await create_user(body)

Flask

from flask import Blueprint
from growth import growth_span
from growth_setup import growth

bp = Blueprint("checkout", __name__)

@bp.route("/checkout", methods=["POST"])
@growth_span(growth, "checkout", distinct_id=lambda: g.user.id)
def checkout():
    return stripe.charge(request.json)

Core API

Growth(options: GrowthOptions)

@dataclass
class GrowthOptions:
    api_key: str                       # required
    host: str = "https://api.growth-loop.dev"
    flush_interval: float = 5.0        # seconds
    batch_size: int = 50
    environment: str | None = None     # "production" | "preview" | "development"
    release: str | None = None         # git SHA — used by /diagnose for commit-level attribution
    timeout: float = 5.0               # HTTP timeout
Method What it does
track(name, properties=None, options=None) Enqueue one event. Non-blocking.
identify(IdentifyOptions(distinct_id=..., properties=...)) Set the current distinct ID + emit $identify.
set_distinct_id(id) Set the ID without emitting $identify.
flush() Force-send queued events. Always call before request returns on serverless.
shutdown() Flush + stop the worker. Called automatically on process exit.

TrackOptions

@dataclass
class TrackOptions:
    distinct_id: str | None = None     # override the client's default
    timestamp: datetime | None = None  # override the auto-set UTC now
    context: EventContext | None = None

Decorators

The three decorators auto-applied by claude /init (the MCP slash-prompt). Each preserves your function signature; types and docs flow through @functools.wraps.

@growth_span(client, name, *, properties=None, distinct_id=None)

Emits <name>.started, <name>.completed (with duration_ms), or <name>.failed (with error_message, error_name). Works on sync and async functions automatically. Use on anything > 500ms or with non-trivial failure rate.

@growth_span(growth, "ai.generate", distinct_id=lambda req: req.user_id)
async def generate(req: GenerateRequest):
    return await anthropic.messages.create(...)

distinct_id may be a literal string or a callable that receives the wrapped function's args/kwargs and returns the ID.

@growth_step(client, funnel_step, *, properties=None, distinct_id=None)

Single-event funnel marker. Drop on whatever step represents progress through your activation.

@growth_step(growth, "onboarding.invited_team")
def invite_team(team_id: str):
    ...

growth_track(client, name, properties=None)

Imperative one-off track. Equivalent to client.track(name, properties), provided for symmetry with the decorator helpers.

growth_track(growth, "pricing_viewed", {"tier": "pro"})

Recommended event taxonomy

The MCP server's /diagnose, /weekly, and /pmf prompts know these names natively:

Stage Events
Identity signup_completed, login_completed, $identify
Activation onboarding.started, onboarding.completed, first_<thing>_created
Revenue checkout_started, checkout_completed, subscription_created, subscription_canceled, payment_failed
Performance growth_span(growth, "checkout", ...), growth_span(growth, "ai.generate", ...)

Privacy

  • Never put PII (email, raw IP, full address, payment details) in properties. Use distinct_id for identity. Backend ClickHouse never decrypts or displays properties as identity.
  • ClickHouse TTL is 12 months by default — events older than that are dropped automatically.

Going deeper

The SDK is the ingest layer. The agent layer (Claude Code + MCP) is what makes growth-loop different — install the MCP server too:

claude mcp add growth-loop \
  -e GROWTH_API_KEY=pk_live_<your-key> \
  -e GROWTH_HOST=https://api.growth-loop.dev \
  -- npx -y @growth-loop/mcp-server

Then in Claude Code: /growth-init (auto-instrument), /growth-diagnose <metric>, /growth-weekly, /growth-pmf, /growth-icp, /growth-strategy, /growth-pivot.

(The growth- prefix is intentional — it keeps our prompts out of the way of Claude Code's built-in /init and any other editor's defaults.)

License

MIT

Metadata

Release files for growth-loop-sdk 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for growth-loop-sdk 0.1.6
File Size Uploaded Provenance
growth_loop_sdk-0.1.6.tar.gz 10.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for growth-loop-sdk 0.1.6
File Interpreter ABI Platform
growth_loop_sdk-0.1.6-py3-none-any.whl Python 3 none any Details

Total release size: 20.7 kB

Release files / growth_loop_sdk-0.1.6.tar.gz

Download URL growth_loop_sdk-0.1.6.tar.gz
Size 10.8 kB
Tags Source
SHA-256 checksum
How to use checksums
23c9286d19188a8bebdca67c3a548fece679e28f0014def5e46bb4f8e25e4155
BLAKE2b-256 checksum
How to use checksums
66141bae77b87a8b9e5312b49ec1a069a74d90f7440358b0a3205858ee2d179f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / growth_loop_sdk-0.1.6-py3-none-any.whl

Download URL growth_loop_sdk-0.1.6-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
959c0e2ad2bbc0b70ab1893615fd49f3cc23514da266a30108591128382e6bfc
BLAKE2b-256 checksum
How to use checksums
374cc27c3e16bb69117959947a000c4fd135ef457317b23f543260cccfe955fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Security for growth-loop-sdk 0.1.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page