Developer API reference
Reference the main SDK methods, HTML attributes, FlowHandle events, and protected API authentication model.
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.
Endpoint
Check identity
Returns the authenticated user and current organization for protected API work.
/api/users/me Headers
Acceptstringdefault: application/jsonAsk the route to return JSON.
Identity request
curl "https://api.plandalf.com/api/users/me" \
-H "Authorization: Bearer $PLANDALF_API_KEY" \
-H "Accept: application/json"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
{
"id": "usr_123",
"email": "founder@example.com",
"current_organization": {
"id": "org_123",
"name": "Example Studio",
"timezone": "Australia/Sydney"
}
} Endpoint
Load checkout
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.
/api/checkout Query parameters
offerstringrequiredPublished offer slug, Sqid route key, or UUID. The route also accepts offer_id for compatibility.
Load offer checkout
curl "https://api.plandalf.com/api/checkout?offer=pro-plan" \
-H "Accept: application/json"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
{
"offer": {
"id": "off_123",
"slug": "pro-plan",
"name": "Pro plan"
},
"theme": {
"primary_color": "#007d96"
},
"pages": [],
"firstPage": null
} Endpoint
Create checkout session
Creates a checkout session for a published offer. The SDK path defers invoice creation until the buyer starts a real checkout interaction.
/api/checkout/sessions Request body
offerstringrequiredPublished offer slug, Sqid route key, or UUID. The route also accepts offer_id.
customerobjectOptional customer fields or signed identity passed by your integration.
metadataobjectOptional implementation metadata, such as source page, campaign, or account ID.
Create a session
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"
}
}'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
{
"session": {
"id": "cs_123",
"status": "open",
"currency": "USD",
"total": 2900
},
"offer": {
"id": "off_123",
"slug": "pro-plan",
"name": "Pro plan"
}
} SDK surface
Most-used SDK calls
These are the calls most implementations use on a public website or logged-in app.
Open checkout
await plandalf.present("pro-plan", { frame: "modal" }) Open a published offer and wait for a completed or dismissed checkout result.
Mount inline checkout
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
plandalf.identify(userJwt) Attach checkout sessions to a logged-in user with signed server-side identity.
Observe purchases
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
// 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:
startpurchasecompletecancel
Choosing the right call
Use `present()` for buttons
Best for pricing pages, upgrade prompts, sales CTAs, and campaign links that should open checkout on demand.
Use `mount()` for embedded checkout
Best when checkout should live inside your page layout and remain visible as part of the page.
Use `.events` for post-purchase work
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.
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.
<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.
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.
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>;
}