> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ozura.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> Complete reference for OzVault, OzElement, all options, events, and TypeScript types.

***

## OzVault

The main SDK entry point. Manages all payment fields and vault credentials.

<Note>
  Always create `OzVault` via the **async static factory** `OzVault.create()`. Never call `new OzVault(...)` directly.
</Note>

### OzVault.create

```ts theme={null}
OzVault.create(options: VaultOptions, signal?: AbortSignal): Promise<OzVault>
```

Initializes the vault, fetches a session, and loads the payment iframes. Resolves once the session is ready — you can create and mount elements immediately after. The vault is ready to tokenize once `onReady` fires (or `vault.isReady === true`).

The optional `signal` parameter is an `AbortSignal` for advanced teardown scenarios. The React `<OzElements>` provider handles this automatically.

<Warning>
  **`onReady` can fire while `OzVault.create()` is still pending.** Vault initialization runs multiple steps in parallel. The `onReady` callback may fire while `await OzVault.create(...)` is still in progress, at which point the `vault` variable is still `undefined`. Do not reference `vault` (or call `vault.createElement()`) inside `onReady`. Declare readiness flags before calling `create()` so they are accessible when the callback runs.
</Warning>

### VaultOptions

```ts theme={null}
type VaultOptions = {
  pubKey?:             string;                                   // required for production vault keys; omit for test vault keys
  sessionUrl?:         string;                                   // required (one of these three)
  getSessionKey?:      (sessionId: string) => Promise<string>;  // required (one of these three)
  fetchWaxKey?:        (sessionId: string) => Promise<string>;  // deprecated — use sessionUrl or getSessionKey
  frameBaseUrl?:       string;                                   // default: 'https://elements.ozura.com'
  fonts?:              FontSource[];
  appearance?:         Appearance;
  onLoadError?:        () => void;
  loadTimeoutMs?:      number;                                   // default: 10000 (ms); requires onLoadError
  onSessionRefresh?:   () => void;
  onReady?:            () => void;
  sessionLimit?:       number | null;                            // default: 3; null = no cap; must match server createSession call
  debug?:              boolean;                                  // default: false; enables [OzVault] console.log output
};
```

