Reference

SDK API reference

Every function on the global window.releaseo runtime — signatures, parameters, return values, and copy-paste examples for lifecycle, identity, widget controls, analytics, consent, host actions, and events.

The Releaseo SDK exposes a single runtime object. Once the script loads, every function lives on window.releaseo. When you import the npm package, the default export is the same runtime with the same methods.

// CDN — the loader assigns the runtime to window.releaseo
window.releaseo.init({ publishKey: "pk_live_xxx" });

// npm — the default export IS the runtime
import releaseo from "@releaseo/sdk-core";
releaseo.init({ publishKey: "pk_live_xxx" });

Loading and readiness

The widget initializes asynchronously: init() fetches your project config and mounts the launcher. You do not need to wait before calling other methods — the SDK queues calls made before it is ready and replays them in order once the runtime and bridge are live. For non-blocking CDN loads, ship the stub queue so even pre-load calls are buffered:

<script>
  // Stub queue — buffers calls until the SDK script finishes loading.
  window.releaseo = window.releaseo || { _q: [] };
  ["init", "identify", "open", "openFocused", "close", "track", "on", "off"].forEach(
    function (m) {
      window.releaseo[m] =
        window.releaseo[m] ||
        function () {
          window.releaseo._q.push([m, [].slice.call(arguments)]);
        };
    },
  );
</script>
<script src="https://cdn.releaseo.io/sdk/v0/loader.js" async></script>
<script>
  window.releaseo.init({ publishKey: "pk_live_xxx" });
</script>

Methods that return a Promise resolve once the underlying action completes. They never reject for normal control flow, so fire-and-forget with void is safe:

void window.releaseo.open();

Method index

MethodGroupSummary
init(config)LifecycleInitialize the runtime and mount the launcher.
endpoint(url)LifecyclePoint the SDK at a different API base URL at runtime.
reset()LifecycleTear down the iframe, launcher, identity, and state.
identify(userId, traits?)IdentityAttach the signed-in viewer to the session.
logout()IdentityClear identity and switch to anonymous mode.
open()WidgetOpen the drawer on its default tab bar.
openFocused(tab)WidgetOpen the drawer directly on one tab.
close()WidgetClose the drawer.
track(event, payload?)AnalyticsSend a custom analytics event.
consentPrivacyRead the current consent state.
setConsent(state)PrivacyUpdate consent at runtime (GDPR).
purgeAll()PrivacyErase all persisted SDK data (right to erasure).
registerAction(key, handler)Host actionsWire a widget Home action to host-app code.
unregisterAction(key)Host actionsRemove a registered host-action handler.
on(event, handler)EventsSubscribe to a runtime event.
off(event, handler)EventsUnsubscribe a runtime event handler.
setMockData(posts)PreviewSwap in mock changelog data.
setMockFeatureRequests(items)PreviewSwap in mock feature-request data.
settingsDiagnosticsRead the resolved runtime snapshot.

Lifecycle

init()

init(config: ReleaseoInitConfig): void

Initializes the runtime, fetches /sdk/config for your project, and mounts the launcher when the widget is enabled in dashboard settings. Call it once, as early as possible. See the ReleaseoInitConfig reference for every option.

Parameters

ParameterTypeDescription
configReleaseoInitConfigAt minimum a publishKey. All other fields are optional and resolved from dashboard settings.

Returns void

window.releaseo.init({
  publishKey: "pk_live_xxx",
  theme: "auto",      // "auto" | "light" | "dark"
  position: "right",  // "left" | "right"
  locale: "en",
  debug: false,
});

endpoint()

endpoint(endpoint: string): Promise<void>

Updates the API base URL after init(). Use this for self-hosted backends or to switch environments without re-initializing. The backward-compatible apiHost init option does the same thing at boot.

Parameters

ParameterTypeDescription
endpointstringAbsolute base URL of the Releaseo API.

Returns Promise<void> — resolves once the new endpoint is applied.

await window.releaseo.endpoint("https://api.example.com");

reset()

reset(): void

Full teardown — clears identity, closes the widget, removes the launcher and iframe from the DOM, and returns internal state to IDLE. After reset() you can call init() again with a fresh configuration. Use it for tenant, organization, or project switches that need a completely clean session.

Returns void

window.releaseo.reset();
window.releaseo.init({ publishKey: "pk_live_other_tenant" });

Identity

identify()

identify(userId: string | number, properties?: ReleaseoIdentifyProperties): Promise<void>

Attaches the current signed-in viewer to the SDK session and opens an authenticated widget session. Call it as soon as your app knows who the user is. Identity is persisted (default TTL 30 days, configurable via identityTtl) so it survives refreshes.

Parameters

ParameterTypeDescription
userIdstring | numberYour stable user identifier.
propertiesReleaseoIdentifyPropertiesOptional flat traits. Values must be string, number, boolean, null, or undefined — no nested objects or arrays.

Recognized traits include email, name, tenantId, and userHash. See ReleaseoIdentifyProperties.

Returns Promise<void>

