# ElvixSessions

> Live session list scoped per-app or per-account, with per-row revoke and a two-CTA mass-revoke confirm pane.

<!-- app/security/sessions/page.tsx -->
```tsx
"use client";

import { ElvixSessions } from "@elvix.is/sdk/react";

export default function SecuritySessionsPage() {
  return (
        <ElvixSessions
      appId={process.env.NEXT_PUBLIC_ELVIX_CLIENT_ID}
      signInUrl="/sign-in"
      onChanged={() => {
        // Refetch any host-side session count or device badge.
      }}
    />
  );
}
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `appId` | `string` | optional | `undefined` | The app whose sessions to list. Accepts EITHER your public clientId (the same one you pass `<ElvixProvider>`) OR the internal Application.id. **Set this on every customer app** so the list reaches the app-scoped endpoint cross-origin. Omit ONLY on elvix's own first-party account surface. |
| `signInUrl` | `string` | optional | `/sign-in/account` | Where the SDK navigates after the sign-out-everywhere path completes. |
| `onChanged` | `() => void` | optional | `undefined` | Fires after any successful revoke so the host can refetch ambient counts. |
| `onResult` | `(r: ElvixSessionsResult) => void` | optional | `undefined` | Terminal callback per revoke attempt. Carries `action` kind and `ended` count on success. No session IDs leak to the host. |

> **Note:** The sign-out-everywhere path navigates to `signInUrl` because the current session is gone. `onResult` still fires with `ok: true` before navigation, so any host-side cleanup runs first. The sign-out-others path keeps the current session and resolves with an in-frame done pane.

## Reacting to terminal results

`onResult` is a discriminated union. The success branch carries `action` (the revoke kind) and `ended` (the number of closed sessions). Use it to redirect after the sign-out-everywhere path, since the current session is gone and the in-frame done pane cannot be reached.

<!-- app/security/sessions/page.tsx (with onResult) -->
```tsx
"use client";

import { ElvixSessions } from "@elvix.is/sdk/react";
import { useRouter } from "next/navigation";

export default function SecuritySessionsPage() {
  const router = useRouter();
  return (
        <ElvixSessions
      appId={process.env.NEXT_PUBLIC_ELVIX_CLIENT_ID}
      signInUrl="/sign-in"
      onResult={(r) => {
        if (!r.ok) {
          console.warn("sessions revoke failed", r.error, r.message);
          return;
        }
        if (r.action === "sign_out_all") {
          router.push("/sign-in");
        }
      }}
    />
  );
}
```


## Related

- [Ban / pause / delete watcher](/docs/components/elvix-lifecycle-watcher.md): Mount once in any authenticated layout. When the user's membership flips off active, the watcher paints a full-screen blocking modal with a 9-second countdown, then signs them out and redirects.
- [ElvixExport](/docs/components/elvix-export.md): In-frame OTP-gated GDPR data export wizard (preview, send-to, otp, done) for identity or per-app scope.
