---
name: sales-growsurf
description: "GrowSurf platform help — referral AND affiliate program software for SaaS and B2C product and marketing teams: JavaScript SDK + embeddable Elements, REST API (`api.growsurf.com/v2`, Bearer auth), 7 webhook events (participant, commission, payout, fraud), Stripe-native referral triggering, affiliate commissions with 1099 tax filing, anti-fraud, and 60+ native connectors (Stripe, HubSpot, Salesforce, Zapier). Use when GrowSurf referrals aren't tracking because test mode is still on or a dev URL isn't whitelisted, a Stripe referral won't fire after a customer changed their email, wiring participant or commission webhooks into a CRM, adding participants or triggering referrals via the API, the API key is locked with EMAIL_NOT_VERIFIED or rotated on first dashboard login, or picking a participant-based plan. Do NOT use for referral/affiliate strategy across tools (use /sales-affiliate-program), audience-growth tactics (use /sales-audience-growth), or comparing rival referral tools (use /sales-referralhero)."
argument-hint: "[describe what you need help with in GrowSurf]"
license: MIT
version: 1.0.0
tags: [sales, referral-program, affiliate, audience-growth, platform]
github: "https://github.com/growsurf"
---

# GrowSurf Platform Help

## Step 1 — Gather context

If `references/learnings.md` exists, read it first for accumulated platform knowledge.

1. **What are you trying to do?**
   - A) Referral vs affiliate program — which mode fits, and how they differ in data model/webhooks
   - B) Set up the REST API — base URL, Bearer auth, first request, key verification/rotation
   - C) Add participants or trigger referrals via the API (with referrer attribution)
   - D) Configure webhooks and wire participant/commission/payout events into a CRM or warehouse
   - E) Embed the referral program in-product with the JavaScript SDK + Elements
   - F) Referrals or commissions not firing in live mode (test mode, dev URL whitelist, Stripe timing)
   - G) Reward fulfillment — gift cards (Tango Card), cash (PayPal), account credits
   - H) Anti-fraud + payout holds on flagged participants
   - I) Pick a plan — participant-based Startup vs Business vs Custom
   - J) Compare GrowSurf against ReferralHero / Viral Loops / Referral Factory / ReferralKit

2. **Referral or affiliate program?** The data model and webhook events differ — commissions/payouts and 1099 filing are affiliate-only; goal/reward unlocks are referral-only.

3. **What's your stack?** Stripe (native triggering), your CRM (HubSpot/Salesforce), and whether you embed client-side (JS SDK) or drive server-side (API/webhooks).

Skip-ahead rule: if the user's prompt already contains enough context, skip to Step 2.

## Step 2 — Route or answer directly

| If the question is about... | Route to... |
|---|---|
| Referral/affiliate program *strategy* across many tools (commission rates, cookie windows, recruiting) | `/sales-affiliate-program [question]` |
| General audience-growth tactics (lead magnets, cross-promo, waitlists) | `/sales-audience-growth [question]` |
| Comparing full-stack referral tools with multi-level Level 1/2/3 + coupon groups | `/sales-referralhero [question]` |
| Turnkey viral-campaign templates (waitlist/giveaway/milestone) | `/sales-viral-loops` or `/sales-kickofflabs` |
| Deliverability of the referral/reward emails | `/sales-deliverability [question]` |

When routing, give the exact command: "This is a {domain} question — run: `/sales-{skill} {original question}`."

If the question is GrowSurf-specific, continue to Step 3.

## Step 3 — GrowSurf platform reference

**Read `references/platform-guide.md`** for the full reference — capabilities & automation surface, participant-based pricing/plan gates, integrations, data model, and quick-start recipes.

**Read `references/growsurf-api-reference.md`** for the verbatim REST API — authentication (Bearer, `EMAIL_NOT_VERIFIED` gate, key rotation), base URL (`https://api.growsurf.com/v2`), the full endpoint list (Accounts, Campaigns, Participants, Rewards, Referrals/Invites, Analytics, Commissions/Payouts, Webhooks), three-tier rate limiting, and the 7 webhook events with payload gotchas.

Answer using only the relevant section. Don't dump the full reference.

## Step 4 — Actionable guidance

Focus on the user's specific situation and apply these:

