@apex-inc/sdk 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@ Works in Node.js 18+ and browser environments. Zero runtime dependencies.
6
6
 
7
7
  ## Access
8
8
 
9
- Apex is invite-only during the private-beta period. If you received an invite, your onboarding email contains your `projectKey` and `apiUrl`. Full API documentation is available in-app once your account is active.
9
+ Apex is invite-only during the private-beta period. If you received an invite, your onboarding email contains your `workspaceKey` and `apiUrl`. Full API documentation is available in-app once your account is active.
10
10
 
11
11
  Not in the beta yet? Request access at [apex.inc](https://apex.inc) (coming soon).
12
12
 
@@ -22,7 +22,7 @@ npm install @apex-inc/sdk
22
22
  import { init, track, identify } from "@apex-inc/sdk";
23
23
 
24
24
  init({
25
- projectKey: "your-project-key",
25
+ workspaceKey: "your-workspace-key",
26
26
  apiUrl: "https://your-apex-instance.com",
27
27
  });
28
28
 
@@ -40,7 +40,7 @@ expansion, and retention rollups automatically:
40
40
  import { init, identify, group, feature, track } from "@apex-inc/sdk";
41
41
  import { EVENTS, type ActivatedEvent } from "@apex-inc/sdk/plg-events";
42
42
 
43
- init({ projectKey: "your-project-key", apiUrl: "https://app.apex.inc" });
43
+ init({ workspaceKey: "your-workspace-key", apiUrl: "https://app.apex.inc" });
44
44
 
45
45
  // Identify the authenticated user.
46
46
  identify("chris@acme.com", { visitorId: "apex_vid_from_cookie" });
@@ -93,7 +93,7 @@ stitching just works.
93
93
  ## Multi-workspace orgs
94
94
 
95
95
  If your organization runs more than one workspace (e.g. a SaaS product
96
- plus a partner marketplace), each workspace has its own `projectKey`.
96
+ plus a partner marketplace), each workspace has its own `workspaceKey`.
97
97
  Initialize one SDK instance per workspace; event identity stitches at
98
98
  the org level via `OrgPerson` so a single human tracked in both shows
99
99
  up as one person in cross-workspace cohorts and reports.
