Документация публикуется на английском языке.

DocumentationSign in

The drop-in component

A launcher, an SRI-pinned script, and two backend routes you still have to write.

What it is

<unifyid-continue> is a custom element published as @vn.unifyid/connect. It renders the Continue with UnifyID control and launches the flow.

It is a launcher, never a consent surface. Consent always renders on a UnifyID-owned page. There are zero iframes: the element opens a popup, falls back to a redirect when the popup is blocked, and deliberately uses redirect on mobile and narrow screens.

The postMessage traffic between the popup and your page carries completion and state only — never tokens. A browser message on its own never authorizes anything.

Loading it, pinned

Assets are SRI-pinned and immutable per version. Load the script with its integrity hash on both the initiating page and the registered callback page, before anything uses window.UnifyID. The script contains no client secret.

Generated from the release bytes — v1.5.2
<script src="https://developers.staging.unifyid.io/sdk/unifyid-connect/v1.5.2/unifyid-connect.js"
  integrity="sha384-R9C2QH49DGZzSpAWlx7+OlGJPFDqWRFcV6b8F2IN8upEhSWwicvh2lsagcWRYe10"
  crossorigin="anonymous" defer></script>

<unifyid-continue
  start-url="/api/auth/unifyid/start"
  scopes="openid profile email"
  mode="popup"></unifyid-continue>

Allow the pinned asset origin in your CSP and preserve cross-origin CORS headers on the asset, or SRI will refuse it. Use same-origin-allow-popups on the initiating page's opener policy and do not sever the callback's opener.

The two routes you must provide

The component is not a drop-in *integration*. It is a drop-in *button*. The code exchange uses your client secret, so it happens on your server, in routes you write.

POST /api/auth/unifyid/start

receives
{ scopes, purpose, display }.
must do
Validate the origin. Enforce the scopes and purpose you configured rather than trusting what arrived. Generate state, nonce and the PKCE pair server-side and bind them to an HTTP-only browser cookie.
returns
{ authorizationUrl, state, callbackOrigin }. state must be at least 32 characters of cryptographic randomness and match the authorization URL exactly; callbackOrigin must equal the initiating application's origin.

POST /api/auth/unifyid/complete

receives
{ state, code, error, errorDescription }.
must do
Atomically consume the unexpired, browser-bound transaction. Exchange the code server-side. Validate issuer, audience, signature, nonce and expiry. Create the application session.
returns
{ completed: true } only after the session exists. A denial returns { completed: false, error: "access_denied" }. Other failures use a non-success status and carry no secrets.
On the callback page
await window.UnifyID.completeServerBoundCallback({
  completionUrl: "/api/auth/unifyid/complete",
});

// Verify your own session endpoint before showing anything protected,
// then navigate to a fixed destination. This also finishes the redirect
// fallback, where there is no opener at all.
await fetch("/api/session");
On the initiating page
const button = document.querySelector("unifyid-continue");

button.addEventListener("unifyid:success", async () => {
  // A browser event is not authorization. Ask your own server.
  const session = await fetch("/api/session").then((r) => r.json());
  if (session.signedIn) location.assign("/app");
});

button.addEventListener("unifyid:cancel", () => showRetry());
button.addEventListener("unifyid:error", (event) => showError(event.detail));

A runnable reference lives at examples/hosted-server-bound/ in the developer portal repository. Its in-memory persistence is local-only and must be replaced before you deploy.

What this does not do

  • Cross-host handoff is not implemented. A popup cannot create cookies on another tenant host. Start, callback and completion must be same-origin. If you need a cross-host handoff you are building and reviewing it yourself — and relaying access tokens or widening cookie domains is not the shortcut it looks like.
  • Legacy `client-id` / `redirect-uri` attributes still exist for migration only. New web integrations use the server-bound flow above.
  • Never deploy the localhost snippet. The production asset origin is an https origin your deployment operator confirms.

Verified against API commit 234dba22 on 2026-10-18. The routes, scopes, checklist, events and limits on these pages are read from that export, not typed.