# ElvixExport

> In-frame OTP-gated GDPR data export wizard (preview, send-to, otp, done) for identity or per-app scope.

<!-- app/account/export/page.tsx -->
```tsx
"use client";

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

export default function ExportPage() {
  return (
        <ElvixExport
      target={{ kind: "identity" }}
      onResult={(r) => {
        if (!r.ok) return console.warn(r.error, r.message);
        console.info("Export sent to", r.deliveredTo, "id:", r.downloadId);
      }}
    />
  );
}
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `target` | `{ kind: "identity" } \| { kind: "app"; appId: string; appName: string }` | optional | `{ kind: "identity" }` | Export scope. Locked at mount: to switch scope, unmount and remount. |
| `primaryEmail` | `string` | optional | session email | Delivery inbox for the zip. Falls back to `useElvixAppContext().user.email`. |
| `onSuccess` | `(downloadId: string) => void` | optional | (none) | Fires before the in-frame done pane. If the host navigates or unmounts, the done pane is skipped (host wins). |
| `onFail` | `(error: string) => void` | optional | (none) | Notification hook. Fires alongside the in-frame error pane. |
| `onResult` | `(r: ElvixExportResult) => void` | optional | (none) | Unified discriminated-union callback for every terminal outcome. Success carries `downloadId` + `deliveredTo`, failure carries `error` + optional `message`. |

> **Note:** `target` is locked at mount. The scope chooser (identity vs per-app) belongs in your route, not inside the SDK. Unmount and remount with a new `target` to switch.

> **Warning:** The download link is single-use and expires 24h after issue. The zip is also emailed as an attachment to `deliveredTo`, so users who lose the in-frame link still have a copy. Don't surface `downloadId` outside the OTP-verified session.

## Per-app scope

Pass `appId` + `appName` for a per-app archive, and optionally override the delivery inbox.

<!-- app/account/export/[appId]/page.tsx -->
```tsx
<ElvixExport
  target={{ kind: "app", appId: "app_01H...", appName: "Buildza" }}
  primaryEmail="edvard@021.is"
/>
```


## Related

- [ElvixSessions](/docs/components/elvix-sessions.md): Live session list scoped per-app or per-account, with per-row revoke and a two-CTA mass-revoke confirm pane.
- [ElvixDeactivate](/docs/components/elvix-deactivate.md): State-aware Instagram-style temporary deactivation wizard with OTP gate for deactivate and one-click reactivate.