- **"Referrals/commissions aren't firing in live mode" → check test mode is OFF first.** If test mode was left enabled when the campaign went live, referrals and commissions will NOT be generated in live mode. This is the single most common cause — rule it out before anything else.
- **Stripe email-change race:** if a Stripe customer changes their email and then pays, allow at least **a few minutes between the two events** or the referral trigger won't register. Tell users to space these out (or re-trigger) rather than expecting instant attribution.
- **Whitelist dev/localhost URLs.** Referral tracking won't fire from an un-whitelisted environment — when testing from `localhost` or a staging domain, add the URL to the campaign's allowed URLs first. Also test **each** signup entry point separately (inline form AND popup) — attribution can work on one and silently miss another.
- **Never call the API "free."** The REST API/webhooks require an **active paid subscription** (referral) or a **valid payment method on file** (affiliate). Confirm the account qualifies before recommending API-driven recipes.
- **API basics:** `https://api.growsurf.com/v2`, header `Authorization: Bearer <key>`. The key is **locked until email verification** (`EMAIL_NOT_VERIFIED_ERROR` on non-Accounts endpoints) and **rotates on first dashboard login** — re-read it from Account settings if you scripted creation. Attribute referrals by passing `referredBy` on `POST /campaign/{id}/participant`; omitting it makes a standalone referrer, not a credited referral.
- **Webhooks:** there are 7 events — for a CRM/warehouse sync subscribe to `NEW_PARTICIPANT_ADDED` (new signups/referrals) and, on affiliate programs, `NEW_COMMISSION_ADDED` and `NEW_PAYOUT_ISSUED`. **Double-sided rewards send TWO events** (branch on `data.reward.isReferrer`), **manual-approval rewards fire the event TWICE** (pending, then approved), and `CAMPAIGN_ENDED` caps at the first 1,000 winners. Dedupe on ids, respond 2xx fast (GrowSurf retries with backoff for days), and — since there's **no documented HMAC** — keep the URL secret and re-verify via `GET` before any payout.
- **Present pricing as best-effort and participant-based** (prorated by participant count; Startup/Business/Custom) and point to `growsurf.com/pricing` — do not quote exact prices as current.
- **When comparing to rivals,** note GrowSurf's edge is *in-product embed (JS SDK/Elements) + referral AND affiliate in one, with Stripe-native triggering and 1099 filing* — but hand cross-tool selection to `/sales-affiliate-program` or `/sales-referralhero`.

If you discover a gotcha, workaround, or tip not covered in `references/learnings.md`, append it there.

## Gotchas

> *Best-effort from research (2026-07) — review these, especially plan-gated features and integration details that may shift.*

1. **Test mode left on = nothing fires in live mode.** Referrals and commissions are not generated in live mode while test mode is enabled. Always confirm test mode is OFF at go-live.
2. **API is not free.** Startup lists API/webhooks, but the docs gate the REST API to referral users on an active paid subscription and affiliate users with a payment method on file. Don't promise programmatic workflows to an unqualified account.
3. **API key gates + rotation.** The key stays locked with `EMAIL_NOT_VERIFIED_ERROR` until the account email is verified, and it **rotates automatically on first dashboard login**. Re-read it from settings after that first login.
4. **Stripe email-change timing race.** A Stripe email change immediately followed by a payment won't register the referral — leave a few minutes between them.
5. **Dev URLs must be whitelisted** or tracking won't fire; and test every entry point (inline + popup forms) — one can work while another silently misses.
6. **Double-sided + manual-approval webhooks repeat.** Two events for referrer/referee (`isReferrer`), and the event fires twice for manual approval (pending → approved). Dedupe or you'll double-fulfill.
7. **No documented HMAC on webhooks.** Keep the URL secret, dedupe on ids, and re-verify state via `GET` before paying out. `CAMPAIGN_ENDED` only lists the first 1,000 winners.
8. **5 webhooks per program** hard cap; three-tier rate limiting (per-second/minute/hour) — read the response headers rather than hard-coding a ceiling.
9. **Referral ≠ affiliate.** Commissions, payouts, `COMMISSION_ADJUSTED` (refunds/chargebacks), and 1099 filing are affiliate-only; goal/reward unlocks are referral-only. Pick the right program mode up front.

## Related skills

