# Developer API reference
Reference the main SDK methods, HTML attributes, FlowHandle events, and protected API authentication model.
Source: /docs/api/reference
Last modified: 2026-06-20
This page summarizes the public developer surface. Use the task guides for full examples.

## Endpoint reference

These are the API calls most implementation work starts with. Each endpoint keeps its request and response example attached to the right rail, so the code beside the page changes with the call you are reading.


  - [Check identity](#check-identity): Validate the bearer token and see the current organization before making protected calls.
  - [Load checkout](#load-checkout): Fetch a published offer so the SDK can render checkout UI.
  - [Create session](#create-checkout-session): Create the checkout session that records buyer state and line items.


<ApiEndpoint
  id="check-identity"
  method="GET"
  path="/api/users/me"
  title="Check identity"
  description="Returns the authenticated user and current organization for protected API work."
  operationId="getCurrentUser"
>


### Headers


- `Authorization` (string; required):
    Send `Bearer <token>` from your server or trusted integration runtime.


- `Accept` (string; default: application/json):
    Ask the route to return JSON.


### Identity request


```bash title="GET /api/users/me"
curl "https://api.plandalf.com/api/users/me" \
  -H "Authorization: Bearer $PLANDALF_API_KEY" \
  -H "Accept: application/json"
```

```js title="get-current-user.js"
const response = await fetch("https://api.plandalf.com/api/users/me", {
  headers: {
    Authorization: `Bearer ${process.env.PLANDALF_API_KEY}`,
    Accept: "application/json"
  }
});

const identity = await response.json();
```


### Identity response


```json title="200 identity response"
{
  "id": "usr_123",
  "email": "founder@example.com",
  "current_organization": {
    "id": "org_123",
    "name": "Example Studio",
    "timezone": "Australia/Sydney"
  }
}
```


</ApiEndpoint>

<ApiEndpoint
  id="load-checkout"
  method="GET"
  path="/api/checkout"
  title="Load checkout"
  description="Initializes checkout data for a published offer. Use it when a custom surface needs the offer, theme, pages, and first page before creating a session."
  operationId="initializeCheckout"
  auth="Public offer route"
>


### Query parameters


- `offer` (string; required):
    Published offer slug, Sqid route key, or UUID. The route also accepts `offer_id` for compatibility.


### Load offer checkout


```bash title="GET /api/checkout"
curl "https://api.plandalf.com/api/checkout?offer=pro-plan" \
  -H "Accept: application/json"
```

```js title="initialize-checkout.js"
const response = await fetch(
  "https://api.plandalf.com/api/checkout?offer=pro-plan",
  { headers: { Accept: "application/json" } }
);

const checkout = await response.json();
```


### Checkout initialization response


```json title="200 checkout initialization"
{
  "offer": {
    "id": "off_123",
    "slug": "pro-plan",
    "name": "Pro plan"
  },
  "theme": {
    "primary_color": "#007d96"
  },
  "pages": [],
  "firstPage": null
}
```


</ApiEndpoint>

<ApiEndpoint
  id="create-checkout-session"
  method="POST"
  path="/api/checkout/sessions"
  title="Create checkout session"
  description="Creates a checkout session for a published offer. The SDK path defers invoice creation until the buyer starts a real checkout interaction."
  operationId="createCheckoutSession"
  auth="Public offer route"
>


### Request body


- `offer` (string; required):
    Published offer slug, Sqid route key, or UUID. The route also accepts `offer_id`.


- `customer` (object):
    Optional customer fields or signed identity passed by your integration.


- `metadata` (object):
    Optional implementation metadata, such as source page, campaign, or account ID.


### Create a session


```bash title="POST /api/checkout/sessions"
curl -X POST "https://api.plandalf.com/api/checkout/sessions" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "offer": "pro-plan",
    "metadata": {
      "source": "pricing-page"
    }
  }'
```

```js title="create-checkout-session.js"
const response = await fetch("https://api.plandalf.com/api/checkout/sessions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Accept: "application/json"
  },
  body: JSON.stringify({
    offer: "pro-plan",
    metadata: { source: "pricing-page" }
  })
});

const checkout = await response.json();
```


### Session response


```json title="201 checkout session"
{
  "session": {
    "id": "cs_123",
    "status": "open",
    "currency": "USD",
    "total": 2900
  },
  "offer": {
    "id": "off_123",
    "slug": "pro-plan",
    "name": "Pro plan"
  }
}
```


</ApiEndpoint>

## SDK surface


### Most-used SDK calls

These are the calls most implementations use on a public website or logged-in app.

- [Open checkout](/docs/quickstart) `await plandalf.present("pro-plan", { frame: "modal" })` - Open a published offer and wait for a completed or dismissed checkout result.
- [Mount inline checkout](/docs/offers/add-to-site) `plandalf.mount("#checkout", "pro-plan", { promo: "early-bird" })` - Render an offer into a page container instead of opening a modal or slideout.
- [Identify a customer](/docs/sdk/identity) `plandalf.identify(userJwt)` - Attach checkout sessions to a logged-in user with signed server-side identity.
- [Observe purchases](/docs/sdk/events) `for await (const event of handle.events) { ... }` - React to paid invoices, completion, cancellation, and checkout start events.

## Browser SDK methods

| Method | Signature | Purpose |
| --- | --- | --- |
| `present` | `plandalf.present(offer, opts?)` | Open an offer in a frame and return a `FlowHandle`. |
| `mount` | `plandalf.mount(target, offer, opts?)` | Render an offer inline and return a `FlowHandle`. |
| `identify` | `plandalf.identify(jwtOrEmail)` | Set customer identity globally. |
| `reset` | `plandalf.reset()` | Clear customer identity while preserving anonymous device ID. |
| `ready` | `plandalf.ready(callback)` | Run code after the SDK loads. |
| `from` | `plandalf.from(element)` | Get the current handle for a declarative element. |
| `promo` | `plandalf.promo(slug)` | Open an awaitable promo handle for state, tier changes, and countdown widgets. |
| `addGate` | `plandalf.addGate(name, offer, check)` | Register a local access gate. |
| `gate` | `plandalf.gate(name)` | Evaluate a registered gate. |

## HTML attributes

| Attribute | Purpose |
| --- | --- |
| `data-plandalf-present` | Open an offer when the element is clicked. |
| `data-plandalf-mount` | Mount an offer inline. |
| `data-plandalf-promo` | Render a promo or countdown widget. |
| `data-plandalf-apply-promo` | Apply promo context to an offer trigger or mount. |
| `data-plandalf-frame` | Choose frame modality. |
| `data-plandalf-size` | Choose checkout frame size. |
| `data-plandalf-mode` | Choose `test`, `live`, or `preview`. |

## FlowHandle

```ts title="flow-handle.ts"
// Every checkout opener returns a promise-like handle.
interface FlowHandle<T> extends Promise<T> {
  // Stream lifecycle events while the checkout frame is open.
  events: AsyncIterable<FlowHandleEvent>;
  // Close the modal, slideout, bottom sheet, or embedded frame.
  close(): void;
}
```

Events:

- `start`
- `purchase`
- `complete`
- `cancel`

## Choosing the right call

- [Use `present()` for buttons](/docs/offers/buy-buttons) - Best for pricing pages, upgrade prompts, sales CTAs, and campaign links that should open checkout on demand.
- [Use `mount()` for embedded checkout](/docs/offers/add-to-site) - Best when checkout should live inside your page layout and remain visible as part of the page.
- [Use `.events` for post-purchase work](/docs/sdk/events) - Best when your frontend needs to unlock UI, redirect, record analytics, or call your backend after a purchase.

## Protected API authentication

Protected API routes accept a bearer token. Use an API key for server-to-server automation or an OAuth bearer token for app integrations.

```http title="Authorization header"
Authorization: Bearer <token>
```


### Call the checkout API from the browser

The public browser SDK supports declarative markup, direct JavaScript, and framework components without changing the published offer.

Use attributes when a page builder or static template owns the markup.


```html HTML
<button data-plandalf-present="pro-plan" data-plandalf-frame="modal">
  Buy Pro
</button>
```

Use JavaScript when the page needs to inspect the checkout result before redirecting or unlocking UI.


```js JavaScript
async function openOffer() {
  // Start checkout for the offer slug configured in Plandalf.
  const handle = plandalf.present("pro-plan", { frame: "modal" });

  // Listen while checkout is open if your UI needs live state.
  for await (const event of handle.events) {
    if (event.type === "purchase") {
      console.log("Purchase recorded", event.session);
    }
  }

  return await handle;
}
```

Use a component wrapper when checkout depends on app state, logged-in user data, or route-level metadata.


```tsx React
export function CheckoutCta({ customerJwt }: { customerJwt: string }) {
  async function buy() {
    // Pass signed identity only when this customer is known.
    const result = await window.plandalf.present("pro-plan", {
      user: customerJwt,
      metadata: { source: "account-upgrade" }
    });

    if (result.status === "complete") {
      window.location.assign("/account/billing");
    }
  }

  return <button onClick={buy}>Upgrade</button>;
}
```


## Related docs

- [API authentication](/docs/api/authentication)
- [SDK checkout API](/docs/api/sdk-checkout)
- [Live events](/docs/sdk/events)