data-debug while you investigate — the SDK will explain what it’s doing in the console.
cbh:ready never fires
The script tag has no data-key
The script tag has no data-key
Without
data-key the SDK loads but doesn’t initialise, and cbh:ready only fires after initialisation. Either add data-key or call CashbackHive.init({ key }) yourself.Check: window.CashbackHive exists but window.CashbackHive.initialized is false.Your listener was added after the event fired
Your listener was added after the event fired
cbh:ready fires once. If your code runs after that (a lazily loaded component, a client-side route change, a tag that executes late), it misses the event. Check window.CashbackHive?.initialized first, and only add the listener if it’s false. See Lifecycle.The script didn't load
The script didn't load
Check the Network tab for
sdk.js. A blocked request is usually a CSP violation (look for a Refused to load the script console error), an ad blocker, or a typo in the URL. See Content Security Policy.The script was injected without data-key set
The script was injected without data-key set
When injecting the tag from JavaScript, set
script.dataset.key before appendChild. The SDK reads attributes synchronously when it executes.offers.list() rejects with 403
The current origin isn’t in the property’s allowed origins. The origin includes the scheme and port, so http://localhost:3000, http://localhost:5173, https://example.com and https://www.example.com are all different. Add the exact origin in the publisher portal.
Check: location.origin in the console shows the origin you need to allow.
offers.list() rejects with 401
The publishable key is wrong or has been rotated. Compare document.querySelector('script[src*="cashbackhive"]').dataset.key against the key in the publisher portal.
[CashbackHive] call init({ key }) first…
You called an SDK method before initialisation. Wait for cbh:ready — see Lifecycle.
[CashbackHive] unknown offer "…"
You passed a slug string to openOffer() or trackingUrl() but that offer isn’t in the SDK’s cache. Either fetch it first with offers.get(slug) / offers.list(), or pass the offer object instead of the slug. See Click tracking.
[CashbackHive] click tracking is not available for "…"
The offer’s clickUrl is null. Not every offer supports click tracking; check offer.clickUrl and hide or disable the call to action when it’s missing.
[CashbackHive] member is not signed in
member.activity() requires a signed-in member. Check auth.isSignedIn() first, or only render the activity UI once auth:change delivers a member.
Sign-in popup is blocked
auth.signIn() must be called synchronously from a user gesture (a click handler). If you await something before calling it, browsers treat it as a programmatic popup and block it. The SDK falls back to a full-page redirect in that case, which works but is a worse experience. Restructure so signIn() is the first thing the click handler does.
signIn() rejects with “Sign-in window was closed”
The member closed the popup before completing sign-in. This is a cancel, not an error — reset your UI and let them try again.
Member appears signed out on a returning visit, then signed in a moment later
Expected. On load the SDK finds the stored token and fetches the member in the background;member.current() is null until that completes, then auth:change fires. Drive your UI from auth:change rather than a one-off check. See Members and authentication.
Member is signed out unexpectedly on load
The stored token was rejected by the API (expired or revoked), and the SDK signed the member out automatically. They’ll need to sign in again. Nothing to fix on your side.openOffer() opens nothing / new tab is blocked
Same cause as the sign-in popup: window.open outside a user gesture. Call openOffer() directly in the click handler, with the offer object already in hand, or pass { newTab: false } to navigate the current tab instead.
Two copies of the SDK are loaded
Harmless — the second copy seeswindow.CashbackHive already exists and exits — but it means you have two script tags (often one in HTML and one in a tag manager). Remove one.
TypeScript: Property 'CashbackHive' does not exist on type 'Window'
Add the type declarations to your project and make sure the .d.ts file is included by tsconfig.json.
Still stuck?
Collect the following and contact Cashback Hive support through the publisher portal:- The page URL and
location.origin window.CashbackHive.version- Console output with
data-debugenabled - The failing request and response from the Network tab