# Get token Source: https://docs.cello.so/api-reference/authentication/get-token POST /token Obtain accessToken & refreshToken using your accessKeyId and secretAccessKey, or obtain a new accessToken using a refreshToken. # Send new event Source: https://docs.cello.so/api-reference/generic-events/send-event POST /events Report referral-related events such as signups, purchases, and refunds. # Introduction Source: https://docs.cello.so/api-reference/introduction Overview of Cello API for referral codes, authentication, and quickstart. ## Cello API The Cello API provides endpoints to: * Validate referral codes (`ucc`) * Retrieve active referral links * Send referral events for signups and purchases *** ## Base URLs Use the URL that matches your environment: | Environment | Base URL | | ----------- | ------------------------------- | | Sandbox | `https://api.sandbox.cello.so/` | | Production | `https://api.cello.so/` | *** ## Authentication Authenticate API requests using an `accessToken` in the Authorization header. Obtain your `accessKeyId` and `secretAccessKey` from the [Access Keys](https://portal.cello.so/integrations/accesskeys) page in your dashboard. # Get new user reward info Source: https://docs.cello.so/api-reference/new-users/get-reward GET /new-users/{productUserId}/reward Retrieve details on eligibility for the new user reward (discount) and referral information. ## Common reasons for `eligible: false` If the response is `{ "eligible": false }` even though the user has a `cello_ucc`, the most common causes are: * **No active new-user reward on the campaign** - the campaign tied to the UCC has no new-user discount configured, or the reward is inactive/expired. * **`productUserId` mismatch** - the `productUserId` you passed isn't the user who actually signed up through the referral. * **Attribution arrived after the first invoice** - `cello_ucc` was added to the customer after the first `invoice.paid`; attribution can be retroactive, but reward eligibility is still evaluated against the reward rules. * **Self-referral** - the new user signed up using their own UCC, or the signup was flagged as a [self-referral](/guides/fraud-detection) by Cello's fraud detection. Self-referrals are not eligible for new-user discounts. To verify, compare `referralUcc`, `campaignId`, and `campaignRevision` from the response (when `eligible: true`) against what you expect, and check the [Review Referrals](https://portal.cello.so/manage/reviewreferrals) section in the portal for self-referral flags. # Fetch active link Source: https://docs.cello.so/api-reference/referral-codes/fetch-active-link GET /referral-codes/active-link/{productUserId} Retrieve an active UCC and invite link for a given user to support contextual sharing. # Fetch referral code info Source: https://docs.cello.so/api-reference/referral-codes/fetch-referral-code-info GET /referral-codes/{code} Validate a referral code (UCC) and discover associated user/campaign. # Apply Discounts Source: https://docs.cello.so/attribution/apply-discounts Learn how to apply discounts to referred users when the purchase a subscription ## Implementation steps Implementing automated discounts for referred users follows a consistent pattern across all subscription platforms. Here's the complete workflow: Create discount coupons in your subscription platform (Stripe, Chargebee, Paddle, Recurly, etc.): **Platform Setup:** * Configure discounts at the plan/price level * Create multiple variations for different subscription plans: * Monthly plans: e.g., 25% off for 3 months * Annual plans: e.g., 50% off first year * Store provider coupon IDs in application configuration. You will need them later to apply the correct coupon at subscription time based on plan/price and referral status. Once you’ve set up discounts in your subscription platform, a potential next step would be to [display the discount information on your pricing or landing page](/guides/user-experience/new-user-discounts). During subscription creation, check if the new user is a Cello referral and discount needs to be assigned: * New ⭐: Use our [New User Reward API](/api-reference/new-users/get-reward) to validate the eligibility for a new user reward (discount) or * **Using Stripe or Chargebee only:** Check your Stripe/Chargebee Customer if a `cello_ucc` is present in the [**Customer Object**](https://apidocs.chargebee.com/docs/api/customers)**.** * **Using CelloAPI to track signups and Stripe/Chargebee to track purchases:** Check your Stripe/Chargebee customer if a `cello_ucc` is present in the [**Customer Object**](https://apidocs.chargebee.com/docs/api/customers) * **Cello API to track all conversion events:** Check if the new user with this id has a `cello_ucc` in your profile you stored during [signup tracking](/attribution/tracking-signups). During subscription creation, pass the determined coupon code to your subscription platform: **Required Data for Subscription:** * Plan/Price information * Coupon/discount code **Platform-Specific Application:** * **Stripe**: Use `discounts` array or `coupon` parameter on Checkout Session * **Chargebee**: Apply `coupon_ids` on Subscription or via Hosted Pages (not at customer creation) ### Key Implementation Notes * **Timing**: Discounts must be applied during initial subscription creation, not afterward * **Validation**: Always verify the user is eligible for referral discounts * **Fallback**: Handle cases where discount codes are invalid or expired * **Configuration**: Maintain an application-level mapping of coupon IDs to plan type and referral status so the correct coupon can be applied at subscription time ## Stripe implementation Stripe offers flexible discount mechanisms through **coupons**. For referral discounts, apply coupons during Subscription creation or Checkout. You cannot attach discounts at customer creation. ### Overview There are two ways to apply coupons in Stripe, depending on your integration style: * Server-side Subscription API (apply during `subscriptions.create`) - best for custom UIs. See [Stripe documentation](https://stripe.com/docs/billing/subscriptions/discounts). * Prebuilt Checkout Session (apply during `checkout.sessions.create`) - best for hosted checkout. See [Stripe documentation](https://stripe.com/docs/payments/checkout/discounts). Stripe's discount system works through: * **Coupons**: Define the discount structure (percentage, duration, limits) * **Application methods**: Apply coupons to Subscriptions or Checkout Sessions Set up discount coupons for your referral program: **Via Stripe Dashboard:** 1. Go to [Stripe Dashboard > Coupons](https://dashboard.stripe.com/coupons) 2. Click "Create coupon" 3. Configure discount parameters: * **Name**: e.g., `Referral Discount - Monthly 25%` * **Type**: Percentage * **Percent off**: 25% * **Duration**: Repeating (3 months) * After creation, store the returned coupon ID in your config **Via Stripe API:** ```javascript theme={null} const stripe = require('stripe')('sk_live_...'); const coupon = await stripe.coupons.create({ name: 'Referral Discount - Monthly 25%', percent_off: 25, duration: 'repeating', duration_in_months: 3, metadata: { campaign_type: 'user-referrals', plan_type: 'monthly' } }); // Save coupon.id to your configuration ``` ```javascript theme={null} const subscription = await stripe.subscriptions.create({ customer: user.customerId, items: [{ price: 'price_monthly_plan' }], discounts: [{ coupon: couponId }] }); ``` ### Handle checkout sessions with discounts For Stripe Checkout, include discounts in session creation: ```javascript theme={null} const session = await stripe.checkout.sessions.create({ mode: 'subscription', line_items: [{ price: 'price_monthly_plan', quantity: 1 }], customer: user.customerId, discounts: [{ coupon: couponId }], success_url: 'https://yoursite.com/success', cancel_url: 'https://yoursite.com/cancel' }); ``` The Stripe UI automatically displays the discount during checkout: Stripe checkout with discount visualization ### Manual discount application (not recommended) For testing or special cases, you can manually attach coupons on a Subscription in the Stripe Dashboard: 1. Navigate to the subscription in [Stripe Dashboard](https://dashboard.stripe.com/subscriptions) 2. Click **Update subscription** → **Add coupon** 3. Select the appropriate referral coupon Stripe Console apply coupon action Manual application is not scalable for automated referral programs. Use the API methods above for production implementations. ## Chargebee implementation Chargebee uses **coupons** to apply discounts on subscriptions. For referral discounts, apply coupons during subscription creation or via Hosted Pages. ### Overview There are two ways to apply coupons in Chargebee: * Subscription API (apply during `subscription.create`) - for server-side subscription creation. See [Chargebee documentation](https://apidocs.chargebee.com/docs/api/subscriptions?prod_cat_ver=2#create_a_subscription). * Hosted Pages (apply via `coupon_ids` during checkout) - for provider-hosted checkout. See [Chargebee documentation](https://apidocs.chargebee.com/docs/api/hosted_pages?prod_cat_ver=2#checkout_new_subscription). Chargebee's discount system works through: * **Coupons**: Define discount rules (percentage, amount, duration) * **Application methods**: Apply to subscriptions or via Hosted Pages Set up discount coupons for your referral program: **Via Chargebee Dashboard:** 1. Go to [Chargebee Dashboard > Coupons](https://www.chargebee.com/docs/2.0/coupons.html#creating-coupons) 2. Click "Create Coupon" 3. Configure discount parameters: * **Coupon Name**: e.g., `Referral Discount - Monthly 25%` * **Discount Type**: Percentage * **Discount**: 25% * **Duration Type**: Limited Period (3 months) * After creation, store the coupon ID in your config **Via Chargebee API:** ```javascript theme={null} const chargebee = require('chargebee'); chargebee.configure({ site: 'your-site', api_key: 'your-api-key' }); const coupon = await chargebee.coupon.create({ id: 'YOUR_COUPON_ID', name: 'Referral Discount - Monthly 25%', discount_type: 'percentage', discount_percentage: 25, duration_type: 'limited_period', period: 3, period_unit: 'month' }); ``` ```javascript theme={null} const subscription = await chargebee.subscription.create({ customer_id: user.id, plan_id: 'monthly_plan', coupon_ids: [couponId] }); ``` ### Handle Hosted Pages with discounts For Chargebee Hosted Pages, include coupons in checkout URLs: ```javascript theme={null} const hostedPage = await chargebee.hosted_page.checkout_new({ subscription: { plan_id: 'monthly_plan', coupon_ids: [couponId] }, customer: { id: user.id, email: user.email } }); // Redirect user to hostedPage.url ``` ## Cello API integration (for other platforms) If you use another billing platform (for example, Paddle, Recurly, Braintree) or a home-grown system, follow the same general approach described above: 1. Create and manage coupons/discounts in your billing system. 2. Keep an application-level mapping of coupon IDs by plan and referral status. 3. Apply the correct coupon at subscription/checkout creation time. # Mobile Signup Flow Source: https://docs.cello.so/attribution/for-mobile Learn how to set up mobile app referral attribution This guide explains how to add referral tracking capabilities to your existing attribution links without creating new ones. In this guide, we'll use Branch.io as an example. The implementation is similar if you use other attribution libraries like [AppsFlyer](https://www.appsflyer.com/), [Singular](https://www.singular.net/) or [Adjust](https://www.adjust.com/). Mobile attribution builds on top of [web attribution](/attribution/for-web) since users typically click referral links on web before downloading your app. The web setup captures the initial referral code that will later be attributed to the mobile app installation and signup. ## Overview The referral flow works as follows: * Existing user shares their unique referral link * New user clicks the link and is directed to your landing page * User then clicks on AppStore or Google Play app download * New user installs and opens the app * App receives referral data and attributes the installation * Backend records the referral during signup ## Basic Concept Instead of creating new links for each referrer, you'll append referral data to your existing Branch.io (or other attribution library) app install link: ```html theme={null} Original: https://yourbrand.app.link/abc123 With Referral: https://yourbrand.app.link/abc123?referral_ucc=A1B2C ``` ## Data Persists Through Installation When a user clicks the referral link, Branch.io stores the referral data (including the referral\_ucc) in their servers and associates it with the user's device fingerprint. This allows the data to persist through: * App Store redirect * App download * First app launch ## Data Flow Sequence #### Link Click ```html theme={null} https://yourbrand.app.link/abc123?referral_ucc=A1B2C ↓ Branch.io captures and stores: - referral_ucc: A1B2C - Device fingerprint - Click timestamp ``` #### App Installation ```html theme={null} User installs app from store ↓ Branch SDK initializes on first launch ↓ Branch matches device to stored click data ↓ Delivers referral data to app ``` ## Accessing Referral Data in Your App #### iOS Implementation ```swift theme={null} import Branch class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Branch.getInstance().initSession(launchOptions: launchOptions) { (params, error) in // Check if the user came from a Branch link if let clickedBranchLink = params?["+clicked_branch_link"] as? Bool, clickedBranchLink { // Extract referral code if let referralCode = params?["referral_ucc"] as? String { print("Referral Code: \(referralCode)") // Store for use during signup UserDefaults.standard.set(referralCode, forKey: "pending_referral_code") } } } return true } } ``` #### Android Implementation ```kotlin theme={null} class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Branch.getAutoInstance(this).initSession({ branchUniversalObject, linkProperties, error -> if (error == null) { // Check if user came from Branch link if (linkProperties?.has("+clicked_branch_link") == true) { // Get referral code val referralCode = linkProperties.get("referral_ucc") referralCode?.let { Log.d("Branch", "Referral Code: $it") // Store for signup getSharedPreferences("app_prefs", Context.MODE_PRIVATE) .edit() .putString("pending_referral_code", it) .apply() } } } }, this.intent.data, this) } } ``` #### React Native Implementation ```javascript theme={null} import branch from 'react-native-branch'; function DeepLinkHandler() { useEffect(() => { // Handle deep link when app is already running const subscription = branch.subscribe({ onNewIntent: ({ error, params, uri }) => { if (error) { console.error('Branch link error:', error); return; } if (params['+clicked_branch_link']) { handleDeepLink(params); } } }); return () => subscription(); }, []); const handleDeepLink = async (params) => { const referralCode = params.referral_ucc; if (referralCode) { await AsyncStorage.setItem('pending_referral_code', referralCode); // Handle navigation or other logic based on deep link } }; return null; } ``` ## Using the Referral Data During Signup When the user completes signup, retrieve the stored referral code and include it in your signup API call: #### iOS Implementation ```swift theme={null} // iOS Example class SignupViewController: UIViewController { func completeSignup(email: String, password: String) { // Get stored referral code let referralCode = UserDefaults.standard.string(forKey: "pending_referral_code") // Include in signup API call let signupData = [ "email": email, "password": password, "referral_code": referralCode ] api.signup(signupData) { result in if result.success { // Clear stored referral data after successful signup UserDefaults.standard.removeObject(forKey: "pending_referral_code") } } } } ``` #### Android Implementation ```kotlin theme={null} // Android Example class SignupActivity : AppCompatActivity() { private fun completeSignup(email: String, password: String) { val prefs = getSharedPreferences("app_prefs", Context.MODE_PRIVATE) val referralCode = prefs.getString("pending_referral_code", null) val signupData = HashMap().apply { put("email", email) put("password", password) referralCode?.let { put("referral_code", it) } } api.signup(signupData) { success -> if (success) { // Clear stored referral data prefs.edit().remove("pending_referral_code").apply() } } } } ``` #### React Native Implementation ```javascript theme={null} function SignupScreen({ navigation }) { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleSignup = async () => { try { const referralCode = await AsyncStorage.getItem('pending_referral_code'); const response = await api.signup({ email, password, referral_code: referralCode }); if (response.success) { await AsyncStorage.removeItem('pending_referral_code'); navigation.navigate('Home'); } } catch (error) { console.error('Signup error:', error); } }; return ( // Your signup form JSX ); } ``` # Web Signup Flow Source: https://docs.cello.so/attribution/for-web Learn how to capture referral codes on your website When users click referral links, they land on your website first. Capture the referral code (`ucc`) on this landing page to properly attribute future conversions. Follow these steps to set up referral code capture: ## Step 1: Set up your landing page Create a landing page for referral traffic. Choose one approach: * Dedicated referral landing page * Home page with Cello New User Banner See the [landing page optimization guide](/guides/user-experience/optimizing-landing-pages) for best practices. ## Step 2: Install attribution script The attribution script detects the `ucc` query parameter and stores it as a first-party cookie for later attribution of conversion events. Install the Cello attribution script - [Attribution JS](/sdk/client-side/attribution-js-introduction) - using one of these methods: The attribution script also enables you to: * Fetch referrer names for [landing page personalization](/guides/user-experience/personalizing-referrals) * Get campaign parameters to [display discounts](/guides/user-experience/new-user-discounts) * Attach `ucc` to signup forms See the [Attribution JS reference](/sdk/client-side/attribution-js-introduction) for complete details. ## Step 3: Verify installation Verify that the `ucc` is available on your signup page: 1. Test your website with these query parameters: ```html theme={null} https://yourwebsite.com/?productId=test&ucc=test ``` 2. Verify these values are saved as cookies: `cello-product-id` and `cello-referral` 3. On your signup page, test `ucc` access from the browser console: ```javascript theme={null} window.CelloAttribution('getUcc') ``` Expected response: ```javascript theme={null} Promise {: 'test'} ``` If this test passes, the script is installed correctly. **Using referral codes at signup** Use `getUcc()` during user signup to retrieve the referral code, then pass it in the [signup event](/attribution/tracking-signups) to Cello. For complex flows, save the `ucc` with your user record so it's available when sending [signup events](/attribution/tracking-signups). # HubSpot Forms Source: https://docs.cello.so/attribution/hubspot Integrate the Cello attribution library with HubSpot forms to track referral conversions ## Overview This guide shows you how to capture referral codes (`ucc`) from visitors and automatically populate them into HubSpot forms when users submit lead generation or contact forms. This enables you to track which referrals lead to qualified leads and conversions. ## Considerations when creating the `ucc` property in HubSpot When creating a custom property in HubSpot, it is important that the internal name of the property is `ucc`. This sets up the property in either company or deal. The one to choose depends on your specific sales process and the corresponding HubSpot setup. These instructions describe creating the `ucc` property in the object type **Company**, group **Company information**. Often, it can make sense to create the `ucc` property in the **Deal** object type. A custom property can be created following the instructions of HubSpot [here](https://knowledge.hubspot.com/properties/create-and-edit-properties). ## Step 1: Create a form with a hidden `ucc` field in HubSpot To properly capture referral data, you need to add a `ucc` field to your HubSpot form: 1. Create a customized form in HubSpot by following the instructions [here](https://knowledge.hubspot.com/forms/create-forms). 2. In your form, create a hidden field called `ucc`. This field automatically picks up the `ucc` from the link and feeds it into the create `ucc` property in HubSpot. The result should look like this: Cello Attribution Capture UCC HubSpot deal with Hubspot Form ## Step 2: Include the Cello Attribution Library Add the Cello attribution script to your website's `` section or before the closing `` tag: ```html theme={null} ``` ## Step 3: Add the Attribution Command Queue Since HubSpot forms are loaded dynamically, include this script to handle race conditions between your code and the Cello library loading: ```html theme={null} ``` **Important:** This script must be added before any calls to `window.CelloAttribution()` to prevent race conditions. ## Step 3: Integrate with HubSpot Form Creation When creating your HubSpot form, use the `onFormReady` callback to populate the referral code. Replace the placeholder values with your actual HubSpot configuration: ```javascript theme={null} hbspt.forms.create({ region: "AAA", // Replace with your HubSpot region (e.g., "na1") portalId: "BBB", // Replace with your HubSpot Portal ID formId: "CCC", // Replace with your HubSpot Form ID onFormReady(form, ctx) { window.CelloAttribution('getUcc').then((celloUcc) => { console.log('Incoming Referral:', celloUcc); // Find all ucc fields and populate them document.querySelectorAll('input[name="ucc"]').forEach( el => { el.value = celloUcc; } ); }).catch((error) => { console.log('No referral code found or error occurred:', error); }); } }); ``` ## Test Your Implementation ### 1. Test Referral Code Capture 1. Visit your page with a referral parameter: ``` https://yoursite.com/landing-page?ucc=test123&productId=yourproduct ``` 2. Open browser developer tools and check: ```javascript theme={null} // Test if ucc is available window.CelloAttribution('getUcc') ``` Expected response: `Promise {: 'test123'}` ### 2. Test Form Integration 1. Open the page with the created form 2. Add `?ucc=demo12345687` to the link and reload the page. After the initialization of the config, this will be added automatically to the link by Cello 3. Enter some test data into the form. The result should look similar to the following Cello Attribution Capture UCC HubSpot deal with Hubspot Form 4. Submit your HubSpot form 5. HubSpot should now have created a new contact and a new company. In the new company, you should find the `ucc` property filled with the entered value `demo12345687` 6. The test was successful. You can now move ahead to the section on providing the required data to Cello. Cello Attribution Capture UCC HubSpot deal with Hubspot Form ## Troubleshooting ### Common Issues and Solutions **1. "getReferral is not supported" error** * Make sure you're using `getUcc()` instead of `getReferral()` * This is the correct method for the latest attribution library **2. Form fields not getting populated** * Verify your form has a field with `name="ucc"` * Check that the field selector in `querySelectorAll()` matches your form * Ensure the `onFormReady` callback is executing **3. Referral code is undefined** * Test with a URL containing the `ucc` parameter: `?ucc=test123` * Check browser cookies for `cello-referral` * Verify the attribution script loaded properly **4. Script loading order issues** * Always include the command queue script before any attribution calls * Use the `async` attribute on the attribution library script ## HubSpot Scheduling Pages Integration You can also use the Cello attribution library with HubSpot scheduling pages to capture referral codes when prospects book meetings or demos. This is particularly useful for sales-led referral programs where referrals often lead to booked consultations or product demos. ### How it works HubSpot scheduling pages include built-in forms that collect contact information before allowing visitors to book meetings. You can integrate Cello attribution with these forms using the same approach as regular HubSpot forms. ### Setup Steps The integration process for scheduling pages is identical to regular forms: 1. Include the Cello Attribution Library (Steps 2-3 above remain the same) 2. Set up the `ucc` property in your HubSpot contacts/companies 3. Add a hidden `ucc` field to your scheduling page form 4. Configure the scheduling page to populate the referral code ### Adding `ucc` Field to Scheduling Pages 1. Create or edit a scheduling page ([HubSpot's scheduling page guide](https://knowledge.hubspot.com/meetings/create-scheduling-pages)) 2. In the "Form" section, add the created `ucc` parameter to the form. You can't hide this field on a scheduling page. This field automatically picks up the `ucc` parameter from the link and feeds it into the created `ucc` property in HubSpot. The result should look like this: Cello Attribution Capture UCC HubSpot deal with Hubspot Form ### JavaScript Integration for Scheduling Pages Since scheduling pages are embedded HubSpot components, you'll add the same integration code to the page where your scheduling page is embedded: ```html theme={null} ``` ### Testing Your Scheduling Page Integration 1. Visit your scheduling page with a referral parameter: ``` https://yoursite.com/book-demo?ucc=demo12345687 ``` 2. Start the booking process and fill out the form 3. Complete the booking 4. Check the created contact in HubSpot - the `ucc` field should contain `demo12345687` ### Key Differences from Regular Forms * **Timing**: Scheduling pages load asynchronously, so we use MutationObserver to detect when the form is ready * **Form structure**: Scheduling page forms are embedded HubSpot components with specific styling * **Optional field**: Make the `ucc` field optional since not all meeting bookings will come from referrals * **Meeting context**: The referral code will be associated with the contact and any resulting deals from the meeting **For sales-led businesses**: Integrating referral tracking with scheduling pages is crucial for tracking which referrals lead to qualified sales conversations and ultimately closed deals. # Introduction Source: https://docs.cello.so/attribution/introduction Learn how to implement referral attribution to track signups and purchases back to their original referrers Referral conversion enables you to track and attribute user signups and purchases back to their original referrers and reward them for conversions. Cello helps you capture referral codes `ucc` from landing pages and maintains attribution throughout the entire user journey, from initial visit to final purchase. # How it works The referral conversion process follows a four-step attribution flow: Cello Referral conversion process four-step attribution flow overview diagram 1. **Referral Link Sharing** - Referrers share links containing unique codes (`ucc` parameters) 2. **Landing Page Capture** - Your website captures and stores referral codes `ucc` as first-party cookies 3. **Signup Tracking** - New user registrations are linked to their referrer 4. **Purchase Tracking** - Revenue events are attributed back to the original referrers Accurate referral conversion tracking depends on properly passing the referral code `ucc` through each step of the referral journey. **Attribution based on organization level** If the buying persona is the organization and you want to attribute purchases on the organization level always provide the **ID of the organization** in the parameter `payload.newUserId` # Getting started with referral conversion tracking Learn how to track conversions with Cello in the following resources: Capture referral code during web signup flow Capture referral code during mobile signup A full guide on tracking signup events A full guide on tracking purchase events or choose a step-by-step quickstart guide for your integration scenario: # Track Purchases Source: https://docs.cello.so/attribution/tracking-purchase Learn how to track purchase events with Cello To complete the conversion tracking and reward referrers, you will need to send Cello purchase events. A purchase event is sent when a user pays for a subscription or a product. After sending purchase events, check [Integration Status](/guides/support/portal/integration-status) to confirm Purchases tracking is **Connected**. For per-event detail and to troubleshoot any field validation errors, open the [Event Feed](https://portal.cello.so/integrations/events-feed) in the Cello Portal. # Prerequisites Before you can send Cello purchase events, make sure you are already: * [Capturing referral code on your landing page](https://docs.cello.so/attribution/for-web) * [Tracking signups](https://docs.cello.so/attribution/tracking-signups) **Attribution based on organization level** If the buying persona is the organization and you want to attribute purchases at the organization level, always provide the **ID of the organization** in the parameter `payload.newUserId` If you are providing discounts to new users, they need to be [applied at the point of creating a subscription](/attribution/apply-discounts) in your subscription platform # Track purchase events with Webhooks Depending on which payment gateway you’re using, we offer webhooks for the following: } href="/integrations/webhooks/stripe-webhook" > Send events using Stripe Webhook } href="/integrations/webhooks/chargebee-webhook" > Send events using Chargebee Webhook # Track purchase events with Cello API If you’re not using any of the gateways listed above, you can also send purchase events using Cello API `POST /events` API endpoint. Here are the 2 events you will need to send: ## `invoice-paid` This event is sent every time a transaction based on the provided subscription is successful or a new user buys a one-time plan, a license or something similar. ```bash theme={null} POST https://api.cello.so/events { "eventName": "ReferralUpdated", "payload": { "ucc": "cello-ucc", "newUserId": "new-user-product-user-id", // or 'new-user-organization-id' "price": 100, "currency": "EUR" }, "context": { "newUser": { "id": "new-user-product-user-id", "email": "new-user@gmail.com", "organizationId": "new-user-organization-id" }, "event": { "trigger": "invoice-paid", "timestamp": "2022-10-05 14:14:34" }, "subscription": { "invoiceId": "34hsjdh34jfksd", "interval": "one-time", "productKey": "Pro License" } } } ``` Here are the properties you can include when sending a `invoice-paid` event: | Property | Required | Description | | ------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ucc` | yes | A referral code (`ucc`) identifying the referrer. You can retrieve this code using [attribution script](/sdk/client-side/attribution-js-introduction) `getUcc ()` method, you have installed as a prerequisite to this guide | | `newUserId` | yes | A unique ID in your system, identifying the **new user** who just signed up. Can also be **organization ID**, if your referrers can refer organizations and you want to **reward them for organization account expansion** | | `price` | yes | Amount on the invoice | | `currency` | yes | Currency of the amount | | `newUser.id` | yes | A unique ID of the new user (not the organization, if you are rewarding on organization level). This should be the same ID (`productUserId`) you will use to boot the [Referral component](/referral-component/introduction), when this user logs into your app | | `newUser.email` | yes | New user email | | `newUser.organizationId` | no | Organization ID. Add this field if your referrers can **refer an organization** and you want to reward them for **organization account expansion** | | `event.trigger` | yes | `invoice-paid` | | `event.timestamp` | yes | Event timestamp in **ISO8601 format** | | `subscription.invoiceId` | yes | ID of the invoice that was paid or refunded | | `subscription.interval` | yes | Interval of the payment. Available options: `one-time`, `weekly`, `bi-weekly`, `monthly`, `quarterly`, `semi-annual`, `yearly`, `biennial`, `triennial`, `lifetime` | | `subscription.productKey` | yes | Name of the product or plan purchased | Full API referrence for `POST /events` API endpoint can be found [here](/api-reference/generic-events/send-event). ## `charge-refunded` This event is sent if the payment of the new user was refunded. When Cello receives this event, it automatically cancels any pending reward for that transaction. ```bash theme={null} POST https://api.cello.so/events { "eventName": "ReferralUpdated", "payload": { "ucc": "cello-ucc", "newUserId": "new-user-product-user-id", // or 'new-user-organization-id' "price": 1000, "currency": "EUR" }, "context": { "newUser": { "id": "new-user-product-user-id", "email": "new-user@gmail.com", "organizationId": "new-user-organization-id" }, "event": { "trigger": "charge-refunded", "timestamp": "2022-10-05 14:14:34" }, "subscription": { "invoiceId": "34hsjdh34jfksd" } } } ``` Here are the properties you can include when sending a `charge-refunded` event: | Property | Required | Description | | ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ucc` | yes | A referral code (`ucc`) identifying the referrer. You can retrieve this code using [attribution script](/sdk/client-side/attribution-js-introduction) `getUcc ()` method, you have installed as a prerequisite to this guide | | `newUserId` | yes | A unique ID in your system, identifying the **new user** who just signed up. Can also be **organization ID**, if your referrers can refer organizations and you want to **reward them for organization account expansion** | | `price` | yes | Amount refunded | | `currency` | yes | Currency of the amount | | `newUser.id` | yes | A unique ID of the new user (not the organization, if you are rewarding on organization level). This should be the same ID (`productUserId`) you will use to boot the [Referral component](/referral-component/introduction), when this user logs into your app | | `newUser.email` | yes | New user email | | `newUser.organizationId` | no | Organization ID. Add this field if your referrers can **refer an organization** and you want to reward them for **organization account expansion** | | `event.trigger` | yes | `charge-refunded` | | `event.timestamp` | yes | Event timestamp in **ISO8601 format** | | `subscription.invoiceId` | yes | ID of the invoice that was paid or refunded | Full API referrence for `POST /events` API endpoint can be found [here](/api-reference/generic-events/send-event). # Track Signups Source: https://docs.cello.so/attribution/tracking-signups Learn how to track signup events with Cello When a referee signs up or otherwise shows interest in your product - like booking or attending a demo - you need to send this event to Cello. This allows Cello to attribute this conversion to the referrer, so they can be rewarded if a purchase happens later. You can also choose to reward users for actions like signups or demos by configuring this in your [Campaign settings](/guides/campaigns/setting-up-campaigns). After sending signup events, check [Integration Status](/guides/support/portal/integration-status) to confirm Signups tracking is **Connected**. For per-event detail and to troubleshoot any field validation errors, open the [Event Feed](https://portal.cello.so/integrations/events-feed) in the Cello Portal. # Prerequisites Before you can send Cello signup events, you need to make sure that you are able to **capture the referral code** `ucc`**during signup or demo booking**: * [When users sign up in your web app](/attribution/for-web) * [When users sign up in your mobile app](/attribution/for-mobile) * When users book a demo using [Hubspot](/attribution/hubspot) or [Typeform](/attribution/typeform) forms or scheduling **Attribution based on organization level** If the buying persona is the organization and you want to attribute purchases at the organization level, always provide the **ID of the organization** in the parameter `payload.newUserId` # Tracking signup events For a SaaS application signup flow, you will track a signup event or equivalent. Depending on how you create a new user and which payment gateway you are using, you can choose from the following options to send Cello signup events. ## Option 1: Using Stripe - I create Stripe Customer at Signup Use this option if your payment gateway is Stripe and you **create a Stripe customer at signup** To track a signup, you can pass the following `metadata` to Stripe [Customer Object](https://docs.stripe.com/api/customers/object?api-version=2024-09-30.acacia#customer_object-metadata) on customer creation. * `cello_ucc` - ucc, a referral code identifying the referrer. You can retrieve this code using [attribution script](https://docs.cello.so/sdk/client-side/attribution-lib) `getUcc ()` method, you have installed as a prerequisite to this guide. * `new_user_id` - a unique user ID in your system, identifying the new user who just signed up. This should be the same ID (`productUserId`) you will use to boot the [Referral component](https://docs.cello.so/sdk/client-side/cello-js), when this user logs into your app * `new_user_organization_id` (optional) - add this, if your referrers can refer an organization rather then a single user and you want to reward based on that. Modify customer fields you send upon customer creation. Here is an example for a NodeJS App that does that: ```javascript theme={null} const stripe = require('stripe')('sk_test_51KiCYYCSMQAUBF...'); const customer = await stripe.customers.create({ description: 'New Stripe Customer', metadata: { cello_ucc: "hdz7afhs7", new_user_id: "xcsdad", // product user id of the new user new_user_organization_id: "123456" // organization id of the new user } }); ``` Now that the customer is created in Stripe with Cello metadata, a `customer.created` event will be sent with [Stripe Webhook](/integrations/webhooks/stripe-webhook), which we will count as a signup event in Cello. ## Option 2: Using Chargebee - I create Chargebee customer at signup Use this option if your payment gateway is Chargebee and you **create a Chargebee customer at signup** You can pass the following metadata to Chargebee on customer creation. You can also choose to use **Chargebee custom fields (CF\_)** to add referral data to the event. Learn more about custom fields in the [**Chargebee documentation**](https://www.chargebee.com/docs/billing/2.0/site-configuration/custom_fields) * `cello_ucc` - ucc, a referral code identifying the referrer. You can retrieve this code using [attribution script](/sdk/client-side/attribution-js-introduction) `getUcc ()` method, you have installed as a prerequisite to this guide. * `new_user_id` - a unique user ID in your system, identifying the new user who just signed up. This should be the same ID (`productUserId`) you will use to boot the [Referral component](/referral-component/introduction), when this user logs into your app * `new_user_organization_id` (optional) - add organization ID, if your referrers can **refer an organization** and you want to reward them for **organization account expansion**. Modify customer fields you send upon customer creation. Here is an example for a NodeJS App that does that: ```javascript theme={null} var chargebee = require("chargebee"); chargebee.configure({site : "getmoonly-v3-test", api_key : "test_jqXGuQLkBHUSR2PM0qgUV21W1VqSFJIU"}); chargebee.customer.create({ first_name : "Bob", last_name : "Bobsky", //... // other customer fields //... meta_data: { cello_ucc: "hdz7afhs7", new_user_id: "xcsdad", // product user id of the new user new_user_organization_id: "123456" // organization id of the new user } // .. // }) ``` Now that the customer is created in Chargebee with Cello metadata, a `Customer Created` event will be sent with [Chargebee Webhook](/integrations/webhooks/chargebee-webhook), which we will count as a signup event in Cello. ## Option 3: Using Cello API POST /events API endpoint Use this option for all other use cases. For example: * You use Stripe or Chargebee, but customer is created in the payment gateway **at purchase**. * Your payment gateway is Paddle, Recurly or other, including in-house built payment gateways Send a `new-signup` event to the Cello API with the following values in the payload: * `ucc` - ucc, a referral code identifying the referrer. You can retrieve this code using [attribution script](/sdk/client-side/attribution-js-introduction) `getUcc ()` method, you have installed as a prerequisite to this guide. * `newUserId` - a unique ID in your system, identifying the **new user** who just signed up. Can also be **organization ID**, if your referrers can refer organizations and you want to **reward them for organization account expansion**. * `newUser.id` - unique ID of the new user (not the organization, if you are rewarding on organization level). This should be the same ID (`productUserId`) you will use to boot the [Referral component](/referral-component/introduction), when this user logs into your app * `newUser.email` - new user email * `newUser.name` - new user name * `newUser.organizationId`(optional) - add organization ID, if your referrers can **refer an organization** and you want to reward them for **organization account expansion**. Here is an example of the `POST /events` call to send a `new-signup` event: ```bash theme={null} POST https://api.cello.so/events { "eventName": "ReferralUpdated", "payload": { "ucc": "cello-ucc", "newUserId": "new-user-product-user-id", // or "new-user-organization-id" "price": 0, "currency": "" }, "context": { "newUser": { "id": "new-user-product-user-id", "email": "new_user@gmail.com", "name": "new-user-name", "organizationId": "new-user-organization-id" }, "event": { "trigger": "new-signup", "timestamp": "2022-10-05 14:14:34" } } } ``` # Tracking "demo attended" event Use this option if your product follows a sales-led model where successful conversions are driven by users attending a demo call. Send a `demo-attended` event to the Cello API with the following values in the payload: * `ucc` - ucc, a referral code identifying the referrer. You can retrieve this code using [attribution script](/sdk/client-side/attribution-js-introduction) `getUcc ()` method, you have installed as a prerequisite to this guide. * `newUserId` - a unique ID in your system, identifying the **new user** who just signed up. Can also be **organization ID**, if your referrers can refer organizations and you want to **reward them for organization account expansion**. * `newUser.id` - unique ID of the new user (not the organization, if you are rewarding on organization level). This should be the same ID (`productUserId`) you will use to boot the [Referral component](/referral-component/introduction), when this user logs into your app * `newUser.email` - new user email * `newUser.name` - new user name * `newUser.organizationId`(optional) - add organization ID, if your referrers can **refer an organization** and you want to reward them for **organization account expansion**. Here is an example of the `POST /events` call to send a `new-signup` event: ```bash theme={null} POST https://api.cello.so/events { "eventName": "ReferralUpdated", "payload": { "ucc": "cello-ucc", "newUserId": "product-user-id" // or 'new-user-organization-id' }, "context": { "newUser": { "id": "new-user-product-user-id", "email": "new-user@gmail.com", "name": "new-user-name", "organizationId": "new-user-organization-id" }, "event": { "trigger": "demo-call-attended", "timestamp": "2022-10-05 14:14:34" } } } ``` # Typeform Forms Source: https://docs.cello.so/attribution/typeform Ingest Cello's referral code (ucc) into HubSpot using Typeform forms This page guides you through the required steps to ingest **Cello's referral code (`ucc`) into HubSpot using Typeform forms**. ## Create a form with a hidden ucc field in Typeform Create a new form in Typeform On the initial question in your form, go to **Hidden Fields** via **Logic → Hidden Fields** on the panel on the right Add a new field named `ucc` and click Save Cello Capture UCC Typeform hidden fields setup ## Setup of Sync from Typeform to HubSpot Navigate to the **Connect** Section in the header of Typeform and connect HubSpot After the authorization is done, you can select the HubSpot object to which you want to sync the `ucc`. In the below example the `ucc` is synced to a deal in HubSpot. You can also sync the `ucc` to multiple objects at the same time: contact, company and deals. If you sync the `ucc` to a deal, you have to specify in which pipeline at which stage the deals should be created After finalizing the setup of the integration, save the settings and run a short test run Cello Capture UCC Typeform HubSpot integration setup ## Test the created Typeform and HubSpot integration Open the created Typeform Add either `?ucc=12341234` or `&ucc=12341234` to the link depending on if there is already a "?" present in the link Cello Capture UCC Typeform URL with UCC parameter Submit the Typeform Open HubSpot and check that the contact, company or deal was created and the `ucc` was synced correctly Cello Capture UCC Typeform HubSpot deal with UCC ## Further hints You can also embed a Calendly in Typeform to allow customers to schedule e.g. a demo from the Typeform. Documentation can be found [here](https://www.typeform.com/connect/calendly/). # Chargebee Webhook Quickstart Source: https://docs.cello.so/attribution/use-cases/chargebee Learn how to integrate Cello if you are using Chargebee JS to create Chargebee customer and Chargebee Webhook to send Cello conversion events. This guide is **optimized for the typical freemium scenario with Chargebee**. Use this guide if you: * Create Chargebee customer on signup * Use Chargebee webhook to send Cello referral conversion events # Step 1: Integrate the Referral Component First, integrate Cello Referral Component into your web app to provide referrers with full referral experience. Referral Component is integrated using one of our SDKs. For your web app, use Cello JS - our client-side SDK. You can install it by: 1. Adding a script tag to the `` of your application 2. Generating a JWT token for user authentication 3. Booting the component with the provided token and user details Follow this installation guide: You can also integrate Referral Component into your mobile applications: # Step 2: Capture referral codes on landing page Next, you will need to add [Cello attribution script](https://docs.cello.so/sdk/client-side/attribution-lib) to your referral landing page: 1. Setup a [landing page](https://docs.cello.so/docs/optimize-landing) for your referral links to redirect to 2. Install attribution script. Choose one of the following installation options best suited for your setup: 3. Verify the installation To verify, follow these steps: 1. Add `?productId=test` and `?ucc=test` to your website URL ```html theme={null} https://yourwebsite.com/?productId=test&ucc=test ``` 2. Make sure that these values are saved in the cookies as `cello-product-id` and `cello-referral` 3. Navigate to your signup page and try to access the ucc using the `getUcc()` method from the browser console ```javascript theme={null} window.CelloAttribution('getUcc') ``` This method should return a promise with value `test` ```javascript theme={null} Promise {: 'test'} ``` **If this check passes, the script is installed correctly.** For capturing referral code in your mobile signup flow, follow this guide: # Step 3: Add Cello metadata or custom fields on Chargebee customer creation To track a signup, you can pass the following metadata to Chargebee on customer creation. You can also choose to use **Chargebee custom fields (CF\_)** to add referral data to the event. Learn more about custom fields in the [**Chargebee documentation**](https://www.chargebee.com/docs/billing/2.0/site-configuration/custom_fields) * `cello_ucc` - ucc, a referral code identifying the referrer. You can retrieve this code using [attribution script](https://docs.cello.so/sdk/client-side/attribution-lib) `getUcc ()` method, you have installed as a prerequisite to this guide. * `new_user_id` - a unique user ID in your system, identifying the new user who just signed up. This should be the same ID (`productUserId`) you will use to boot the [Referral component](https://docs.cello.so/sdk/client-side/cello-js), when this user logs into your app * `new_user_organization_id` (optional) - add this, if your referrers can refer an organization rather then a single user and you want to reward based on that. Modify customer data you send upon customer creation. Here is an example for a NodeJS App that does that with `meta_data`: ```javascript theme={null} var chargebee = require("chargebee"); chargebee.configure({site : "getmoonly-v3-test", api_key : "test_jqXGuQLkBHUSR2PM0qgUV21W1VqSFJIU"}); chargebee.customer.create({ first_name : "Bob", last_name : "Bobsky", //... // other customer fields //... meta_data: { cello_ucc: "hdz7afhs7", new_user_id: "xcsdad", // product user id of the new user new_user_organization_id: "123456" } // .. // }) ``` Now that the customer is created in Chargebee with Cello metadata, a `Customer Created` event will be sent with [Chargebee Webhook](https://docs.cello.so/integrations/webhooks/chargebee-webhook), which we will count as a signup event in Cello. # Step 4: Connect Chargebee Webhook to send signup and purchase events To send Cello signup and purchase events, you will need to connect Chargebee Webhook to Cello. Follow this guide to connect the webhook: } href="/integrations/webhooks/chargebee-webhook" > Send events using Chargebee Webhook **Congratulations!** You are done and now able to try out the full Cello referral experience 🎉 # HubSpot + Zapier Quickstart Source: https://docs.cello.so/attribution/use-cases/hubspot-zapier Learn how to send Cello signup events from HubSpot deal stage changes using a no-code Zapier workflow. This guide is **optimized for sales-led products** where conversions are driven by demos, sales calls, or other manual qualification steps tracked in HubSpot. Use this guide if you: * Use **HubSpot** as your source of truth for deals * Want to send Cello signup events (e.g. `demo-call-attended`) **without writing any backend code** * Trigger events based on **HubSpot deal stage changes** (e.g. "Demo Done", "Qualified", "Purchase Consideration") # Overview This guide walks you through building a no-code Zapier workflow that: 1. **Watches HubSpot** for deals moving into a specific stage (e.g. "Demo Done") 2. **Filters** deals to only those with a captured `ucc` referral code 3. **Authenticates** with the Cello API to obtain an access token 4. **Sends a signup event** to Cello using the `POST /events` endpoint By the end, every qualified deal in HubSpot will automatically generate a Cello conversion event — letting you reward referrers as soon as their referee attends a demo or hits any milestone in your sales pipeline. # Prerequisites Before you start, make sure you have: * A **HubSpot account** with deals flowing through your sales pipeline * A **Zapier account** (Starter plan or above — Code by Zapier steps require a paid plan) * A **Cello account** with API credentials (`accessKeyId` and `secretAccessKey`) — generate these in the [Cello Portal](https://portal.cello.so) * A **`ucc` property** on your HubSpot deal or company object, populated when the referral lands. Follow the [HubSpot Forms attribution guide](/attribution/hubspot) to set this up. * [Cello JS Referral Component](/referral-component/quickstart) integrated in your product so referrers can share referral links If `ucc` is not being captured on your HubSpot deals, the Zap will skip every event. Complete the [HubSpot Forms attribution setup](/attribution/hubspot) first and verify with a test referral before continuing. # The completed Zap Your finished Zap will have four steps: HubSpot + Zapier flow with four steps: retrieve deal info, filter on ucc, create access token, send signup event # Step 1: Trigger on HubSpot deal stage change The Zap fires whenever a deal enters the stage you choose (typically the one that represents a qualified conversion — "Demo Done", "Purchase Consideration", or similar). 1. In Zapier, create a new Zap and choose **HubSpot** as the trigger app. 2. Pick the event **"Deal in stage"** (or "Deal Property Changed" depending on your HubSpot plan). 3. Select your **Deal Pipeline** and the **Deal Stage** that should trigger the event (e.g. `Demo Done/Purchase Consideration`). 4. Under **Additional properties to retrieve**, add the `ucc` property so it's available in later steps. HubSpot trigger configured with pipeline, deal stage, and ucc as an additional property The HubSpot trigger checks for matching deals every 15 minutes and only picks up deals moved into the stage in the **last 30 minutes**. Plan your stage transitions accordingly. Test the trigger and confirm Zapier returns a sample deal with the expected fields: `dealname`, `hs_object_id`, `ucc`, plus any contact/company info you want to forward. # Step 2: Filter deals without a `ucc` You only want to send events for deals that came from a referral. Add a **Filter by Zapier** step: 1. Choose **Filter by Zapier**. 2. Set the rule to: `1. Deal information: ucc` **Exists**. Zapier filter step: only continue if deal property ucc exists Deals without a `ucc` will stop here and no Cello event will be sent. # Step 3: Create a Cello access token Cello uses short-lived access tokens for API auth. Add a **Code by Zapier** step using Python: 1. Choose **Code by Zapier** → **Run Python**. 2. Leave **Input Data** empty (credentials are hardcoded in this step). 3. Paste the snippet below and replace `` and `` with your Cello API credentials. ```python theme={null} import json import urllib.request ACCESS_KEY_ID = "" SECRET_ACCESS_KEY = "" body = { "accessKeyId": ACCESS_KEY_ID, "secretAccessKey": SECRET_ACCESS_KEY } req = urllib.request.Request( url="https://api.cello.so/token", data=json.dumps(body).encode("utf-8"), method="POST", headers={"Content-Type": "application/json"} ) try: with urllib.request.urlopen(req, timeout=10) as resp: data = json.loads(resp.read().decode("utf-8")) output = { "access_token": data.get("accessToken"), "expires_in": data.get("expiresIn"), "status": resp.status } except urllib.error.HTTPError as e: output = { "access_token": "", "status": e.code, "error": e.read().decode("utf-8") } ``` Code by Zapier step creating a Cello access token via POST /token Test the step — you should see an `access_token` value and `status: 200` in the output. For production, store your `accessKeyId` and `secretAccessKey` in Zapier's **Storage by Zapier** or as **Code by Zapier environment variables** rather than hardcoding them. See [Zapier's guide on storing credentials](https://help.zapier.com/hc/en-us/articles/8496300064525) for details. Reference: [Cello Authentication API](/api-reference/authentication/get-token). # Step 4: Send the signup event to Cello Add a second **Code by Zapier (Python)** step that posts the event to `POST /events`. 1. Choose **Code by Zapier** → **Run Python**. 2. Map the following **Input Data** fields from the previous steps: | Input Data key | Map from | | -------------- | ----------------------------------------------------------------------------- | | `access_token` | Step 3 → `Access Token` | | `ucc` | Step 1 → `Deal information: ucc` | | `user_id` | Step 1 → `Deal information: Record ID` (or your own product user ID property) | | `email` | Step 1 → `Deal information: email_of_demo_request` (or contact email) | | `name` | Step 1 → `Deal information: Deal Name` (or contact name) | | `org_id` | Step 1 → company / organization ID (optional) | 3. Paste the snippet below: ```python theme={null} import json import urllib.request from datetime import datetime, timezone access_token = input_data.get("access_token", "") ucc = input_data.get("ucc", "") user_id = input_data.get("user_id", "") email = input_data.get("email", "") name = input_data.get("name", "") org_id = input_data.get("org_id", "") timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S") body = { "eventName": "ReferralUpdated", "payload": { "ucc": ucc, "newUserId": user_id }, "context": { "newUser": { "id": user_id, "email": email, "name": name, "organizationId": org_id }, "event": { "trigger": "demo-call-attended", "timestamp": timestamp } } } req = urllib.request.Request( url="https://api.cello.so/events", data=json.dumps(body).encode("utf-8"), method="POST", headers={ "Content-Type": "application/json", "Authorization": f"Bearer {access_token}" } ) try: with urllib.request.urlopen(req, timeout=10) as resp: response_body = resp.read().decode("utf-8") output = {"status": resp.status, "response": response_body} except urllib.error.HTTPError as e: output = {"status": e.code, "response": e.read().decode("utf-8")} ``` Code by Zapier step sending a demo-call-attended event to Cello with mapped HubSpot fields The `event.trigger` value (`demo-call-attended` in this example) determines how Cello classifies the event. Common values: * `new-signup` — user signed up but no demo yet * `demo-call-attended` — user attended a sales/demo call * `qualified-lead` — user has been qualified by sales Match the trigger to the HubSpot deal stage you're firing from. Test the step and confirm you receive `status: 200` from Cello. # Step 5: Verify and publish 1. **Publish your Zap.** 2. Move a test deal into the trigger stage in HubSpot. 3. Wait up to 15 minutes for Zapier to pick up the change. 4. Open the [Event Feed](https://portal.cello.so/integrations/events-feed) in the Cello Portal and confirm the event was received with the correct `ucc`, `newUserId`, and `trigger`. 5. Check [Integration Status](/guides/support/portal/integration-status) — **Signups** should now show as **Connected**. **You're done!** Every qualified deal in HubSpot will now generate a Cello signup event automatically. To also track purchase events, pair this with the [Stripe](/attribution/use-cases/stripe) or [Chargebee](/attribution/use-cases/chargebee) webhook integrations — or extend this Zap with an additional Code step that posts a `purchase` event when the deal closes won. # Variations * **Different trigger stages.** Duplicate the Zap and change the HubSpot deal stage + `event.trigger` value to track multiple milestones (e.g. one Zap for `demo-call-attended`, another for `qualified-lead`). * **Reward at the organization level.** Set `newUserId` to the HubSpot company ID instead of the deal/contact ID, and populate `newUser.organizationId` accordingly. See [Tracking Signups](/attribution/tracking-signups) for the organization-level attribution model. * **Use the Zapier HTTP action instead of Code steps.** If you prefer not to write Python, both API calls can be done with **Webhooks by Zapier → POST**. The body and headers are the same as in the snippets above. # Stripe Webhook Quickstart Source: https://docs.cello.so/attribution/use-cases/stripe Learn how to integrate Cello if you are using Stripe JS to create Stripe customer and Stripe Webhook to send Cello conversion events. This guide is **optimized for the typical freemium scenario with Stripe**. Use this guide if you: * Create Stripe customer on signup * Use Stripe webhook to send Cello referral conversion events # Step 1: Integrate the Referral Component First, integrate Cello Referral Component into your web app to provide referrers with full referral experience. Referral Component is integrated using one of our SDKs. For your web app, use Cello JS - our client-side SDK. You can install it by: 1. Adding a script tag to the `` of your application 2. Generating a JWT token for user authentication 3. Booting the component with the provided token and user details Follow this installation guide: You can also integrate Referral Component into your mobile applications: # Step 2: Capture referral codes on landing page Next, you will need to add [Cello attribution script](https://docs.cello.so/sdk/client-side/attribution-lib) to your referral landing page: 1. Setup a [landing page](https://docs.cello.so/docs/optimize-landing) for your referral links to redirect to 2. Install attribution script. Choose one of the following installation options best suited for your setup: 3. Verify the installation To verify, follow these steps: 1. Add `?productId=test` and `?ucc=test` to your website URL ```html theme={null} https://yourwebsite.com/?productId=test&ucc=test ``` 2. Make sure that these values are saved in the cookies as `cello-product-id` and `cello-referral` 3. Navigate to your signup page and try to access the ucc using the `getUcc()` method from the browser console ```javascript theme={null} window.CelloAttribution('getUcc') ``` This method should return a promise with value `test` ```javascript theme={null} Promise {: 'test'} ``` **If this check passes, the script is installed correctly.** For capturing referral code in your mobile signup flow, follow this guide: # Step 3: Add Cello metadata on Stripe customer creation To track a signup, you can pass the following `metadata` to Stripe [Customer Object](https://docs.stripe.com/api/customers/object?api-version=2024-09-30.acacia#customer_object-metadata) on customer creation. * `cello_ucc` - ucc, a referral code identifying the referrer. You can retrieve this code using [attribution script](https://docs.cello.so/sdk/client-side/attribution-lib) `getUcc ()` method, you have installed as a prerequisite to this guide. * `new_user_id` - a unique user ID in your system, identifying the new user who just signed up. This should be the same ID (`productUserId`) you will use to boot the [Referral component](https://docs.cello.so/sdk/client-side/cello-js), when this user logs into your app * `new_user_organization_id` (optional) - add this, if your referrers can refer an organization rather then a single user and you want to reward based on that. Modify customer fields you send upon customer creation. Here is an example for a NodeJS App that does that: ```javascript theme={null} const stripe = require('stripe')('sk_test_51KiCYYCSMQAUBF...'); const customer = await stripe.customers.create({ description: 'New Stripe Customer', metadata: { cello_ucc: "hdz7afhs7", new_user_id: "xcsdad", // product user id of the new user new_user_organization_id: "123456" // organization id of the new user } }); ``` Now that the customer is created in Stripe with Cello metadata, a `customer.created` event will be sent with [Stripe Webhook](https://docs.cello.so/integrations/webhooks/stripe-webhook), which we will count as a signup event in Cello. You will connect Stripe Webhook in the next step. # Step 4: Connect Stripe Webhook to send signup and purchase events To send Cello signup and purchase events, you will need to connect Stripe Webhook to Cello. Follow this guide to connect the webhook: } href="https://docs.cello.so/integrations/webhooks/stripe-webhook" > Send events using Stripe Webhook **Congratulations!** You are done and now able to try out the full Cello referral experience 🎉 # Cello + Claude integration Source: https://docs.cello.so/coding-apps/claude-integration How to add user referrals to your app using Cello with Claude Claude can implement Cello user referrals end-to-end if you give it the **right guide** and force it to create a plan before coding. Use **Claude Code** (the CLI coding agent) to build the integration, and connect the Cello MCP so Claude can look up docs and verify your setup as it goes. This page covers using **Claude Code** to build your referral integration. To connect the **Claude desktop or web app** so you can chat about your program, see the [Claude](/mcp/connect#claude) section of the MCP connect guide. Cello + Claude integration ## Prerequisites Before integrating Cello, ensure the following prerequisites are met: * User signup and authentication is functional * Stripe subscription flow is functional * You have a Cello account and API keys at hand. Make sure to use Cello **Sandbox environment** when developing and testing ## Optional: Connect the Cello MCP The [Cello MCP server](/mcp/introduction) gives Claude direct access to Cello's documentation, integration health checks, and best-practice recommendations. Connecting it before you start means Claude can look up the right docs itself, verify your setup as it goes, and follow best practices automatically - instead of relying only on the guide link you paste. This step is optional but recommended. The integration steps below work either way. See [Connect your client → Claude Code](/mcp/connect#claude-code) for the setup steps. ## Cello user referrals integration For a step-by-step technical implementation (source of truth + acceptance criteria), follow the detailed guide: * [React + Node.js Integration Guide](/resources/react-nodejs-integration) The guide uses React + Node.js as an example, but it can be any other combination - the steps stay the same. * Signup and authentication flow is functional * Stripe subscription flow is functional * Cello API keys are handy * Get your webhook URL from [Cello Portal](https://portal.cello.so/integrations/webhooks) * Add a Webhook endpoint in Stripe (Log into your Stripe Dashboard -> Go to Developer Mode -> Add a Webhook endpoint and enter endpoint URL -> Select the events to send -> Click "Add endpoint") * Secure the Webhook with "Signing secret" Events to send: * `charge.refunded`, `charge.succeeded`, `charge.updated` * `customer.created`, `customer.deleted`, `customer.updated` * `customer.subscription.created`, `customer.subscription.deleted`, `customer.subscription.updated` * `invoice.paid` See [Stripe Webhook Integration](/integrations/webhooks/stripe-webhook#steps) for more details. Ask Claude Code to create a plan first - it stays in **plan mode** until you approve. Paste this prompt: ```text theme={null} I want to add user referrals to my app using Cello. Use the Cello MCP to search the integration documentation, check my current integration status, and create a thorough implementation plan. Follow all best-practice recommendations from Cello. ``` Claude will pull the relevant guides, check what's already set up, and tailor the plan to your project. ```text theme={null} I now want to add user referrals. I chose platform Cello for this. I added a Cello integration guide according to which you should do the implementation. parsed the documentation more carefully from the start rather than assuming standard patterns would work. create a thorough implementation plan based on guidance, patterns and AC from the provided guide. Don't skip any content, it is all relevant Guide: https://docs.cello.so/resources/react-nodejs-integration ``` Claude asks you guiding questions and creates an implementation plan based on your answers. Review the plan carefully. It should cover: * Cello JS SDK initialization and user authentication * Referral component placement and configuration * Attribution setup for tracking referred signups * Stripe webhook integration for conversion tracking If it looks correct, tell Claude to proceed and start implementing it. Run your app and test the end-to-end flow. If everything was implemented correctly, you should see events coming in to [Cello Dashboard](https://portal.cello.so/dashboard/referrer). If you have the Cello MCP connected, ask Claude to run a health check after deploying: *"Use Cello to check my integration status and confirm all four components are connected."* ## After you're live If you have the Cello MCP connected, it continues to be useful after the initial integration: | Prompt | What happens | | ------------------------------------------------ | ---------------------------------------------------------------------------------------- | | *"Is my Cello integration working?"* | Checks all four integration components and reports which are connected or broken | | *"Why aren't referral rewards being triggered?"* | Inspects recent events to find missing or malformed fields preventing attribution | | *"How can I improve my referral program?"* | Returns a prioritized list of recommendations across activation, sharing, and conversion | | *"How do I set up a custom referral launcher?"* | Searches the docs for custom launcher implementation guides | # Cello + Cursor integration Source: https://docs.cello.so/coding-apps/cursor-integration How to add user referrals to your app using Cello with Cursor Cursor can implement Cello user referrals end-to-end if you give it the **right guide** and force it to create a plan before coding. Cello + Cursor integration