- `/sales-affiliate-program` — Affiliate & referral program strategy and platform selection across tools (commission models, cookie windows, recruiting, fraud)
- `/sales-audience-growth` — Audience-growth strategy (lead magnets, cross-promotion, referral program design across platforms)
- `/sales-referralhero` — ReferralHero (full-stack referral/affiliate/waitlist/contest with multi-level Level 1/2/3 + coupon groups)
- `/sales-viral-loops` — Viral Loops (turnkey referral/waitlist/giveaway/milestone campaign templates)
- `/sales-referral-factory` — Referral Factory (no-code referral builder, qualification→due-reward API flow, native CRM syncs)
- `/sales-kickofflabs` — KickoffLabs (viral waitlists + bonus-entry giveaways + milestone rewards)
- `/sales-do` — Not sure which skill to use? The router matches any sales objective to the right skill. Install: `npx skills add sales-skills/sales --skill sales-do -a claude-code`

## Examples

### Example 1: Referrals stopped tracking after launch
**User says**: "We flipped our GrowSurf campaign live but no referrals are being recorded even though people are signing up."
**Skill does**: Rules out **test mode still enabled** first (referrals/commissions don't fire in live mode while test mode is on), then checks the signup entry points are each tracked (inline vs popup) and that non-production/dev URLs are whitelisted. If they're on Stripe, checks the email-change timing race. Points to the testing best-practices flow in the guide.
**Result**: User finds test mode was left on, switches to live, and referrals start recording; adds each entry point to their test checklist.

### Example 2: Sync new participants and commissions to the CRM via webhooks
**User says**: "How do I push every new GrowSurf participant and affiliate commission into HubSpot automatically?"
**Skill does**: Explains the webhook egress model — subscribe to `NEW_PARTICIPANT_ADDED` and `NEW_COMMISSION_ADDED` (5 webhooks/program cap), respond 2xx fast because GrowSurf retries with backoff, and **dedupe on ids** because double-sided/approval events repeat. Notes there's no documented HMAC so keep the URL secret and re-verify via `GET` before acting on payouts. Gives the Flask handler from the guide and points to native HubSpot as an alternative to hand-rolling.
**Result**: User stands up a deduping webhook listener and mirrors participants + commissions into HubSpot.

### Example 3: Add a referred participant via the API with attribution
**User says**: "Show me how to add a referred signup through the GrowSurf API and credit the referrer."
**Skill does**: Gives base URL `https://api.growsurf.com/v2`, `Authorization: Bearer <key>`, and `POST /campaign/{id}/participant` with `referredBy` set to the referrer's id/link code — warning that omitting `referredBy` creates a standalone referrer, not a credited referral. Flags the `EMAIL_NOT_VERIFIED` gate and first-login key rotation, and notes the API requires an active paid subscription.
**Result**: User makes a successful attributed `POST`, sees the referral credited, and knows to re-read the key after first dashboard login.

## Troubleshooting

### Referrals or commissions not generated in live mode
**Symptom**: Signups happen but no referral/commission is recorded after going live
**Cause**: Test mode was left enabled at launch; or the entry point/dev URL isn't tracked; or a Stripe email change immediately preceded payment
**Solution**: Confirm **test mode is OFF** (referrals/commissions won't generate in live while test mode is on). Whitelist any dev/staging URL and test each signup entry point (inline + popup). For Stripe, leave a few minutes between a customer email change and their payment. Check participant activity logs to trace where attribution dropped.

### API returns 403 `EMAIL_NOT_VERIFIED_ERROR` (or the key stopped working)
**Symptom**: Every non-Accounts endpoint 403s, or a previously working key is now rejected
**Cause**: Account email isn't verified yet, or the key **rotated on first dashboard login**
**Solution**: Verify the account email to unlock the key, then re-copy it from Account settings (`app.growsurf.com/settings#api-keys`) after the first dashboard login. Confirm the account is on an active paid subscription (referral) or has a payment method on file (affiliate) — the API is gated behind that.

### Webhook fired but the reward got fulfilled twice
**Symptom**: A referrer/referee got double-credited, or a manual-approval reward processed twice
**Cause**: Double-sided rewards send **two** events (referrer + referee); manual-approval rewards fire the event **twice** (pending, then approved)
**Solution**: Branch on `data.reward.isReferrer` to separate referrer/referee, and dedupe on the event/participant id (and approval state) so pending+approved don't both trigger fulfillment. Respond 2xx quickly and re-verify via `GET` before issuing a payout.
