> ## Documentation Index
> Fetch the complete documentation index at: https://developer.cashbackhive.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Keys and allowed origins

> Learn how Cashback Hive publishable keys and allowed origins work, why they are safe to ship in the browser, and which credentials to keep server-side.

## Publishable keys

Every property has a **publishable key** that begins with `cbh_pk_`. You pass it to the SDK via the `data-key` attribute (or `init({ key })`), and the SDK sends it with every API request in the `X-CBH-Key` header.

Publishable keys are designed to be visible. Anyone can read them from your page source, and that's fine, because the key alone can't do anything harmful:

* It can only read **offers for your property** and act on behalf of a member who has explicitly signed in on your page.
* It is **bound to your allowed origins** (below). Requests from any other origin are rejected.

> [!WARNING]
>
> Secret keys (used for server-to-server integrations and reporting) must **never** appear in browser code, `NEXT_PUBLIC_*` variables, tag managers, or client bundles. The SDK never needs one.

## Allowed origins

Each property has a list of **allowed origins** — the schemes, hosts and ports the SDK is allowed to run on. An origin is the `scheme://host[:port]` part of a URL, for example:

| URL | Origin |
| - | - |
| `https://www.example.com/deals?x=1` | `https://www.example.com` |
| `https://example.com/` | `https://example.com` (a different origin from `www.`) |
| `http://localhost:3000/` | `http://localhost:3000` |

Register every origin you'll run on: production, staging, preview environments, and local development ports.

### How enforcement works

The script file itself (`sdk.js`) is served to anyone, and `window.CashbackHive` will exist on any page that loads it. Origin enforcement happens **at the API**: the browser attaches an `Origin` header to each request, and the API checks it against the key's allowed list.

On a non-allowed origin you'll see:

* `cbh:ready` still fires, and `CashbackHive.initialized` is `true`.
* `offers.list()`, `offers.get()`, `member.get()` and `member.activity()` reject with an [`SdkApiError`](https://developer.cashbackhive.com/reference/errors) whose `status` is `403`.
* The sign-in window will refuse to issue a token.

This is deliberate: it means you can verify your install locally before the origin is approved, and a misconfigured origin fails loudly instead of silently.

## Multiple properties

If you run several sites, each with its own property and key, load the SDK with the key that belongs to that site. The SDK stores the member's token under a key-specific `localStorage` entry (`cbh:<key>:token`), so sessions don't leak between properties.

## Rotating a key

If you need to rotate a publishable key, update the `data-key` value in your deployed pages. Existing members will need to sign in again on the new key, because their stored token is scoped to the old one.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.