await window.releaseo.identify("u_123", {
  tenantId: "t_456",
  email: "[email protected]",
  name: "Amina",
  userHash: "server-generated-hmac", // optional, see below
});

logout()

logout(): void

Clears the current identity and session. The widget stays mounted but switches to anonymous mode; persisted identity is removed from localStorage and a fresh anonymous ID is minted on the next interaction. Call it when a user signs out.

Returns void

window.releaseo.logout();

Widget controls

open()

open(): Promise<void>

Opens the widget drawer with its full tab bar. Required when the dashboard trigger mode is set to “Only manually”; otherwise the launcher handles opening for you.

Returns Promise<void> — resolves once the drawer is open.

void window.releaseo.open();

openFocused()

openFocused(tab: ReleaseoFocusableTab): Promise<void>

Opens the drawer directly on a single tab, with the tab bar hidden — ideal for a dedicated “What’s new” button, an embedded help launcher, or a marketing CTA that should deep-link to one surface. The drawer returns to its default (full tab bar) the next time open() is called after close().

Parameters

ParameterTypeDescription
tabReleaseoFocusableTabOne of "home", "changelog", "feature_requests", "roadmap", "help".

Returns Promise<void>

// Deep-link a "What's new" button straight to the changelog feed
document.querySelector("#whats-new")?.addEventListener("click", () => {
  void window.releaseo.openFocused("changelog");
});

close()

close(): void

Closes the widget drawer.

Returns void

window.releaseo.close();

Analytics

track()

track(eventName: string, payload?: Record<string, unknown>): Promise<void>

Sends a custom analytics event. Events appear in dashboard analytics and can be forwarded to selected integrations (PostHog, Webhook Out). Use it to record product moments worth correlating with widget engagement.

Parameters

ParameterTypeDescription
eventNamestringA stable, snake_case-friendly event name.
payloadRecord<string, unknown>Optional structured properties for the event.

Returns Promise<void>

await window.releaseo.track("billing_limit_reached", {
  plan: "pro",
  source: "settings",
});

GDPR / ePrivacy controls for telemetry and persistent storage. Default consent is "granted", so existing integrations need no changes.

readonly consent: ConsentState

Read-only property holding the current consent state — "granted", "denied", or "pending".

console.log(window.releaseo.consent); // "granted" | "denied" | "pending"

setConsent()

setConsent(state: ConsentState): Promise<void>

Updates the consent state at runtime — wire it to your cookie banner.

StatelocalStorageAnalytics
"granted"read + writesent normally (queued telemetry is flushed)
"pending"memory onlyqueued, not sent
"denied"memory onlydropped; persistence stays off

Parameters

ParameterTypeDescription
stateConsentState"granted", "denied", or "pending".

Returns Promise<void>

// Initialize deferred, then grant after the user accepts the banner
window.releaseo.init({ publishKey: "pk_live_xxx", consent: "pending" });
window.releaseo.setConsent("granted");

purgeAll()

purgeAll(): Promise<void>

GDPR Article 17 (right to erasure). Best-effort wipe of all persisted SDK data: host-side localStorage/sessionStorage keys, queued telemetry, the in-memory identity, and widget-side storage. The user becomes anonymous, the SDK stays mounted, and the promise never rejects.

Returns Promise<void>

// Segment-style reset: wipe everything, mint a fresh anonymous id
await window.releaseo.purgeAll();

// Strict erasure — leave zero releaseo:* keys behind
await window.releaseo.setConsent("denied");
await window.releaseo.purgeAll();

Host actions

A “host action” lets a whitelisted widget Home button trigger code in your app — for example opening your existing support chat. The dashboard stores only an action key; it never stores or executes raw JavaScript.

registerAction()

registerAction(actionKey: string, handler: ReleaseoWidgetActionHandler): void

Registers a handler for a host action key configured in the dashboard.

Parameters

ParameterTypeDescription
actionKeystringThe key configured on the widget Home action.
handlerReleaseoWidgetActionHandlerReceives { actionKey, actionId, label } and may return a Promise.

Returns void

window.releaseo.registerAction("open_chat", async ({ actionKey, actionId, label }) => {
  window.Intercom?.("show");
  console.info("Releaseo action", { actionKey, actionId, label });
});

unregisterAction()

unregisterAction(actionKey: string): void

Removes a previously registered host-action handler — call it when the owning app shell unmounts.

Parameters

ParameterTypeDescription
actionKeystringThe key passed to registerAction().

Returns void

window.releaseo.unregisterAction("open_chat");

Events

Subscribe to runtime lifecycle events for custom host behavior — badge counts, analytics bridges, or recovery handling.

on()

on<K extends keyof ReleaseoEventMap>(eventName: K, handler: (payload: ReleaseoEventMap[K]) => void): void

Subscribes a handler to a runtime event.

Returns void

window.releaseo.on("ready", () => console.log("Releaseo is ready"));

window.releaseo.on("unreadChange", (count) => {
  document.querySelector("#badge")?.replaceChildren(String(count));
});

window.releaseo.on("error", (error) => console.error("[Releaseo]", error));

off()

