Partners & affiliate programs
How do I view affiliate stats in the Cello portal?
How do I view affiliate stats in the Cello portal?
How can I provide marketing materials for the affiliates to use?
How can I provide marketing materials for the affiliates to use?
Can we automatically add partners/affiliates via API sync?
Can we automatically add partners/affiliates via API sync?
Is coupon-code-only tracking supported (without an affiliate link)?
Is coupon-code-only tracking supported (without an affiliate link)?
ucc parameter are the supported tracking method. Standalone coupon-code tracking (where a code is shared and attributed at checkout without a referral link) is not available today.If your referrers promote through channels where links aren’t practical (podcasts, video, print), consider using a short, memorable referral URL instead. If coupon-code-only tracking is important for your program, share the use case with your CSM.When I upgrade a user referrer to a partner, do they keep the same referral link?
When I upgrade a user referrer to a partner, do they keep the same referral link?
- Users access Cello via the in-product Referral Component.
- Partners can access a separate Cello partner portal, and can also use the in-product Referral Component.
- The same campaign code can be shared across your product and the partner portal. To do so: when adding the partner in the Cello admin portal, ensure the partner is mapped using their
productUserIdso they retain the same UCC/link across your product and the Cello partner portal.
When upgrading a referrer to a partner, does historical performance carry over?
When upgrading a referrer to a partner, does historical performance carry over?
productUserId, the intent is for the partner to retain their current UCC and associated performance history across your product and the Cello partner portal.When upgrading a referrer to a partner, do commissions change retroactively?
When upgrading a referrer to a partner, do commissions change retroactively?
Do we need to remove the referral widget when someone becomes a partner?
Do we need to remove the referral widget when someone becomes a partner?
Attribution & cookies
What is attribution?
What is attribution?
- Referral link sharing — referrers share links containing a unique referral code (
uccparameter) - Landing page capture — your website or app captures and stores the
uccas a first-party cookie - Signup tracking — new user registrations are linked to their referrer via the stored
ucc - Purchase tracking — revenue events are attributed back to the original referrer
Why is the Attribution Library required?
Why is the Attribution Library required?
ucc) from referral links and stores it as a first-party cookie. This cookie persists for 3 months, which is critical because users often don’t sign up immediately — they may click a referral link, browse your site, leave, and return days later before converting.Without the library, the ucc parameter would be lost as soon as the user navigates away from the landing page URL, breaking attribution for these indirect signups.Beyond persistence, the library also provides APIs to:- Retrieve the referral code —
getUcc()for passing into signup and purchase events - Get the referrer’s name —
getReferrerName()for personalizing landing pages - Access campaign config —
getCampaignConfig()for displaying referral discounts - Manage cookie consent — built-in methods for privacy compliance
Do I need the attribution library if I only want cookies stored?
Do I need the attribution library if I only want cookies stored?
Is the cookie with the Cello UCC available across pages/subdomains?
Is the cookie with the Cello UCC available across pages/subdomains?
We have different root domains for landing vs product. Will attribution work?
We have different root domains for landing vs product. Will attribution work?
ucc in a first-party cookie scoped to the root domain where it was set. This means the cookie set on example.net is not automatically available on example.app — browsers enforce this as a security boundary.If your landing page and product use different root domains, here are your options (in order of preference):-
Use the same root domain (recommended) — host your landing page on a subdomain of your product domain (e.g.,
www.example.appfor landing,app.example.appfor the product). This makes attribution seamless with no extra work, since cookies are shared across subdomains of the same root domain. -
Persist the
uccin URLs across domains — install the Attribution Library on both domains and ensure all links between them append the?ucc={ucc}parameter. This way theuccis recaptured by the Attribution Library when the user arrives on the second domain. -
Build a custom cross-domain bridge — implement server-side logic to store and forward the
uccwhen users transition between domains (e.g., pass it through your authentication or redirect flow so it’s available on the product domain at signup time).
Does Cello integrate with cookie consent management platforms (OneTrust, CookieBot, etc.)?
Does Cello integrate with cookie consent management platforms (OneTrust, CookieBot, etc.)?
What is direct vs indirect signups?
What is direct vs indirect signups?
- Direct signup: user clicks a referral link and signs up immediately.
- Indirect signup: user clicks a referral link, navigates around, and signs up later from a different page.
Can we track purchases without requiring a prior signup event?
Can we track purchases without requiring a prior signup event?
new-signup or sign_in event via the Cello API before sending invoice-paid events — otherwise the purchase has no user to attribute to.A common use case is existing-user attribution, where a current user clicks a referral link and you want to credit the referrer for their next purchase. The recommended approach:- Check for a
uccon login — not just on signup. UsegetUcc()from the Attribution Library or read theuccURL parameter directly. - Validate the
ucc— call Cello’s Referral Codes API to confirm the code is valid and identify the referrer. - Prevent self-attribution — compare the referrer’s
productUserIdwith the logged-in user’s ID. If they match, ignore theucc. - Store the
ucc— save it in your database linked to the user, so it’s available when sending events. - Send events to Cello — send a
sign_inevent (to establish the attribution) followed byinvoice-paidevents as purchases occur.
How do I manually backfill attribution for a missed signup or purchase?
How do I manually backfill attribution for a missed signup or purchase?
- Get the referrer’s
cello_uccfrom the Cello Portal and the new user’snew_user_idfrom your system. - Add
cello_uccandnew_user_idto the new user’s customer metadata in Stripe or Chargebee. - Cello will receive a
customer.updated(Stripe) orcustomer_changed(Chargebee) event automatically. - If past invoices were already paid, resend the
invoice.paid(Stripe) orpayment_succeeded(Chargebee) events from within your payment platform’s dashboard.
- Get the referrer’s
cello_uccand the new user’s ID. - Resend the signup event via the POST /events API.
- Resend any past transaction events via the same API.
My flow is purchase first, signup later. Does that work?
My flow is purchase first, signup later. Does that work?
- User clicks a referral link and the
uccis captured by the Attribution Library. - User completes a Stripe Checkout session, which creates a Stripe customer.
- After the checkout session completes, update the Stripe customer with
cello_uccandnew_user_idmetadata viacustomer.update. - Cello receives the
customer.updatedevent and uses it to establish the attribution. - Even if the first
invoice.paidevent arrived before the metadata was added, Cello will retroactively attribute it once the customer is updated.
cello_ucc and new_user_id to the Chargebee customer metadata after checkout. Cello will receive the customer_changed event.How it works with Cello API:
If your payment gateway is Paddle, Recurly, or another provider, use the POST /events API to send a new-signup event after the customer is created at purchase.Related docsStripe / Chargebee events & webhooks
Do we really need many Stripe events? Would invoice.paid be enough?
Do we really need many Stripe events? Would invoice.paid be enough?
What are subscription events used for?
What are subscription events used for?
- created: detect signups, free-to-paid conversion, and capture subscription details
- updated: same as created; they additionally detect plan/seat changes, downgrades, expansions, churn
- deleted (or canceled): detect churn for paid subscriptions
Why send subscription events if we already send invoice.paid?
Why send subscription events if we already send invoice.paid?
What is invoice.paid used for?
What is invoice.paid used for?
What is customer.created / customer.updated used for?
What is customer.created / customer.updated used for?
- customer.created: typically used as the signup signal when the customer is created at signup
- customer.updated: used when you add or change attribution metadata (e.g.
cello_ucc,new_user_id) after the customer already exists (e.g. at first purchase)
What is charge.succeeded used for?
What is charge.succeeded used for?
What is charge.refunded used for?
What is charge.refunded used for?
What events do we need if we use Cello API only?
What events do we need if we use Cello API only?
- Send signup events via API.
- Send at least purchase events (e.g. invoice-paid equivalent) via the Cello API.
- Include amount (in cents), currency, and payment frequency (monthly vs annual) where applicable.
- Send renewal purchase events for continuous rewarding and referral ARR computation.
What events do we need if we use Stripe or Chargebee webhooks only?
What events do we need if we use Stripe or Chargebee webhooks only?
cello_ucc and new_user_id to the customer object (on customer.created or customer.updated, depending on when you create the customer). That customer update is the signup signal; subscription and invoice events are then used automatically for rewards.Related docsWhat if we use a payment provider other than Stripe/Chargebee?
What if we use a payment provider other than Stripe/Chargebee?
Which user ID should we send as new_user_id / productUserId?
Which user ID should we send as new_user_id / productUserId?
Will connecting Stripe webhooks affect our payment architecture?
Will connecting Stripe webhooks affect our payment architecture?
Are accessKeyId and productId the same thing?
Are accessKeyId and productId the same thing?
Reward amount is less than expected. What could be wrong?
Reward amount is less than expected. What could be wrong?
Stripe can’t send webhook events to our server. What should we check?
Stripe can’t send webhook events to our server. What should we check?
What events are needed when using Cello API plus Stripe or Chargebee webhooks?
What events are needed when using Cello API plus Stripe or Chargebee webhooks?
- Send
new-signupevents via the Cello API. - Connect Stripe or Chargebee webhooks.
- Add
cello_uccandnew_user_idto the customer object (oncustomer.createdorcustomer.updated). - Subscription and invoice events are detected automatically once the above is triggered — no need to add
cello_uccandnew_user_idto subscription or transaction events.
Is there deduplication for invoice-paid events (e.g. by invoiceId) when using Cello API?
Is there deduplication for invoice-paid events (e.g. by invoiceId) when using Cello API?
new_user_id + time difference + invoiceId (if provided).- The current time-difference threshold for detecting duplicate
invoice-paidevents is one minute. - Flagged events go through manual review, and the threshold is adjusted if there are too many false positives.
- There are scenarios where a customer can buy multiple subscriptions within a minute, so the threshold is kept conservative.
- If you can send an
invoiceId, this significantly improves deduplication accuracy since it becomes the primary identifier for detecting duplicates.
Rewards, payouts, taxes & billing
What payout methods are supported (besides PayPal/Venmo)?
What payout methods are supported (besides PayPal/Venmo)?
How does Cello invoicing work?
How does Cello invoicing work?
When will we receive invoices?
When will we receive invoices?
How should we handle refunds and reward clawbacks?
How should we handle refunds and reward clawbacks?
How do we apply the referee discount if we don’t use the Cello↔Stripe discount integration?
How do we apply the referee discount if we don’t use the Cello↔Stripe discount integration?
If a referrer churns from our product, do their rewards stop?
If a referrer churns from our product, do their rewards stop?
What happens if a referee cancels and later resubscribes? Does the referrer keep earning?
What happens if a referee cancels and later resubscribes? Does the referrer keep earning?
What happens when a referred user cancels an annual subscription?
What happens when a referred user cancels an annual subscription?
If a customer prepays annually, is the reward paid on the full year or prorated?
If a customer prepays annually, is the reward paid on the full year or prorated?
Can we cap rewards by time instead of total reward amount?
Can we cap rewards by time instead of total reward amount?
What currencies are supported for campaigns?
What currencies are supported for campaigns?
What currencies are supported for reward payouts?
What currencies are supported for reward payouts?
Can we restrict payment countries shown to referrers (e.g. US only)?
Can we restrict payment countries shown to referrers (e.g. US only)?
Rewards earned shows $0 in the widget. When does that update?
Rewards earned shows $0 in the widget. When does that update?
Can end users see a dashboard of their referrals and rewards?
Can end users see a dashboard of their referrals and rewards?
Successful referrals are missing from the customer view. What should I check?
Successful referrals are missing from the customer view. What should I check?
- Verify that signup and purchase events are being sent correctly and contain the expected
cello_uccandnew_user_idvalues - Confirm that the
productUserIdis consistent — if the same user signs up via different channels with different IDs, attribution may not match - Check whether there have been any recent code changes that could affect how events are sent to Cello
Do referrers handle taxes themselves? Do we need to explain tax implications?
Do referrers handle taxes themselves? Do we need to explain tax implications?
When exactly are invoices generated, and how do cancellations affect them?
When exactly are invoices generated, and how do cancellations affect them?
When referrers add their payment details, when exactly is the reward applied?
When referrers add their payment details, when exactly is the reward applied?
Is the payout always in USD, or can it be in EUR/GBP based on the referrer's preference?
Is the payout always in USD, or can it be in EUR/GBP based on the referrer's preference?
- Cello allows you to select only one default currency for your rewards (configured in the Campaigns tab).
- Cello covers transfer and transaction fees, including currency conversion from the subscription event currency back to your nominated default currency.
- Referrers receive rewards in their PayPal account in your default currency. If they convert to a different currency (e.g. their local one), the exchange rate depends on PayPal’s currency exchange and may include additional PayPal fees.
I want to move my referrers to a higher revshare or reward, or move a user-led referrer to a higher partner campaign plan
I want to move my referrers to a higher revshare or reward, or move a user-led referrer to a higher partner campaign plan
I want to move a referrer from one Partner Campaign to another
I want to move a referrer from one Partner Campaign to another
- Existing signups retain the reward terms from the original campaign
- New signups (after the move) use the new campaign’s reward structure
Can we implement a reward cap based on a time threshold AND/OR an amount ceiling?
Can we implement a reward cap based on a time threshold AND/OR an amount ceiling?
Notifications & emails
If a referrer earns a reward but hasn’t set up payout details, will they be prompted?
If a referrer earns a reward but hasn’t set up payout details, will they be prompted?
Can Cello provide sample email notifications?
Can Cello provide sample email notifications?
Can email templates be customized?
Can email templates be customized?
When are welcome emails triggered?
When are welcome emails triggered?
- Sent on the 6th day after a new user first signs up to introduce the referral program and its details.
- Includes the referral link.
- Sent only once per user.
Please review the notifications tab in portal for copy and timing.
If a user views the widget in another language (example: French or German), will their emails match that language?
If a user views the widget in another language (example: French or German), will their emails match that language?
Enabling of email text in different languages requires config customization on the Cello side. Please coordinate with your Customer Success Manager for the additional languages required.
Why can’t we keep the notification dot always visible?
Why can’t we keep the notification dot always visible?
What we have seen work well for other customers are small “NEW” stickers on the right side of the menu items.
How do announcements, dots, and welcome/view emails work (typical timing)?
How do announcements, dots, and welcome/view emails work (typical timing)?
welcome-dot: after first boot if user remains inactivewelcome-announcement: a few days after first activity (or after the welcome-dot is displayed)welcome-email: about one week after first boot. All other emails are transactional, meaning they are only sent in order to update the referrer on their referral activity.
The notification badge position is incorrect. How do I fix it?
The notification badge position is incorrect. How do I fix it?
- The badge is added on the menu level instead of the menu-item level.
- The badge is positioned
absolutebut lacks arelativeparent. Set the menu-item container toposition: relative.
How are notifications managed overall? What is the notification logic?
How are notifications managed overall? What is the notification logic?
- In-product: announcement banners and badge dots displayed inside the widget.
- External: emails (welcome, reward earned, first-view, etc.).
How can we subscribe to Cello release notes and new features?
How can we subscribe to Cello release notes and new features?
If we have major updates, we often post about them directly in a shared slack channel. We also have this section in our docs for updates: Changelog
Fraud, self-referrals & abuse
What is the self-referral policy?
What is the self-referral policy?
Can a rejected referral be reversed?
Can a rejected referral be reversed?
How do you handle abuse/self-referrals?
How do you handle abuse/self-referrals?
Do you use hashed IP/fingerprinting to detect abuse?
Do you use hashed IP/fingerprinting to detect abuse?
If an account is suspended for fraud, will the referrer see that in the widget?
If an account is suspended for fraud, will the referrer see that in the widget?
How does the self-referral detection system work?
How does the self-referral detection system work?
- The new user (referred person).
- The referrer based on the UCC the new user used.
Integrations, SDKs & implementation
What is the Cello Referral Component?
What is the Cello Referral Component?
- Referral link sharing — users can copy their link, share via social media, email, or QR code
- Progress tracking — real-time dashboard showing clicks, signups, and earned rewards
- Reward payouts — automated payouts via PayPal, Venmo, and other methods
- Notifications — in-app and email alerts for referral activity and milestones
- Multi-language support — 10+ languages with automatic detection
- Dark mode — adapts to your app’s theme
Which programming languages/frameworks are supported?
Which programming languages/frameworks are supported?
- React, Next.js, Vue, Angular, Svelte, and vanilla JavaScript
<body> as your AppRoot element to prevent a race condition with Cello’s DOM injection (see the Angular notes in the quickstart).For mobile apps, native SDKs are available:- iOS SDK — Swift/Objective-C with CocoaPods and SPM
- Android SDK — Kotlin/Java with Gradle
- React Native SDK — cross-platform mobile
- Flutter SDK — cross-platform mobile
Can we remove the Cello branding?
Can we remove the Cello branding?
Can we customize widget text and UI?
Can we customize widget text and UI?
- Brand colors — primary color, button color, and notification badge color
- Button style and position — choose from 3 styles, set screen position, or use a custom launcher integrated into your own menu
- Component type — display as a pop-up or a modal, with configurable position
- Text and language — customize the default text (onboarding, offer description) and provide multiple language options. 10+ languages are supported with automatic detection
- Sharing options — enable/disable link copy, social sharing (Twitter, LinkedIn, email), and QR codes
- Payment methods — configure PayPal, Venmo, or other payout options for referrers
- Announcements — choose between toasts, banners, or anchored announcements
Can we customize emails/announcements copy?
Can we customize emails/announcements copy?
- Enable or disable specific notification types (alerts, announcements, emails)
- Choose announcement display style — toasts, banners, or anchored to your launcher
- Configure the activation campaign — recurring announcements to re-engage inactive referrers
- Set reward amounts and program details — which flow into the standardized email templates automatically
- Email body copy (e.g., “How It Works” page, reward email wording) — custom copy changes may be available depending on your plan. Contact your CSM or the Cello product team to discuss options.
- Announcement text content — same as above
Can we change placement/style of the landing/referral messages?
Can we change placement/style of the landing/referral messages?
- Dedicated landing page (recommended) — build a custom page optimized for referral conversions. Dedicated pages have shown up to 2x higher conversion rates. You have full control over layout, design, messaging, and CTAs.
- Home page with inline personalization — use your existing home page and add referral-specific personalization (referrer name, discounts) directly into your headline and CTA using the Attribution JS API (`getReferrerName()`, `getCampaignConfig()`).
- Home page with New User Banner (no code) — add the Cello attribution script and enable the New User Banner in the Cello Portal. The banner automatically displays personalization and discount info to visitors arriving via referral links.
How do we validate a UCC?
How do we validate a UCC?
GET /referral-codes/{code} to validate a UCC and identify the referrer it belongs to.The API returns:valid— whether the UCC is a legitimate, active referral codeproductUserId— the referrer’s user ID in your systemcampaignId— the campaign the UCC is associated with
- Self-referral prevention — compare the returned
productUserId(referrer) with the logged-in user’s ID; if they match, ignore the UCC - Existing-user attribution — validate the UCC on login before storing it for future purchase attribution
- Tampered URL detection — if someone modifies the
uccquery parameter, the API will returnvalid: false - Discount eligibility — validate the UCC before applying a new-user discount to ensure the code hasn’t been tampered with
Can we grab the UCC directly from the URL instead of calling getUcc()?
Can we grab the UCC directly from the URL instead of calling getUcc()?
ucc is always present as a query parameter in the URL when a user clicks a referral link (e.g., https://yoursite.com/?ucc=ABC123). You can parse it directly from the URL using standard JavaScript:getUcc() from the Attribution JS library is recommended because it:- Falls back to cookies — if the user navigated away and the
uccis no longer in the URL,getUcc()retrieves it from the stored cookie - Handles async loading — waits for the attribution script to initialize before returning data
- Works across sessions — cookies persist for 3 months, covering indirect signups where the user returns later
ucc from the URL yourself, make sure to store it in your database linked to the user at signup, so it’s available when sending signup and purchase events to Cello.Related docsDoes Cello integrate with Salesforce?
Does Cello integrate with Salesforce?
- An Opportunity reaches a specific stage (e.g., “Proposal/Price Quote”)
- The Opportunity has a
cello_ucccustom field populated
Turbo (turbo-rails / Hotwire) hides the widget iframe on navigation. Any guidance?
Turbo (turbo-rails / Hotwire) hides the widget iframe on navigation. Any guidance?
We integrated React Native (Expo) and see APIError error 1 on init. What should we check?
We integrated React Native (Expo) and see APIError error 1 on init. What should we check?
InitializationError) typically means the SDK is connecting to the wrong environment. When using Expo, the env property defaults to prod — if your credentials are for the sandbox environment but env is not explicitly set, initialization will fail.Verify that the env value is correctly nested under the @getcello/cello-react-native Expo plugin in your app.json:- Credentials — ensure
productIdandtokenmatch the environment you selected (sandboxvsprod) - Not using Expo Go — the Cello SDK requires a custom native build and will not work in Expo Go (you’ll see a
LINKING_ERRORinstead)
Our signup discount isn’t applied when the referee reaches payment stage. Why?
Our signup discount isn’t applied when the referee reaches payment stage. Why?
-
Is the
uccavailable at checkout? — verify the referral code was preserved from signup to the payment flow. Check your Stripe/Chargebee customer metadata forcello_ucc, or callgetUcc()from the Attribution Library. If it’s missing, the attribution cookie may have been lost (e.g., cookie consent blocked it, or the user is on a different domain). -
Is the user eligible for a discount? — use the New User Reward API to validate eligibility, or check for
cello_uccin the customer object in your payment platform. -
Is the coupon applied during subscription creation? — discounts must be passed at the time the subscription is created (e.g., via
discountsarray in Stripe orcoupon_idsin Chargebee). They cannot be attached after the fact through the API. - Is the coupon valid? — verify the coupon ID exists in your payment platform, hasn’t expired, and matches the plan type being purchased.
I added the CDN script in index.html and sometimes the page errors on load. Why?
I added the CDN script in index.html and sometimes the page errors on load. Why?
<body> element is available in the DOM. Cello appends its UI to <body>, so if <body> doesn’t exist yet, initialization fails.Recommended fix: Ensure the script tag includes type="module" and async, and is placed in the <head>:type="module" attribute defers execution until after the DOM is parsed, which prevents the race condition. If you’re still seeing issues:- Use the command queue pattern — initialize Cello through the queue so commands are buffered until the script is ready:
- Move the script to the end of
<body>— as a fallback, placing the<script>tag just before</body>ensures the DOM is fully available - Angular users — avoid using
<body>as your AppRoot element, as this creates a race condition with Cello’s DOM injection. See the Angular notes
await window.CelloAttribution('getUcc') can hang if the script fails to load. What should we do?
await window.CelloAttribution('getUcc') can hang if the script fails to load. What should we do?
getUcc() promise will never resolve or reject — it waits indefinitely for the script to initialize.Never place getUcc() on a critical path that blocks your signup or checkout flow. Instead, race it against a timeout:ucc directly from the URL query parameter as a backup.Related docsCan we embed referral links in our own marketing channels (newsletters, emails, etc.)?
Can we embed referral links in our own marketing channels (newsletters, emails, etc.)?
How do we cancel or stop reward payments when a subscription is cancelled or refunded?
How do we cancel or stop reward payments when a subscription is cancelled or refunded?
subscription.deleted— stops future recurring rewards for that referralcharge.refunded— automatically cancels any pending reward for that transaction
charge-refunded event via POST /events to cancel pending rewards for a specific transaction:- Pending rewards are automatically cancelled when a refund event is received
- Already paid-out rewards are not clawed back from referrers — Cello does not ask referrers to return money
- To mitigate refund risk, many programs spread rewards over time (e.g. monthly over 12 months) so future payouts can be stopped if the deal falls through
- Cello can also configure a payout delay (e.g. 14 days) matching your refund window — contact your CSM to set this up
- You can review reward status (CREATED, CANCELED, REJECTED, PROCESSED) in the Cello Portal under the Purchases page
Does the productId need to match our domain?
Does the productId need to match our domain?
productId is simply an identifier for your Cello account — it does not need to match your application domain, staging URL, or any specific URL pattern. It may look like a domain, but that is just a naming convention; it has no functional connection to where you deploy Cello.What does matter is using the correct credentials for each environment:- Sandbox credentials (
productId+PRODUCT_SECRETfrom the Sandbox environment) for development and staging - Production credentials (
productId+PRODUCT_SECRETfrom the Production environment) for your live application
- Using a Sandbox
productIdwith a ProductionPRODUCT_SECRET(or vice versa) - Calling the wrong Cello API environment from your backend
- Using the wrong webhook signing secret for the environment
Is there a headless API? Do we have to use the Referral Component (widget)?
Is there a headless API? Do we have to use the Referral Component (widget)?
- Attribution — capturing referral codes, tracking signups, and tracking purchases all happen via the Cello API or Stripe/Chargebee webhooks, with no widget required
- Referral code validation —
GET /referral-codes/{code}to verify a UCC - Active link retrieval —
GET /referral-codes/active-link/{productUserId}to fetch a user’s referral link programmatically - Event sending —
POST /eventsfor signup, purchase, and refund events
- Link sharing (copy, social media, email, QR code)
- Progress tracking (clicks, signups, earnings)
- Reward payouts and payment details management (PayPal/Venmo)
- In-app notifications, announcements, and onboarding
- Multi-language support and dark mode
- Use
getActiveUcc()to retrieve a user’s referral link - Use
getCampaignConfig()to fetch reward amounts and program details - Use
getLabels()to get localized text for your custom elements
How does Cello handle language and localization?
How does Cello handle language and localization?
| Surface | How language is selected | Fallback |
|---|---|---|
| Referral Component (web) | Pass language (ISO 639-1) during cello.boot() to match your app’s user preference | Product default language |
| Referral Component (mobile) | Pass language during SDK initialization (iOS, Android, React Native, Flutter) | Device language, then English |
| Referee landing page | Detected from the visitor’s browser settings | English |
| Referrer landing page (mobile) | Detected from device settings | English |
- Web:
window.Cello("changeLanguage", "de") - Mobile:
Cello.changeLanguage("de")(iOS 14+ required on iOS)
How do we retrieve campaign details (like reward percentage, new-user discount) programmatically?
How do we retrieve campaign details (like reward percentage, new-user discount) programmatically?
getCampaignConfig() to retrieve the current user’s campaign details:primaryCurrency— reward currency coderevenuePercentage— referrer reward as a percentage of revenuerewardCap— maximum reward per referralnewSignupBonus— bonus reward for each signupnewPurchaseBonus— bonus reward for each purchasenewUserDiscountPercentage— discount for referred new users (decimal:0.1= 10%)newUserDiscountMonth— how many months the discount lasts
getCampaignConfig() from the Attribution SDK to display discount info before signup:getCampaignConfig() on iOS, Android, React Native, and Flutter.Note on campaignId in the referral-codes API:
When calling GET /referral-codes/{code}, the response includes a campaignId field. For the default campaign, this field returns an empty string — this is expected behavior, not an error. Non-default campaigns return their actual campaign ID.Related docsAuthentication & tokens
Why is my JWT token being rejected? How does the iat timestamp validation work?
Why is my JWT token being rejected? How does the iat timestamp validation work?
iat (issued at) field in the JWT payload is a Unix timestamp that tells Cello when the token was created. Cello enforces a validation window on this value:- The
iatcannot be older than 24 hours — tokens issued more than 24 hours ago are considered expired - The
iatcannot be set in the future — tokens with a future timestamp are rejected as invalid
iat value may fall outside these bounds and the token will be rejected, causing a boot failure with a token/authorization error.How to fix:- Verify your server’s system clock — ensure it is synchronized using NTP (Network Time Protocol)
- Use
Math.floor(Date.now() / 1000)(or equivalent in your language) to generate theiatvalue dynamically rather than hardcoding it - Check your environment — staging and production servers may have different time configurations
How does Cello API token authentication work? Does the refresh token expire?
How does Cello API token authentication work? Does the refresh token expire?
-
Authenticate — call
POST /tokenwith youraccessKeyIdandsecretAccessKey(from the Access Keys page). This returns:accessToken— short-lived token used in theAuthorizationheader for API requestsrefreshToken— longer-lived token used to get new access tokens without re-authenticatingexpiresIn— how long the access token is valid
-
Refresh — when the access token expires, call
POST /tokenwith therefreshTokento get a newaccessToken. This does not return a new refresh token. -
Re-authenticate — the refresh token expires after 5 days. Once expired, you must perform a full authentication again with your
accessKeyIdandsecretAccessKeyto obtain both a new access token and a new refresh token.
- Store the refresh token securely after initial authentication
- Use it to refresh the access token before it expires
- Implement a fallback to full re-authentication when the refresh token itself expires (after 5 days)