# Class: Plandalf

This is the ES module class returned by `new Plandalf()` or `init()`. The script-tag [`plandalf` object](https://plandalf.com/docs/sdk) exposes a smaller, intentional public surface. In particular, `preload()` appears below because it exists on the class, but it is absent from the browser object and the [`PlandalfSDK` interface](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).

Defined in: [packages/sdk/src/core/sdk.ts:213](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L213)

Plandalf SDK - Main Entry Point

For ES module imports:
import { Plandalf, init } from '@plandalf/sdk';

## Implements

- [`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK)

## Constructors

### Constructor

> **new Plandalf**(`config?`): `Plandalf`

Defined in: [packages/sdk/src/core/sdk.ts:228](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L228)

#### Parameters

##### config?

[`PlandalfConfig`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfConfig) = `{}`

#### Returns

`Plandalf`

## Properties

### harnesses

> **harnesses**: `object`

Defined in: [packages/sdk/src/core/sdk.ts:780](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L780)

#### get

> **get**: (`id`) => [`HarnessDefinition`](https://plandalf.com/docs/packages/sdk/interfaces/HarnessDefinition)

##### Parameters

###### id

`string`

##### Returns

[`HarnessDefinition`](https://plandalf.com/docs/packages/sdk/interfaces/HarnessDefinition)

#### register

> **register**: (`harness`) => `void`

##### Parameters

###### harness

[`HarnessDefinition`](https://plandalf.com/docs/packages/sdk/interfaces/HarnessDefinition)

##### Returns

`void`

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`harnesses`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#harnesses)

## Methods

### addGate()

```typescript
addGate(
  name: string,
  flow: string,
  check?: GateCheck<any>,
): void
```

Defined in: [packages/sdk/src/core/sdk.ts:376](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L376)

Register a gate. A gate wraps a feature behind an access check.
If the check fails (or is absent), the SDK presents the linked flow.

plandalf.addGate("export", "upgrade", () => user.plan !== "free")
plandalf.addGate("course", "buy-course")  // no check = always presents

#### Parameters

##### name

`string`

##### flow

`string`

##### check?

[`GateCheck`](https://plandalf.com/docs/packages/sdk/type-aliases/GateCheck)\<`any`\>

#### Returns

`void`

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`addGate`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#addgate)

***

### configure()

```typescript
configure(config: Partial<PlandalfConfig>)
```

Defined in: [packages/sdk/src/core/sdk.ts:806](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L806)

#### Parameters

##### config

`Partial`\<[`PlandalfConfig`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfConfig)\>

#### Returns

`Plandalf`

***

### gate()

```typescript
async gate(
    name: string,
    sync?: GateSyncCallback,
    options?: Partial<FlowOpenOptions>,
  ): Promise<GateResult>
```

Defined in: [packages/sdk/src/core/sdk.ts:396](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L396)

Check a gate. If the check passes, resolves immediately with access: true.
If it fails, presents the linked flow. After completion, sync returns
fresh entitlements and the same check runs again with those values.
Check/sync failures deny access without opening another checkout.

#### Parameters

##### name

`string`

##### sync?

[`GateSyncCallback`](https://plandalf.com/docs/packages/sdk/type-aliases/GateSyncCallback)

##### options?

`Partial`\<[`FlowOpenOptions`](https://plandalf.com/docs/packages/sdk/interfaces/FlowOpenOptions)\>

#### Returns

`Promise`\<[`GateResult`](https://plandalf.com/docs/packages/sdk/interfaces/GateResult)\>

#### Example

```typescript feature-gate.ts lineNumbers lineNumberStart=1 highlight="8-11"
import { Plandalf } from '@plandalf/sdk'

declare function readAccessFromServer(): Promise<{ canExport: boolean }>
const sdk = new Plandalf({
  apiBase: 'https://your-org.plandalf.dev',
})
let access = await readAccessFromServer()
sdk.addGate('export', 'upgrade', (fresh) =>
  (fresh as typeof access | undefined)?.canExport ?? access.canExport,
)
const result = await sdk.gate('export', async () => {
  access = await readAccessFromServer()
  return access
})
if (result.access) {
  // Your server must enforce access again for the protected action.
}
```

The sync callback is your application's code. The returned browser result is useful for UI state; enforce the entitlement on your server. [Read the gate guide](https://plandalf.com/docs/guides/gate-a-feature).

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`gate`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#gate)

***

### getAnonId()

```typescript
getAnonId(): string
```

Defined in: [packages/sdk/src/core/sdk.ts:330](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L330)

Get the anonymous device ID. Always present — generated on first visit,
persists forever. Use this to track anonymous visitors and link them
to identified users later.

#### Returns

`string`

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`getAnonId`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#getanonid)

***

### getIdentity()

```typescript
getIdentity(): VisitorIdentity
```

Defined in: [packages/sdk/src/core/sdk.ts:338](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L338)

Get the full visitor identity record.
Contains anonymous_id, ref, first_seen_at, last_seen_at.

#### Returns

[`VisitorIdentity`](https://plandalf.com/docs/packages/sdk/interfaces/VisitorIdentity)

***

### getRef()

```typescript
getRef(): string | null
```

Defined in: [packages/sdk/src/core/sdk.ts:345](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L345)

Get the visitor ref (external identity from ?pf_ref=), or null.

#### Returns

`string` \| `null`

***

### getSessionAge()

```typescript
getSessionAge(): number
```

Defined in: [packages/sdk/src/core/sdk.ts:361](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L361)

Get seconds elapsed since this visitor first arrived (first_seen_at).

#### Returns

`number`

***

### getUserToken()

```typescript
getUserToken(): string | null
```

Defined in: [packages/sdk/src/core/sdk.ts:321](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L321)

Get the current user token, or null if anonymous.

#### Returns

`string` \| `null`

***

### identify()

```typescript
identify(token: string): void
```

Defined in: [packages/sdk/src/core/sdk.ts:296](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L296)

Identify the current user. Accepts a JWT (signed with your API key)
or a plain email string.

The token is persisted to localStorage and restored on page reload.
It's sent on all subsequent API calls (Authorization header).
The anonymous ID is also sent (X-Plandalf-Anon header) so the backend
can link anonymous sessions to this user.

  plandalf.identify("eyJhbGciOiJIUzI1NiJ9...")  // JWT
  plandalf.identify("jane@acme.com")             // email

#### Parameters

##### token

`string`

#### Returns

`void`

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`identify`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#identify)

***

### mount()

```typescript
mount(
    target: HTMLElement | string,
    slug: string,
    opts: MountOptions = {},
  ): FlowHandle<Flow>
```

Defined in: [packages/sdk/src/core/sdk.ts:602](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L602)

Mount an offer inline. Mirrors `present()` but renders into the merchant's
own container instead of a frame.

`opts.promo` accepts a plain promo slug — the SDK resolves the active tier
internally and applies its tier price to the cart. Refs come from the
existing identity record (auto-captured from `?pf_ref=` on init).

#### Parameters

##### target

`string` \| `HTMLElement`

##### slug

`string`

##### opts?

[`MountOptions`](https://plandalf.com/docs/packages/sdk/interfaces/MountOptions) = `{}`

#### Returns

[`FlowHandle`](https://plandalf.com/docs/packages/sdk/interfaces/FlowHandle)\<[`Flow`](https://plandalf.com/docs/packages/sdk/interfaces/Flow)\>

#### Example

```typescript inline-checkout.ts lineNumbers lineNumberStart=1 highlight="7-8"
import { Plandalf } from '@plandalf/sdk'

const sdk = new Plandalf({
  apiBase: 'https://your-org.plandalf.dev',
})
const target = document.querySelector<HTMLElement>('#checkout')
if (!target) throw new Error('Checkout container is missing')
const flow = await sdk.mount(target, 'pro-plan')
```

The handle resolves when the [`Flow`](https://plandalf.com/docs/packages/sdk/interfaces/Flow) is mounted. It does not resolve to the final payment outcome.

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`mount`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#mount)

***

### preload()

```typescript
preload(...moduleNames: Array<'checkout'>)
```

Defined in: [packages/sdk/src/core/sdk.ts:801](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L801)

#### Parameters

##### moduleNames

...`"checkout"`[]

#### Returns

`Plandalf`

***

#### Surface note

This method exists on an ES module `Plandalf` instance and accepts only `'checkout'`. It is not exposed on the [browser `plandalf` object](https://plandalf.com/docs/sdk) or declared in the [`PlandalfSDK` interface](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK). `present()` and `mount()` already load checkout when needed.

```typescript title="optional-preload.ts" lineNumbers lineNumberStart=1 highlight="4"
import { Plandalf } from '@plandalf/sdk'

const sdk = new Plandalf()
sdk.preload('checkout')
```

### present()

```typescript
present(
  slug: string,
  options: Partial<FlowOpenOptions> = {},
): FlowHandle<FlowResult>
```

Defined in: [packages/sdk/src/core/sdk.ts:450](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L450)

Present a flow and wait for it to finish.

Always resolves with a FlowResult describing the outcome. Only real
errors (network failure, bad slug, etc.) reject. User-supplied
onComplete/onClose/onError callbacks still fire.

#### Parameters

##### slug

`string`

##### options?

`Partial`\<[`FlowOpenOptions`](https://plandalf.com/docs/packages/sdk/interfaces/FlowOpenOptions)\> = `{}`

#### Returns

[`FlowHandle`](https://plandalf.com/docs/packages/sdk/interfaces/FlowHandle)\<[`FlowResult`](https://plandalf.com/docs/packages/sdk/interfaces/FlowResult)\>

#### Example

```typescript checkout.ts lineNumbers lineNumberStart=1 highlight="6-7"
import { Plandalf } from '@plandalf/sdk'

const sdk = new Plandalf({
  apiBase: 'https://your-org.plandalf.dev',
})
const result = await sdk.present('upgrade', { frame: 'modal' })
if (result.status === 'complete') {
  // Refresh access from your server before unlocking a feature.
}
```

`present()` returns an awaitable [`FlowHandle`](https://plandalf.com/docs/packages/sdk/interfaces/FlowHandle). A dismissal resolves with `status: 'dismissed'`; genuine loading or session errors reject. [See the complete flow](https://plandalf.com/docs/guides/await-a-checkout).

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`present`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#present)

***

### promo()

```typescript
promo(slug: string, options?: PromoHandleOptions): PromoHandle
```

Defined in: [packages/sdk/src/core/sdk.ts:712](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L712)

Open a live promo handle. Single entry point for everything
promo-related on a host page.

Default behaviour auto-redirects the page to the active tier's
`redirect_url` when the current URL doesn't match (covers both
tier-rolled-while-here AND arrived-on-stale-URL). Pass
`{ redirect: false }` to disable the side effect and use the
handle as a pure listener.

Skipped while a Plandalf checkout frame is open — the in-frame
countdown reloads the iframe; we don't yank the host page. One
promo per page is the canonical pattern; the SDK dedupes by slug.

DOM attach: every element on the page that names this slug via
`data-plandalf-promo="<slug>"` or `data-plandalf-apply-promo="<slug>"`
is registered against the handle. So `plandalf.from(el)` returns
the same handle for any of them, and `plandalf:tier-change` /
`plandalf:expired` bubble as DOM CustomEvents on each.

#### Parameters

##### slug

`string`

##### options?

[`PromoHandleOptions`](https://plandalf.com/docs/packages/sdk/referenced-types/PromoHandleOptions)

#### Returns

[`PromoHandle`](https://plandalf.com/docs/packages/sdk/referenced-types/PromoHandle)

#### Example

```typescript promo.ts lineNumbers lineNumberStart=1 highlight="6-7"
import { Plandalf } from '@plandalf/sdk'

const sdk = new Plandalf({
  apiBase: 'https://your-org.plandalf.dev',
})
const monitor = sdk.promo('early-bird', { redirect: false })
const state = await monitor
console.log(state?.activeTier?.label, state?.remaining)
monitor.close()
```

The returned [`PromoHandle`](https://plandalf.com/docs/packages/sdk/referenced-types/PromoHandle) is awaitable and also exposes live `.events`. Close it when you stop monitoring.

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`promo`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#promo)

***

### reset()

```typescript
reset(): void
```

Defined in: [packages/sdk/src/core/sdk.ts:306](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L306)

Clear the current user identity. The anonymous device ID is preserved —
only the user token is removed. Next gate/present call will be anonymous.

#### Returns

`void`

#### Implementation of

[`PlandalfSDK`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK).[`reset`](https://plandalf.com/docs/packages/sdk/interfaces/PlandalfSDK#reset)

***

### ~~resetUser()~~

> **resetUser**(): `void`

Defined in: [packages/sdk/src/core/sdk.ts:316](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L316)

#### Returns

`void`

#### Deprecated

Use `reset()`. Retained as an alias during the migration.

***

### setRef()

```typescript
setRef(ref: string | null): void
```

Defined in: [packages/sdk/src/core/sdk.ts:354](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L354)

Set the visitor ref and persist it. Call this once you know who the
visitor is (email after opt-in, CRM id after login). Survives reloads
and future sessions on the same browser.

#### Parameters

##### ref

`string` \| `null`

#### Returns

`void`

***

### ~~setUser()~~

> **setUser**(`token`): `void`

Defined in: [packages/sdk/src/core/sdk.ts:313](https://github.com/plandalf/numi/blob/fc6f42b5ade3d63b71623934838a6509f17203e2/packages/sdk/src/core/sdk.ts#L313)

#### Parameters

##### token

`string`

#### Returns

`void`

#### Deprecated

Use `identify()`. Retained as an alias during the migration.

Source: https://plandalf.com/docs/packages/sdk/classes/Plandalf
