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).
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
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).
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
5 webhooks per program hard cap; three-tier rate limiting (per-second/minute/hour) — read the response headers rather than hard-coding a ceiling.
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-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 loginSolution: 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.