| Option             | Type                                     | Required | Default                      | Description                                                                                                                                                                                                |
| ------------------ | ---------------------------------------- | -------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pubKey`           | `string`                                 | ²        | —                            | Your Vault pub key                                                                                                                                                                                         |
| `sessionUrl`       | `string`                                 | ✅ ¹      | —                            | URL of your session endpoint. Simplest option — pass the path and the SDK handles everything.                                                                                                              |
| `getSessionKey`    | `(sessionId: string) => Promise<string>` | ✅ ¹      | —                            | Custom callback for obtaining a session key. Use when you need custom headers or auth logic.                                                                                                               |
| `fetchWaxKey`      | `(sessionId: string) => Promise<string>` | ✅ ¹      | —                            | **Deprecated.** Use `sessionUrl` or `getSessionKey` instead.                                                                                                                                               |
| `frameBaseUrl`     | `string`                                 | —        | `https://elements.ozura.com` | Override where iframe assets are served from                                                                                                                                                               |
| `fonts`            | `FontSource[]`                           | —        | `[]`                         | Custom web fonts to load inside iframes                                                                                                                                                                    |
| `appearance`       | `Appearance`                             | —        | —                            | Global theme and CSS variable overrides                                                                                                                                                                    |
| `onLoadError`      | `() => void`                             | —        | —                            | Called if the vault fails to load within `loadTimeoutMs`                                                                                                                                                   |
| `loadTimeoutMs`    | `number`                                 | —        | `10000`                      | **Requires `onLoadError` to be set.** Setting this without `onLoadError` is silently ignored.                                                                                                              |
| `onSessionRefresh` | `() => void`                             | —        | —                            | Called when the SDK silently refreshes the session during a tokenization attempt                                                                                                                           |
| `onReady`          | `() => void`                             | —        | —                            | Called once when the vault is ready (vanilla JS). In React use `useOzElements().ready` instead.                                                                                                            |
| `sessionLimit`     | `number \| null`                         | —        | `3`                          | Max successful `createToken`/`createBankToken` calls per session before auto-refresh. Pass `null` to remove the cap. Must match the `sessionLimit` value passed to `ozura.createSession()` on your server. |
| `debug`            | `boolean`                                | —        | `false`                      | Enables structured `[OzVault]`-prefixed `console.log` output at every lifecycle event. Safe to use in production — no sensitive data is ever logged. See [Debug mode](#debug-mode).                        |

¹ Exactly one of `sessionUrl`, `getSessionKey`, or `fetchWaxKey` is required.

² `pubKey` is required when using a **production** vault API key. If your vault API key was created for the test/sandbox environment, you can omit `pubKey` entirely.

### Properties

| Property        | Type      | Description                                                                                                                                                                                                                                                                                                       |
| --------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isReady`       | `boolean` | `true` once the vault is ready to tokenize. In vanilla JS, gate your submit button on this **plus** each element's `'ready'` event. In React, use `useOzElements().ready` instead — it combines both checks automatically.                                                                                        |
| `tokenizeCount` | `number`  | Count of successful `createToken()`/`createBankToken()` calls in the current session. Resets to `0` on every session refresh. Use this to display remaining-attempt feedback or gate the submit button once `sessionLimit` is exhausted. In React, prefer `useOzElements().tokenizeCount` — it is reactive state. |

### Methods

#### createElement

```ts theme={null}
vault.createElement(type: ElementType, options?: ElementOptions): OzElement
```

Creates a card input element. Call `.mount()` on the result to attach it to the DOM.

**ElementType values:** `'cardNumber'` | `'expirationDate'` | `'cvv'`

#### getElement

```ts theme={null}
vault.getElement(type: ElementType): OzElement | null
```

Returns the existing element of the given type, or `null`.

#### createBankElement

```ts theme={null}
vault.createBankElement(type: BankElementType, options?: ElementOptions): OzElement
```

Creates a bank account input element.

**BankElementType values:** `'accountNumber'` | `'routingNumber'`

#### getBankElement

```ts theme={null}
vault.getBankElement(type: BankElementType): OzElement | null
```

Returns the existing bank element of the given type, or `null`.

#### createToken

```ts theme={null}
vault.createToken(options?: TokenizeOptions): Promise<TokenResponse>
```

Tokenizes all mounted card elements. Throws `OzError` on failure.

<Note>
  **Tokenization timeout:** If the vault does not respond within **30 seconds**, `createToken()` rejects with an `OzError` (`errorCode: 'timeout'`). This timeout is separate from the element iframe load timeout (`loadTimeoutMs`) and is not configurable.
</Note>

#### createBankToken

```ts theme={null}
vault.createBankToken(options: BankTokenizeOptions): Promise<BankTokenResponse>
```

Tokenizes all mounted bank elements. Throws `OzError` on failure. Same 30-second timeout applies.

#### destroy

```ts theme={null}
vault.destroy(): void
```

Cleans up all payment field iframes and listeners. Call this when the checkout component unmounts.

#### reset

```ts theme={null}
vault.reset(): void
```

Clears all mounted card and bank element fields without destroying the vault, refreshing the session, or resetting the tokenization budget.

Call this after a declined or failed payment so the customer can re-enter their card details on the same checkout screen. The session key, its remaining budget, and all mounted iframes are fully preserved — no network calls are made.

After `reset()`, every mounted element emits a `change` event with `{ complete: false, valid: false, empty: true }`. These events arrive asynchronously (via `postMessage` from the iframes), but in practice they land well before the user can interact with the cleared fields. Any submit-button gating logic that listens to `change` events will automatically re-disable the button — no manual state reset is required, though resetting your own flags immediately after `vault.reset()` is harmless defensive practice.

<Note>
  **Session model:** by design, one session covers the full checkout. The default `sessionLimit: 3` gives you two declined attempts and one final attempt on the same session. Use `vault.reset()` between declines instead of `vault.destroy()` + recreate — that would unnecessarily refresh the session and discard remaining budget.
</Note>

```ts theme={null}
try {
  const { token, cvcSession } = await vault.createToken({ billing });
  await chargeCard(token, cvcSession);
} catch (err) {
  vault.reset();                   // clear fields; let the customer re-enter
  showError(err instanceof OzError ? err.message : 'Payment failed.');
}
```

#### debugState

```ts theme={null}
vault.debugState(): Record<string, unknown>
```

Returns a structured snapshot of the vault's internal state. Always available regardless of whether `debug: true` is set. Safe to log or attach to a support ticket — no sensitive data is returned.

```ts theme={null}
console.log(vault.debugState());
// {
//   vaultId: 'vault_abc12...',
//   isReady: true,
//   tokenizing: null,
//   destroyed: false,
//   waxKeyPresent: true,
//   tokenizeSuccessCount: 1,
//   maxTokenizeCalls: 3,
//   resetCount: 0,
//   elements: ['cardNumber', 'expirationDate', 'cvv'],
//   bankElements: [],
//   completionState: { 'a1b2c3d4': true, 'e5f6a7b8': true, 'c9d0e1f2': false },
//   pendingTokenizations: 0,
//   pendingBankTokenizations: 0,
// }
```

***

## OzElement

Returned by `createElement()` and `createBankElement()`. Represents a single input field.

### Properties

| Property  | Type                             | Description                       |
| --------- | -------------------------------- | --------------------------------- |
| `type`    | `ElementType \| BankElementType` | The element type                  |
| `isReady` | `boolean`                        | `true` once the iframe has loaded |

### Methods

#### mount

```ts theme={null}
el.mount(target: string | HTMLElement): void
```

Attaches the iframe to the DOM. `target` can be a CSS selector string or an `HTMLElement`.

#### unmount

```ts theme={null}
el.unmount(): void
```

Removes the iframe from the DOM and resets internal state, but does **not** destroy the element. The element can be re-mounted after calling `unmount()`. Use `destroy()` for permanent teardown.

#### on

```ts theme={null}
el.on(event: ElementEvent, callback: (payload?) => void): this
```

Registers an event listener. Returns `this` for chaining.

#### off

```ts theme={null}
el.off(event: ElementEvent, callback: (payload?) => void): this
```

Removes a previously registered event listener.

#### once

```ts theme={null}
el.once(event: ElementEvent, callback: (payload?) => void): this
```

Registers a one-time event listener that fires once then removes itself.

#### update

```ts theme={null}
el.update(options: Partial<ElementOptions>): void
```

Updates element options (style, placeholder, disabled) without re-mounting the iframe.

Style update semantics:

* Properties you include are merged into the current style — they replace their previous values.
* Properties previously set but **absent** from the new `style` object **retain their current values** (no keys are cleared by omission).
* To reset a specific property, pass it explicitly with an empty string: `{ base: { color: '' } }`.
* To fully reset all styles, destroy and recreate the element.
* Vault-level appearance theme styles are always preserved underneath — per-element style merges on top.

#### focus

```ts theme={null}
el.focus(): void
```

Programmatically focuses the input inside the iframe.

#### blur

```ts theme={null}
el.blur(): void
```

Programmatically blurs the input.

#### clear

```ts theme={null}
el.clear(): void
```

Clears the current value.

#### destroy

```ts theme={null}
el.destroy(): void
```

Permanently removes the iframe, clears all event handlers, and prevents future use. Distinct from `unmount()`.

***

## Events

```ts theme={null}
type ElementEvent = 'ready' | 'change' | 'focus' | 'blur' | 'loaderror';
```

### change

```ts theme={null}
el.on('change', (event: ElementChangeEvent) => void)
```

Fired whenever the value or state changes.

```ts theme={null}
type ElementChangeEvent = {
  empty:      boolean;    // true when the field has no input
  complete:   boolean;    // field has reached the required length/format — does NOT imply valid (check `valid` separately)
  valid:      boolean;    // value passes full validation (Luhn, expiry in future, etc.)
  error?:     string;     // human-readable error message, or undefined
  cardBrand?: string;     // card brand (cardNumber element only)
  month?:     string;     // parsed month '01'–'12' (expirationDate element only)
  year?:      string;     // parsed 2-digit year e.g. '27' (expirationDate element only)
};
```

### focus / blur

```ts theme={null}
el.on('focus', () => void)
el.on('blur',  (data: { empty: boolean, complete: boolean, valid: boolean, error: string | undefined }) => void)
```

Fired when the iframe input gains or loses focus. The `blur` callback receives the current field state.

### ready

```ts theme={null}
el.on('ready', () => void)
```

Fired once the iframe has fully loaded and is interactive.

### loaderror

```ts theme={null}
el.on('loaderror', (data: { elementType: string, error: string }) => void)
```

Fired if the iframe fails to load within `loadTimeoutMs`. Receives the element type and an error message.

***

## TokenizeOptions

```ts theme={null}
type TokenizeOptions = {
  billing?:   BillingDetails;
  firstName?: string;   // deprecated — use billing.firstName
  lastName?:  string;   // deprecated — use billing.lastName
};
```

## TokenResponse

```ts theme={null}
type TokenResponse = {
  token:      string;
  cvcSession: string;   // always present on success; SDK rejects before returning if absent
  card?: {              // present when vault returns complete card metadata
    last4:    string;   // last 4 digits of card number
    brand:    string;   // 'visa' | 'mastercard' | 'amex' | ...
    expMonth: string;   // '01'–'12'
    expYear:  string;   // '2026', '2027', …
  };
  billing?: BillingDetails;  // validated+normalized — present only when passed to createToken()
};
```

## BillingDetails

```ts theme={null}
type BillingDetails = {
  firstName: string;          // required, 1–50 chars
  lastName:  string;          // required, 1–50 chars
  email?:    string;          // valid email, max 50 chars
  phone?:    string;          // E.164 format, e.g. '+15551234567'
  address?:  BillingAddress;
};

type BillingAddress = {
  line1:    string;   // required
  line2?:   string;   // optional
  city:     string;   // required
  state:    string;   // required; US/CA normalized to 2-letter code
  zip:      string;   // required
  country:  string;   // ISO 3166-1 alpha-2, e.g. 'US'
};
```

## BankTokenizeOptions

```ts theme={null}
type BankTokenizeOptions = {
  firstName: string;   // required
  lastName:  string;   // required
};
```

## BankTokenResponse

```ts theme={null}
type BankTokenResponse = {
  token: string;
  bank?: {
    last4:              string;  // last 4 digits of account number
    routingNumberLast4: string;  // last 4 digits of routing number
  };
};
```

## CardSaleApiResponse

The raw response envelope from the OzuraPay API `cardSale` endpoint. Only relevant when calling the API directly via `fetch` — the server SDK's `Ozura.cardSale()` throws `OzuraError` on failure rather than returning this shape.

```ts theme={null}
interface CardSaleApiResponse {
  success: boolean;
  data?:   CardSaleResponseData;  // present on success only
  error?:  string;                // present on failure — pass to normalizeCardSaleError()
}
```

## ElementOptions

```ts theme={null}
type ElementOptions = {
  style?:         ElementStyleConfig;
  placeholder?:   string;
  disabled?:      boolean;
  loadTimeoutMs?: number;   // ms before the loaderror event fires on this element; default 10000. In vanilla JS, listen for the loaderror event. In React, use the onLoadError prop on the field component.
};
```

## ElementStyleConfig

```ts theme={null}
type ElementStyleConfig = {
  base?:        ElementStyle;
  focus?:       ElementStyle;
  invalid?:     ElementStyle;
  complete?:    ElementStyle;
  placeholder?: ElementStyle;
};
```

See the [Styling guide](/sdks/elements/styling) for the full list of supported `ElementStyle` keys.

## Appearance

```ts theme={null}
type Appearance = {
  theme?:     OzTheme;              // 'default' | 'night' | 'flat'
  variables?: AppearanceVariables;
};

type OzTheme = 'default' | 'night' | 'flat';

type AppearanceVariables = {
  colorText?:        string;  // maps to base.color
  colorBackground?:  string;  // maps to base.backgroundColor
  colorPrimary?:     string;  // maps to base.caretColor and focus.caretColor
  colorDanger?:      string;  // maps to invalid.color
  colorSuccess?:     string;  // maps to complete.color
  colorPlaceholder?: string;  // maps to placeholder.color
  fontFamily?:       string;  // maps to base.fontFamily
  fontSize?:         string;  // maps to base.fontSize
  fontWeight?:       string;  // maps to base.fontWeight
  letterSpacing?:    string;  // maps to base.letterSpacing
  lineHeight?:       string;  // maps to base.lineHeight
  padding?:          string;  // maps to base.padding
};
```

## FontSource

```ts theme={null}
// Google Fonts / remote CSS
type CssFontSource = { cssSrc: string };

// Self-hosted @font-face
type CustomFontSource = {
  family:        string;
  src:           string;   // url(https://...) value
  weight?:       string;
  style?:        string;
  display?:      string;
  unicodeRange?: string;
};

type FontSource = CssFontSource | CustomFontSource;
```

## OzError

```ts theme={null}
class OzError extends Error {
  message:    string;        // normalized, user-facing message
  errorCode:  OzErrorCode;   // machine-readable code
  raw:        string;        // raw vault API message (use for logging)
  retryable:  boolean;       // true for network, timeout, server errors
}

type OzErrorCode =
  | 'network'
  | 'auth'
  | 'validation'
  | 'server'
  | 'timeout'
  | 'config'
  | 'unknown';
```

***

## React Types

### OzElementsProps

```ts theme={null}
type OzElementsProps = {
  pubKey?:             string;                                   // required for production vault keys; omit for test vault keys
  sessionUrl?:         string;                                   // required (one of these three)
  getSessionKey?:      (sessionId: string) => Promise<string>;  // required (one of these three)
  fetchWaxKey?:        (sessionId: string) => Promise<string>;  // deprecated — use sessionUrl or getSessionKey
  children:            ReactNode;                                // required
  frameBaseUrl?:       string;
  fonts?:              FontSource[];
  appearance?:         Appearance;
  onLoadError?:        () => void;
  loadTimeoutMs?:      number;
  onSessionRefresh?:   () => void;
  onReady?:            () => void;
  sessionLimit?:       number | null;  // default 3; null = no cap; must match server createSession call
  debug?:              boolean; // default false; enables [OzVault] console.log output
};
```

### UseOzElementsReturn

```ts theme={null}
type UseOzElementsReturn = {
  createToken:     (options?: TokenizeOptions) => Promise<TokenResponse>;
  createBankToken: (options: BankTokenizeOptions) => Promise<BankTokenResponse>;
  ready:           boolean;         // vault + all mounted fields ready
  initError:       Error | null;
  tokenizeCount:   number;          // successful createToken/createBankToken calls in the current session
  reset:           () => void;      // clear all fields without destroying the vault or refreshing the session
};
```

### OzFieldProps

```ts theme={null}
type OzFieldProps = {
  style?:         ElementStyleConfig;
  placeholder?:   string;
  disabled?:      boolean;
  loadTimeoutMs?: number;
  className?:     string;
  onChange?:      (event: ElementChangeEvent) => void;
  onFocus?:       () => void;
  onBlur?:        () => void;
  onReady?:       () => void;
  onLoadError?:   (error: string) => void;
};
```

### OzCardState

```ts theme={null}
type OzCardState = {
  complete:   boolean;
  cardBrand?: string;
  error?:     string;
  fields: {
    cardNumber: ElementChangeEvent | null;
    expiry:     ElementChangeEvent | null;
    cvv:        ElementChangeEvent | null;
  };
};
```

### OzBankCardState

```ts theme={null}
type OzBankCardState = {
  complete: boolean;
  error?:   string;
  fields: {
    accountNumber: ElementChangeEvent | null;
    routingNumber: ElementChangeEvent | null;
  };
};
```

***

## createSessionFetcher

```ts theme={null}
import { createSessionFetcher } from '@ozura/elements';
```

A helper factory that creates a `getSessionKey` callback for a given backend URL. You rarely need to call this directly — pass `sessionUrl` to `OzVault.create()` or `<OzElements>` and the SDK calls it internally.

```ts theme={null}
createSessionFetcher(url: string): (sessionId: string) => Promise<string>
```

POSTs `{ sessionId }` to the URL and reads `sessionKey` from the response. Useful when you need the callback form for custom headers or auth tokens:

```ts theme={null}
const vault = await OzVault.create({
  pubKey: 'YOUR_PUB_KEY',
  getSessionKey: createSessionFetcher('/api/oz-session'),
});
```

Errors are `OzError` instances with a structured `errorCode` (`'timeout'` | `'network'` | `'auth'` | `'validation'` | `'server'`).

<Note>
  `createFetchWaxKey` is a deprecated alias for `createSessionFetcher`. Both are exported and work identically.
</Note>

***

## Debug mode

Pass `debug: true` to `VaultOptions` (or as a prop on `<OzElements debug>`) to activate structured console logging.

```ts theme={null}
const vault = await OzVault.create({
  pubKey: 'pk_live_...',
  sessionUrl: '/api/oz-session',
  debug: true,
});
```

Each log is a `[OzVault] <event>` prefixed `console.log` entry. Events covered:

| Event                                          | Description                                                 |
| ---------------------------------------------- | ----------------------------------------------------------- |
| `vault created`                                | Constructor completes                                       |
| `wax key received — vault ready`               | Session key resolved and stored; vault is ready to tokenize |
| `mounting tokenizer iframe`                    | Tokenizer iframe creation begins                            |
| `tokenizer iframe ready`                       | Tokenizer handshake complete                                |
| `element iframe ready`                         | A card/bank input iframe loads                              |
| `field changed`                                | Per-field value or state change                             |
| `auto-advance`                                 | Focus moves between card fields automatically               |
| `createToken() called`                         | Entry to `createToken()`                                    |
| `OZ_TOKENIZE sent`                             | Tokenize request dispatched                                 |
| `token received`                               | Token result returned (includes `elapsedMs`)                |
| `token error`                                  | Vault or network error during tokenize                      |
| `proactive session key refresh triggered`      | Session budget exhausted; refresh starting                  |
| `wax key refresh started / succeeded / failed` | Session key refresh lifecycle                               |
| `tab hidden` / `tab visible`                   | `visibilitychange` events                                   |
| `reset() called`                               | `vault.reset()` entry                                       |
| `destroy() called`                             | `vault.destroy()` entry                                     |

**No sensitive data is ever logged.** Session keys, tokens, CVC sessions, and billing fields appear only as boolean presence flags. Output is safe to paste directly into bug reports.

`vault.debugState()` is always available regardless of this flag — see [vault.debugState()](#debugstate) above.

***

## Exports

### @ozura/elements

The browser entry. Exports everything needed to initialize the vault, mount fields, tokenize, and handle errors. The `Transaction*` and `CardSale*` types are re-exported here for TypeScript convenience but are primarily used with `@ozura/elements/server`.

```ts theme={null}
export { OzVault };
export { OzElement };
export { OzError, normalizeVaultError, normalizeBankVaultError, normalizeCardSaleError };
export { createSessionFetcher };
export { createFetchWaxKey };   // deprecated alias for createSessionFetcher
export type {
  ElementType, BankElementType,
  ElementOptions, ElementStyleConfig, ElementStyle, ElementChangeEvent,
  VaultOptions,
  TokenizeOptions, TokenResponse, CardMetadata,
  BankTokenizeOptions, BankTokenResponse, BankAccountMetadata,
  BillingDetails, BillingAddress,
  CardSaleRequest, CardSaleResponseData, CardSaleApiResponse,
  FontSource, CssFontSource, CustomFontSource,
  Appearance, AppearanceVariables, OzTheme,
  TransactionQueryParams, TransactionQueryPagination, TransactionQueryResponse,
  TransactionType, CardTransactionType, AchTransactionType, CryptoTransactionType,
  TransactionBase, CardTransactionData, AchTransactionData, CryptoTransactionData,
  TransactionData,
  OzErrorCode,
};
```

### @ozura/elements/react

```ts theme={null}
export { OzElements };
export { useOzElements };
export { OzCardNumber, OzExpiry, OzCvv };
export { OzCard };
export { OzBankAccountNumber, OzBankRoutingNumber };
export { OzBankCard };
export { createSessionFetcher };
export { createFetchWaxKey };   // deprecated alias for createSessionFetcher
export type {
  OzFieldProps,
  OzCardProps, OzCardState,
  OzBankCardProps, OzBankCardState,
  OzElementsProps,
  UseOzElementsReturn,
  ElementChangeEvent,
  TokenizeOptions, TokenResponse, CardMetadata,
  BankTokenizeOptions, BankTokenResponse, BankAccountMetadata,
  BankElementType,
  Appearance, AppearanceVariables, OzTheme,
  OzErrorCode,
};
```

### @ozura/elements/server

Server-side entry — use in your Node.js / Express / Next.js backend only. Do not import in browser code.

```ts theme={null}
export { Ozura };
export { OzuraError };
export { getClientIp };
export { createSessionHandler, createSessionMiddleware };
/** @deprecated use createSessionHandler / createSessionMiddleware */
export { createMintWaxHandler, createMintWaxMiddleware };
export { createCardSaleHandler, createCardSaleMiddleware };
export { normalizeCardSaleError };

// Interfaces declared in this module
export interface OzuraConfig { … }
export class OzuraError { … }            // fields: message, statusCode, raw, retryAfter
export interface CreateSessionOptions {
  sessionId?:    string;                 // SDK-generated UUID; forwarded by your session endpoint
  sessionLimit?: number | null;          // default 3; null = no cap; must match VaultOptions.sessionLimit
  maxProxyCalls?: number | null;         // vault proxy call limit; omit for most integrations
  orderId?:      string;                 // your order ID — stored for transaction correlation
  customerId?:   string;                 // your customer ID — stored for transaction correlation
  cartId?:       string;                 // your cart ID — stored for transaction correlation
  metadata?:     Record<string, string>; // max 16 keys, 64-char keys, 256-char values
  ttlSeconds?:   number;                 // session TTL 60–1800s; default 1800 (30 min)
}
export interface CreateSessionResult { … }
export interface MintWaxKeyOptions { … }  // deprecated
export interface MintWaxKeyResult { … }   // deprecated
export interface CardSaleInput { … }
export interface CardSaleHandlerOptions { … }
export interface ListTransactionsInput { … }
export interface ListTransactionsResult { … }

// Types re-exported from shared types
export type {
  BillingDetails,
  CardSaleResponseData,
  TransactionQueryPagination,
  TransactionType,
  TransactionBase,
  CardTransactionData,
  AchTransactionData,
  CryptoTransactionData,
  TransactionData,
};
```