package/dist/esm/index.js CHANGED
@@ -14,7 +14,7 @@ async function sendBatch(events) {
14
14
  const apiUrl = config.apiUrl ?? DEFAULT_API_URL;
15
15
  const url = `${apiUrl.replace(/\/$/, "")}/api/events`;
16
16
  const body = JSON.stringify({
17
- projectKey: config.projectKey,
17
+ workspaceKey: config.workspaceKey,
18
18
  userId,
19
19
  events,
20
20
  // MMP-070 — propagate the SDK-level environment override (when
@@ -68,11 +68,16 @@ function enqueue(event) {
68
68
  // ─── Public API ──────────────────────────────────────────────────────────────
69
69
  /**
70
70
  * Initialize the Apex SDK. Must be called before track() or identify().
71
+ * Accepts `workspaceKey` (canonical) or the deprecated `projectKey`.
71
72
  */
72
73
  export function init(options) {
73
- config = options;
74
+ const workspaceKey = options.workspaceKey ?? options.projectKey;
75
+ if (!workspaceKey) {
76
+ throw new Error("apex.init: `workspaceKey` is required");
77
+ }
78
+ config = { ...options, workspaceKey };
74
79
  queue = [];
75
- log("Initialized with project:", options.projectKey);
80
+ log("Initialized with workspace:", workspaceKey);
76
81
  startFlushTimer();
77
82
  }
78
83
  /**
@@ -133,7 +138,7 @@ async function stitchIdentity(email, browserVisitorId, metadata, stableUserId) {
133
138
  return;
134
139
  const apiUrl = config.apiUrl ?? DEFAULT_API_URL;
135
140
  const url = `${apiUrl.replace(/\/$/, "")}/api/identity/stitch`;
136
- const effectiveVisitorId = browserVisitorId || `sdk-${config.projectKey}-${email}`;
141
+ const effectiveVisitorId = browserVisitorId || `sdk-${config.workspaceKey}-${email}`;
137
142
  try {
138
143
  const fetchFn = typeof fetch !== "undefined" ? fetch : await loadNodeFetch();
139
144
  await fetchFn(url, {
@@ -142,7 +147,7 @@ async function stitchIdentity(email, browserVisitorId, metadata, stableUserId) {
142
147
  body: JSON.stringify({
143
148
  visitorId: effectiveVisitorId,
144
149
  email,
145
- projectKey: config.projectKey,
150
+ workspaceKey: config.workspaceKey,
146
151
  ...(stableUserId ? { userId: stableUserId } : {}),
147
152
  metadata: metadata ?? {},
148
153
  }),
@@ -270,6 +275,144 @@ export function shutdown() {
270
275
  config = null;
271
276
  log("Shut down");
272
277
  }
278
+ function experimentMurmurhash3(key) {
279
+ let h = 0x811c9dc5;
280
+ for (let i = 0; i < key.length; i++) {
281
+ h ^= key.charCodeAt(i);
282
+ h = Math.imul(h, 0x01000193);
283
+ }
284
+ return (h >>> 0) % 100;
285
+ }
286
+ function getExperimentVisitorId() {
287
+ if (!isBrowser)
288
+ return "";
289
+ const key = "apex_vid";
290
+ const match = document.cookie.match(new RegExp(`(?:^|; )${key}=([^;]*)`));
291
+ if (match)
292
+ return decodeURIComponent(match[1]);
293
+ const id = typeof crypto !== "undefined" && crypto.randomUUID
294
+ ? crypto.randomUUID()
295
+ : `vid_${Date.now()}_${Math.random().toString(36).slice(2, 12)}`;
296
+ const d = new Date();
297
+ d.setTime(d.getTime() + 365 * 86400000);
298
+ document.cookie = `${key}=${encodeURIComponent(id)};expires=${d.toUTCString()};path=/;SameSite=Lax`;
299
+ return id;
300
+ }
301
+ function getExperimentPreview() {
302
+ if (!isBrowser)
303
+ return null;
304
+ const params = new URLSearchParams(window.location.search);
305
+ const variant = params.get("_apex_preview");
306
+ const expId = params.get("_apex_exp");
307
+ if (variant)
308
+ return { variant, expId };
309
+ return null;
310
+ }
311
+ // Deduped per (experiment, variant) for the page session so repeated
312
+ // `getVariant` calls don't double-count exposures.
313
+ const firedExperimentExposures = new Set();
314
+ function fireExperimentExposure(experimentId, variant, apiBase, workspaceKey) {
315
+ if (!isBrowser)
316
+ return;
317
+ const dedupeKey = `${experimentId}:${variant}`;
318
+ if (firedExperimentExposures.has(dedupeKey))
319
+ return;
320
+ firedExperimentExposures.add(dedupeKey);
321
+ const visitorId = getExperimentVisitorId();
322
+ try {
323
+ void fetch(`${apiBase}/api/events`, {
324
+ method: "POST",
325
+ headers: {
326
+ "Content-Type": "application/json",
327
+ ...(workspaceKey ? { "x-apex-workspace": workspaceKey } : {}),
328
+ },
329
+ credentials: "include",
330
+ keepalive: true,
331
+ body: JSON.stringify({
332
+ type: "experiment_exposure",
333
+ visitorId,
334
+ url: window.location.href,
335
+ timestamp: new Date().toISOString(),
336
+ experimentId,
337
+ variant,
338
+ data: { experiment_id: experimentId, variant_key: variant, surface: "web" },
339
+ }),
340
+ }).catch(() => { });
341
+ }
342
+ catch {
343
+ /* exposure tracking is best-effort */
344
+ }
345
+ }
346
+ /**
347
+ * Resolve the experiment arm for the current visitor — the React-free
348
+ * equivalent of `useApexVariant`.
349
+ *
350
+ * Resolution order:
351
+ * 1. Preview mode (`?_apex_preview=variant_b&_apex_exp=<id>`) — author
352
+ * preview, never counted as an exposure.
353
+ * 2. Cached assignment in `localStorage` (`apex_var_<id>`).
354
+ * 3. Server assignment (`GET /api/experiments/{id}/assign?source=sdk`).
355
+ * 4. Deterministic murmur-hash of `visitorId + experimentId` (fallback).
356
+ *
357
+ * Returns `"control"` during SSR / non-browser contexts. Fires the
358
+ * canonical `experiment_exposure` event (deduped) for cases 2–4.
359
+ *
360
+ * @example
361
+ * import { getVariant } from "@apex-inc/sdk";
362
+ * const arm = await getVariant("exp_123");
363
+ * if (arm === "variant_b") renderVariant(); else renderControl();
364
+ */
365
+ export async function getVariant(experimentId, opts = {}) {
366
+ if (!isBrowser)
367
+ return "control";
368
+ const apiBase = (opts.apiUrl ?? config?.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, "");
369
+ const workspaceKey = opts.workspaceKey ?? config?.workspaceKey;
370
+ // 1. Preview mode — author previewing, not a real exposure.
371
+ const preview = getExperimentPreview();
372
+ if (preview && (!preview.expId || preview.expId === experimentId)) {
373
+ return preview.variant;
374
+ }
375
+ const cacheKey = `apex_var_${experimentId}`;
376
+ // 2. Cached assignment — still count the (deduped) exposure.
377
+ const cached = localStorage.getItem(cacheKey);
378
+ if (cached === "control" || cached === "variant_b") {
379
+ fireExperimentExposure(experimentId, cached, apiBase, workspaceKey);
380
+ return cached;
381
+ }
382
+ const visitorId = getExperimentVisitorId();
383
+ if (!visitorId)
384
+ return "control";
385
+ // 3. Server assignment.
386
+ try {
387
+ const res = await fetch(`${apiBase}/api/experiments/${experimentId}/assign?source=sdk`, {
388
+ credentials: "include",
389
+ headers: workspaceKey ? { "x-apex-workspace": workspaceKey } : {},
390
+ });
391
+ if (!res.ok)
392
+ throw new Error(`${res.status}`);
393
+ const data = (await res.json());
394
+ localStorage.setItem(cacheKey, data.variant);
395
+ fireExperimentExposure(experimentId, data.variant, apiBase, workspaceKey);
396
+ return data.variant;
397
+ }
398
+ catch {
399
+ // 4. Deterministic hash fallback.
400
+ const bucket = experimentMurmurhash3(visitorId + experimentId);
401
+ const fallback = bucket < 50 ? "control" : "variant_b";
402
+ localStorage.setItem(cacheKey, fallback);
403
+ fireExperimentExposure(experimentId, fallback, apiBase, workspaceKey);
404
+ return fallback;
405
+ }
406
+ }
407
+ /**
408
+ * Clear a cached experiment assignment (e.g. when an experiment is
409
+ * archived or completed). No-op outside the browser.
410
+ */
411
+ export function clearVariant(experimentId) {
412
+ if (isBrowser) {
413
+ localStorage.removeItem(`apex_var_${experimentId}`);
414
+ }
415
+ }
273
416
  export { createManagementClient, } from "./management";
274
417
  /**
275
418
  * Generate a stable idempotency key. Prefers `crypto.randomUUID()`
@@ -325,8 +468,8 @@ export async function sendServerEvents(config, events, options = {}) {
325
468
  "x-api-key": config.apiKey,
326
469
  "idempotency-key": idempotencyKey,
327
470
  };
328
- if (config.projectKey)
329
- headers["x-apex-project"] = config.projectKey;
471
+ if (config.workspaceKey)
472
+ headers["x-apex-workspace"] = config.workspaceKey;
330
473
  const fetchFn = typeof fetch !== "undefined" ? fetch : await loadNodeFetch();
331
474
  const res = await fetchFn(url, {
332
475
  method: "POST",
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Programmatic access to Apex APIs using an API key (same as MCP server).
3
- * Intended for Node.js backends; sends x-api-key and x-apex-project on each request.
3
+ * Intended for Node.js backends; sends x-api-key and x-apex-workspace on each request.
4
4
  */
5
5
  function baseUrl(cfg) {
6
6
  return (cfg.apiUrl ?? "http://localhost:3000").replace(/\/$/, "");
@@ -9,7 +9,7 @@ function keyHeaders(cfg) {
9
9
  return {
10
10
  "Content-Type": "application/json",
11
11
  "x-api-key": cfg.apiKey,
12
- "x-apex-project": cfg.projectKey,
12
+ "x-apex-workspace": cfg.workspaceKey,
13
13
  };
14
14
  }
15
15
  /**
@@ -21,7 +21,7 @@ export function createManagementClient(cfg) {
21
21
  const headers = keyHeaders(cfg);
22
22
  return {
23
23
  async listExperiments() {
24
- const res = await fetch(`${root}/api/experiments`, { headers });
24
+ const res = await fetch(`${root}/api/experiments?unified=true`, { headers });
25
25
  if (!res.ok) {
26
26
  const text = await res.text().catch(() => "");
27
27
  throw new Error(`Apex listExperiments failed (${res.status}): ${text}`);
@@ -31,7 +31,7 @@ export function createManagementClient(cfg) {
31
31
  async assignVariant(experimentId, visitorId) {
32
32
  const cookie = [
33
33
  `apex_vid=${encodeURIComponent(visitorId)}`,
34
- `apex_project=${encodeURIComponent(cfg.projectKey)}`,
34
+ `apex_project=${encodeURIComponent(cfg.workspaceKey)}`,
35
35
  ].join("; ");
36
36
  const res = await fetch(`${root}/api/experiments/${encodeURIComponent(experimentId)}/assign`, {
37
37
  headers: { ...headers, Cookie: cookie },
@@ -192,7 +192,7 @@ export function createManagementClient(cfg) {
192
192
  },
193
193
  // ─── Partner Network — Programs (MMP-161) ─────────────────────────
194
194
  //
195
- // Every method below runs under the merchant's x-apex-project scope.
195
+ // Every method below runs under the merchant's x-apex-workspace scope.
196
196
  // Partner-facing flows (self-signup, dashboard, Stripe Connect OAuth)
197
197
  // are cookie-authed in the portal and not wrapped in this SDK.
198
198
  async listPrograms() {
@@ -334,14 +334,14 @@ export function createManagementClient(cfg) {
334
334
  // API-key caller as a trusted server.
335
335
  preferences: {
336
336
  async get(endUserId) {
337
- const res = await fetch(`${root}/api/communications/preferences/${encodeURIComponent(endUserId)}?projectKey=${encodeURIComponent(cfg.projectKey)}`, { headers });
337
+ const res = await fetch(`${root}/api/communications/preferences/${encodeURIComponent(endUserId)}?workspaceKey=${encodeURIComponent(cfg.workspaceKey)}`, { headers });
338
338
  if (!res.ok) {
339
339
  throw new Error(`Apex preferences.get failed (${res.status}): ${await res.text().catch(() => "")}`);
340
340
  }
341
341
  return res.json();
342
342
  },
343
343
  async update(endUserId, patch) {
344
- const res = await fetch(`${root}/api/communications/preferences/${encodeURIComponent(endUserId)}?projectKey=${encodeURIComponent(cfg.projectKey)}`, {
344
+ const res = await fetch(`${root}/api/communications/preferences/${encodeURIComponent(endUserId)}?workspaceKey=${encodeURIComponent(cfg.workspaceKey)}`, {
345
345
  method: "PATCH",
346
346
  headers,
347
347
  body: JSON.stringify(patch),
@@ -403,7 +403,7 @@ export function createManagementClient(cfg) {
403
403
  * `get()` returns the current hub signal + per-step overrides
404
404
  * (read-only). `complete(stepId)` / `skip(stepId, reason)` mirror
405
405
  * the dashboard's write contract at
406
- * POST /api/workspaces/<projectKey>/setup-state/<stepId>.
406
+ * POST /api/workspaces/<workspaceKey>/setup-state/<stepId>.
407
407
  *
408
408
  * Allowed step IDs are enforced server-side via the SetupRegistry
409
409
  * allowlist. Unknown IDs return 400.
@@ -411,7 +411,7 @@ export function createManagementClient(cfg) {
411
411
  workspace: {
412
412
  setupState: {
413
413
  async get() {
414
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/setup-state`, { headers });
414
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/setup-state`, { headers });
415
415
  if (!res.ok) {
416
416
  throw new Error(`Apex workspace.setupState.get failed (${res.status}): ${await res.text().catch(() => "")}`);
417
417
  }
@@ -422,13 +422,13 @@ export function createManagementClient(cfg) {
422
422
  };
423
423
  },
424
424
  async complete(stepId) {
425
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/setup-state/${encodeURIComponent(stepId)}/complete`, { method: "POST", headers });
425
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/setup-state/${encodeURIComponent(stepId)}/complete`, { method: "POST", headers });
426
426
  if (!res.ok) {
427
427
  throw new Error(`Apex workspace.setupState.complete failed (${res.status}): ${await res.text().catch(() => "")}`);
428
428
  }
429
429
  },
430
430
  async skip(stepId, reason) {
431
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/setup-state/${encodeURIComponent(stepId)}/skip`, {
431
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/setup-state/${encodeURIComponent(stepId)}/skip`, {
432
432
  method: "POST",
433
433
  headers,
434
434
  body: JSON.stringify({ reason: reason ?? null }),
@@ -442,13 +442,13 @@ export function createManagementClient(cfg) {
442
442
  /**
443
443
  * Data Sources registry — the producers that send events into this
444
444
  * workspace (Website, iOS / Android apps, Backend). Mirrors
445
- * /api/workspaces/<projectKey>/data-sources. `dataSourceId` is
445
+ * /api/workspaces/<workspaceKey>/data-sources. `dataSourceId` is
446
446
  * reporting-only; these methods manage the registry, not access control.
447
447
  */
448
448
  dataSources: {
449
449
  async list(opts) {
450
450
  const qs = opts?.includeArchived ? "?includeArchived=true" : "";
451
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/data-sources${qs}`, { headers });
451
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/data-sources${qs}`, { headers });
452
452
  if (!res.ok) {
453
453
  throw new Error(`Apex dataSources.list failed (${res.status}): ${await res.text().catch(() => "")}`);
454
454
  }
@@ -456,7 +456,7 @@ export function createManagementClient(cfg) {
456
456
  return json.data ?? [];
457
457
  },
458
458
  async get(id) {
459
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/data-sources/${encodeURIComponent(id)}`, { headers });
459
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/data-sources/${encodeURIComponent(id)}`, { headers });
460
460
  if (!res.ok) {
461
461
  throw new Error(`Apex dataSources.get failed (${res.status}): ${await res.text().catch(() => "")}`);
462
462
  }
@@ -464,7 +464,7 @@ export function createManagementClient(cfg) {
464
464
  return json.data;
465
465
  },
466
466
  async create(params) {
467
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/data-sources`, { method: "POST", headers, body: JSON.stringify(params) });
467
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/data-sources`, { method: "POST", headers, body: JSON.stringify(params) });
468
468
  if (!res.ok) {
469
469
  throw new Error(`Apex dataSources.create failed (${res.status}): ${await res.text().catch(() => "")}`);
470
470
  }
@@ -472,7 +472,7 @@ export function createManagementClient(cfg) {
472
472
  return json.data;
473
473
  },
474
474
  async update(id, patch) {
475
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/data-sources/${encodeURIComponent(id)}`, { method: "PATCH", headers, body: JSON.stringify(patch) });
475
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/data-sources/${encodeURIComponent(id)}`, { method: "PATCH", headers, body: JSON.stringify(patch) });
476
476
  if (!res.ok) {
477
477
  throw new Error(`Apex dataSources.update failed (${res.status}): ${await res.text().catch(() => "")}`);
478
478
  }
@@ -480,13 +480,13 @@ export function createManagementClient(cfg) {
480
480
  return json.data;
481
481
  },
482
482
  async archive(id) {
483
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/data-sources/${encodeURIComponent(id)}`, { method: "DELETE", headers });
483
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/data-sources/${encodeURIComponent(id)}`, { method: "DELETE", headers });
484
484
  if (!res.ok) {
485
485
  throw new Error(`Apex dataSources.archive failed (${res.status}): ${await res.text().catch(() => "")}`);
486
486
  }
487
487
  },
488
488
  async health(id) {
489
- const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.projectKey)}/data-sources/${encodeURIComponent(id)}/health`, { headers });
489
+ const res = await fetch(`${root}/api/workspaces/${encodeURIComponent(cfg.workspaceKey)}/data-sources/${encodeURIComponent(id)}/health`, { headers });
490
490
  if (!res.ok) {
491
491
  throw new Error(`Apex dataSources.health failed (${res.status}): ${await res.text().catch(() => "")}`);
492
492
  }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  export interface ApexConfig {
2
- projectKey: string;
2
+ workspaceKey: string;
3
+ /**
4
+ * @deprecated Use `workspaceKey`. Permanent back-compat alias from
5
+ * the project→workspace rename (2026-06); existing installs passing
6
+ * `projectKey` keep working forever.
7
+ */
8
+ projectKey?: string;
3
9
  apiUrl?: string;
4
10
  /** Flush interval in ms (default: 5000) */
5
11
  flushInterval?: number;
@@ -15,15 +21,17 @@ export interface ApexConfig {
15
21
  * for ~95% of merchants. Set this when:
16
22
  *
17
23
  * - Your staging deploy lives on a custom domain that looks like
18
- * production (e.g. `app-staging.acme.com` resolves to
19
- * production but you want it billed as preview).
24
+ * production (e.g. `app-staging.acme.com` resolves to your
25
+ * staging stack but you want it sliced as preview).
20
26
  * - You want to force `localhost` in a hosted test harness.
21
- * - You're running CI smoke tests that should never bill.
27
+ * - You're running CI smoke tests that should stay out of your
28
+ * production dashboard slice.
22
29
  *
23
30
  * Accepted values: `"production"`, `"preview"`, `"localhost"`.
24
- * Server-side, `preview` and `localhost` are FREE — they don't
25
- * count toward billing or fire outbound webhooks unless the
26
- * webhook explicitly opts into those audiences.
31
+ * The environment drives dashboard slicing and the per-environment
32
+ * breakdown on the Usage page. Every ingested event counts toward
33
+ * the Events meter regardless of environment; use `testMode` (or a
34
+ * sandbox workspace) for traffic that should never bill.
27
35
  */
28
36
  environment?: "production" | "preview" | "localhost";
29
37
  }
@@ -58,8 +66,12 @@ export interface FeaturePayload {
58
66
  }
59
67
  /**
60
68
  * Initialize the Apex SDK. Must be called before track() or identify().
69
+ * Accepts `workspaceKey` (canonical) or the deprecated `projectKey`.
61
70
  */
62
- export declare function init(options: ApexConfig): void;
71
+ export declare function init(options: ApexConfig | (Omit<ApexConfig, "workspaceKey"> & {
72
+ workspaceKey?: string;
73
+ projectKey: string;
74
+ })): void;
63
75
  /**
64
76
  * Track a custom event.
65
77
  */
@@ -205,6 +217,44 @@ export declare const trackCart: {
205
217
  * Shut down the SDK — flush remaining events and stop the timer.
206
218
  */
207
219
  export declare function shutdown(): void;
220
+ /** Experiment arm returned by `getVariant`. */
221
+ export type Variant = "control" | "variant_b";
222
+ /** Per-call overrides for `getVariant`. Falls back to `init()` config. */
223
+ export interface GetVariantOptions {
224
+ /**
225
+ * Apex API base URL (no trailing slash). Defaults to the SDK's
226
+ * configured `apiUrl` (from `init()`), then to the current origin in
227
+ * the browser. Set for cross-origin customer apps.
228
+ */
229
+ apiUrl?: string;
230
+ /** Workspace key — sent as the `x-apex-workspace` header when present. */
231
+ workspaceKey?: string;
232
+ }
233
+ /**
234
+ * Resolve the experiment arm for the current visitor — the React-free
235
+ * equivalent of `useApexVariant`.
236
+ *
237
+ * Resolution order:
238
+ * 1. Preview mode (`?_apex_preview=variant_b&_apex_exp=<id>`) — author
239
+ * preview, never counted as an exposure.
240
+ * 2. Cached assignment in `localStorage` (`apex_var_<id>`).
241
+ * 3. Server assignment (`GET /api/experiments/{id}/assign?source=sdk`).
242
+ * 4. Deterministic murmur-hash of `visitorId + experimentId` (fallback).
243
+ *
244
+ * Returns `"control"` during SSR / non-browser contexts. Fires the
245
+ * canonical `experiment_exposure` event (deduped) for cases 2–4.
246
+ *
247
+ * @example
248
+ * import { getVariant } from "@apex-inc/sdk";
249
+ * const arm = await getVariant("exp_123");
250
+ * if (arm === "variant_b") renderVariant(); else renderControl();
251
+ */
252
+ export declare function getVariant(experimentId: string, opts?: GetVariantOptions): Promise<Variant>;
253
+ /**
254
+ * Clear a cached experiment assignment (e.g. when an experiment is
255
+ * archived or completed). No-op outside the browser.
256
+ */
257
+ export declare function clearVariant(experimentId: string): void;
208
258
  export { createManagementClient, type ManagementConfig, type AssignVariantResult, type CommChannel, type EndUserCommPreferences, type InboxNotification, type ApexDataSourceKind, type ApexDataSourceStatus, type ApexDataSource, type ApexDataSourceHealth, type ApexHostSeen, type ApexAnalyticsSources, } from "./management";
209
259
  /**
210
260
  * Configuration for server-side event delivery.
@@ -218,10 +268,10 @@ export interface ServerEventsConfig {
218
268
  */
219
269
  apiUrl?: string;
220
270
  /**
221
- * When your org has multiple projects, set this to disambiguate.
222
- * Optional — Apex auto-picks if the org has exactly one project.
271
+ * When your org has multiple workspaces, set this to disambiguate.
272
+ * Optional — Apex auto-picks if the org has exactly one workspace.
223
273
  */
224
- projectKey?: string;
274
+ workspaceKey?: string;
225
275
  }
226
276
  /**
227
277
  * A single server-side event in the Apex Spec shape.
@@ -256,7 +306,7 @@ export interface ServerEventsResponse {
256
306
  deduped?: boolean;
257
307
  };
258
308
  metadata?: {
259
- projectKey?: string;
309
+ workspaceKey?: string;
260
310
  idempotencyKey?: string;
261
311
  batchSize?: number;
262
312
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}