off<K extends keyof ReleaseoEventMap>(eventName: K, handler: (payload: ReleaseoEventMap[K]) => void): void

Unsubscribes a previously registered handler. Pass the same function reference you gave to on().

Returns void

const onUnread = (count: number) => updateBadge(count);
window.releaseo.on("unreadChange", onUnread);
// later…
window.releaseo.off("unreadChange", onUnread);

Event reference

EventPayloadFires when
readyvoidThe runtime has initialized and is usable.
unreadChangenumberThe unread announcement count changes.
errorErrorA non-fatal runtime error occurs.
stateChangeSDKStateThe internal state machine transitions.
identityChange{ userId, previousUserId }The identified user changes.
identityErrorErrorIdentity handoff (e.g. userHash) fails.
widgetAction{ actionKey, actionId, label }A host action is requested from the widget.
bridge:readyvoidThe iframe bridge connects.
bridge:lostvoidThe iframe bridge disconnects.
bridge:recoveredvoidThe iframe bridge reconnects after a loss.

Preview and mock data

Swap in mock content for demos, local development, and dashboard previews without reloading. After init(), these update the widget immediately.

setMockData()

setMockData(posts: ReleaseoChangelogListItem[]): void

Replaces the changelog posts shown in the widget.

Returns void

setMockFeatureRequests()

setMockFeatureRequests(featureRequests: ReleaseoFeatureRequestListItem[]): void

Replaces the feature-request items shown in the widget.

Returns void

window.releaseo.setMockFeatureRequests([
  {
    id: "fr_1",
    projectId: "proj_demo",
    kind: "feature_request",
    title: "Clearer export labels",
    description: "Let customers request clearer export names.",
    status: "open",
    reviewStatus: "approved",
    upvotes: 12,
    downvotes: 0,
    score: 12,
    commentCount: 0,
    authorName: "Anonymous",
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
  },
]);

Diagnostics

settings

readonly settings: ReleaseoSettingsSnapshot | undefined

Read-only snapshot of the resolved configuration and live runtime state. undefined until init() has resolved. Useful for debugging and for reading values like the current unread count or session state.

Frequently used fields

FieldTypeDescription
stateSDKStateCurrent state-machine value (e.g. "IDENTIFIED", "OPENED").
unreadCountnumberCurrent unread announcement count.
hasSessionbooleanWhether an authenticated session is active.
bridgeReadybooleanWhether the iframe bridge is connected.
consentConsentStateEffective consent state.
useridstring | number | nullThe identified user id, or null when anonymous.
anonymousIdstringThe current anonymous id.
versionstringRuntime version.
theme / position / localeResolved widget presentation settings.
console.log(window.releaseo.settings?.unreadCount); // e.g. 8
console.log(window.releaseo.settings?.state);       // e.g. "IDENTIFIED"

Type reference

ReleaseoInitConfig

FieldTypeDefaultDescription
publishKeystringProject publish key. Required unless mock content is provided.
endpointstringReleaseo APIPreferred API base URL. Takes precedence over apiHost.
apiHoststringBackward-compatible alias for endpoint.
widgetUrlstringReleaseo CDNOverride only for self-hosted or local dev.
analyticsEndpointstringsame as endpointAnalytics ingestion endpoint.
productIdstringfrom /sdk/configOverride only if needed.
theme"auto" | "light" | "dark"dashboardWidget theme preference.
position"left" | "right"dashboardLauncher / drawer position.
localestringdashboardWidget locale.
debugbooleanfalseVerbose runtime diagnostics and dev warnings.
consentConsentState"granted"Telemetry/storage consent (GDPR).
respectDoNotTrackbooleanfalseTreat navigator.doNotTrack as "denied".
styleNoncestringCSP nonce for injected host <style> tags.
identityTtlnumber2_592_000_000Persisted-identity lifetime in ms (30 days).
mockPostsReleaseoChangelogListItem[]Bypass the API and serve these changelog posts.
mockFeatureRequestsReleaseoFeatureRequestListItem[]Bypass the API and serve these feature requests.

ReleaseoIdentifyProperties

type TraitValue = string | number | boolean | null | undefined;
type ReleaseoIdentifyProperties = Record<string, TraitValue>;

Flat key/value traits only — nested objects and arrays are not allowed. Reserved keys with special handling: email, name, tenantId, and userHash (the server-generated HMAC for trusted identity).

ReleaseoFocusableTab

type ReleaseoFocusableTab =
  | "home"
  | "changelog"
  | "feature_requests"
  | "roadmap"
  | "help";

The strict set of tabs accepted by openFocused(). feedback and messages are widget tabs but are not navigable content views, so they are intentionally excluded.

ConsentState

type ConsentState = "granted" | "denied" | "pending";

ReleaseoEventMap

interface ReleaseoEventMap {
  ready: void;
  unreadChange: number;
  error: Error;
  stateChange: SDKState;
  identityChange: { userId: string; previousUserId: string | null };
  identityError: Error;
  widgetAction: { actionKey: string; actionId: string; label: string };
  "bridge:ready": void;
  "bridge:lost": void;
  "bridge:recovered": void;
}
Was this page helpful?