Keys
- Servers read a live secret key from the environment (
CURIOUS_SECRET_KEY), never from code. Browsers and mobile apps hold a live publishable key only. - The live publishable key’s origin allowlist lists every exact
https://origin that will call from a browser. A missing origin is a403for every visitor on it. - No generic
CURIOUS_API_KEYvariable in a browser bundle, where a build step could substitute the secret one. - You know how to rotate: create a new key, deploy it, revoke the old. Revocation takes effect within about thirty seconds. See Keys and environments.
The declaration
- Each element’s declaration lives in one place: inline on every
decide, or in adeclarestep, not both. Two call sites that disagree on a declaration-class field supersede the experiment on every alternation. -
options.assignmentis chosen:staticfor content a user sees repeatedly,dynamicfor per-send channels. See Assignment and stickiness. -
options.holdoutis what you want; it cannot be changed without restarting the experiment. -
options.approvalis decided:manual(the default) means someone will review variants in the dashboard;automeans they serve as generated. -
element_typeis set where one fits, so variants are written with the right craft.
The delivery path
- Every
decidehas a deadline and serves your control when it passes or anything fails. See Fallbacks and timeouts. -
decideis called once per exposure, not on every render. - No
decideretry without anidempotency_key. - You log
X-Request-Id(the SDK’srequestId) and the fallback rate.
Events and identity
- Every event your rewards and constraints name is reported, with the properties your filters match on, for every user.
- Events carry a stable
id, and retries reuse it. - Buffered or backfilled events carry their real
timestamp. - The
user_idon events is the one you decided with, and login callsidentifyfrom the server; logout mints a fresh anonymous id. - Queued events are flushed before the runtime exits or freezes (
flush()handed towaitUntilon edge runtimes).
The first live decision
- Serve one decision with the live key and find it in the dashboard under the element, with
experiment_status: "initializing"if the element is new. - Report one event for that user and see it on the experiment.
- If variants were already approved under the test key, note that the live experiment is the same chain: what you approved is what serves.