Environments

Two environments, Test and Production. Which one you reach is decided by a single URL — the one you load the widget from.

Saphere runs two environments. They are entirely separate: separate accounts, separate API keys, separate data. A measurement made in Test never appears in Production, and a key issued for one is refused by the other.

EnvironmentWhat it is forCDNAPI
ProductionReal measurements, real quota. What your users reach.https://cdn.saphere.aihttps://api.saphere.ai
TestIntegration and acceptance. Separate accounts, separate data, separate API keys.https://cdn.test.saphere.aihttps://api.test.saphere.ai

Choosing one is choosing a URL

You do not configure an environment. You reach it by the address you call, and the widget follows:

<!-- Test -->
<script type="module">
    import SaphereScan from "https://cdn.test.saphere.ai/saphere-scan/v2/main.js"
</script>

<!-- Production -->
<script type="module">
    import SaphereScan from "https://cdn.saphere.ai/saphere-scan/v2/main.js"
</script>

That single line settles everything else. The widget derives the address of the measurement API from the CDN it was loaded from — a bundle served by cdn.test.saphere.ai talks to api-measure.test.saphere.ai, and never to Production. There is nothing else to switch, and nothing that can be left half-switched.

One thing does not follow automatically

Your own token endpoint. If the widget loads from the Test CDN, your server must call the Test API to mint the access token — a Production token presented to the Test measurement service is refused, and the session never opens.

Read the environment from your own configuration, never hardcode one host.

What differs, and what does not

TestProduction
API keysIssued for Test onlyIssued for Production only
Clients, measurements, tokensSeparate dataSeparate data
Widget version servedThe same releaseThe same release
API surface, event names, optionsIdenticalIdentical

The last two rows are the point of having a Test environment at all: what you validate there is what will run in Production. If a behaviour differs between the two, that is a defect worth reporting, not a difference to code around.

Moving an integration to Production

  1. Swap the CDN URL in the page or app shell.
  2. Point your token endpoint at the Production API, and give it the Production API key.
  3. Check that the key never reaches the browser — see Access tokens.

Nothing else changes: no option, no event name, no payload shape.

Never ship a Production API key to the page

A Production API key has no expiry and no scope. Placed in a page, it is readable by anyone who opens the developer tools, and revoking it means changing it — which cuts every integration of that account at once.

This is why the unsafe-api-key strategy carries that name, and why it belongs to trials on Test only.