SDK checkout API
Understand the public checkout endpoints the Plandalf SDK calls for offer loading, session creation, session lookup, mutations, and discounts.
Most projects should use the SDK instead of calling these endpoints directly. This page documents the API shape behind SDK checkout behavior so custom frontends and agents can reason about the same calls.
Use the SDK unless you are building a custom checkout surface
plandalf.present("pro-plan") handles identity headers, anonymous visitor IDs, session continuity, frame state, and live checkout events. Call these endpoints directly only when you need to own that behavior.
Endpoint flow
-
Fetch the offer, theme, page structure, and first checkout page for the slug you published in Plandalf.
-
Create the checkout session that tracks buyer state, selected items, discounts, and payment progress.
-
Send structured mutations when the buyer changes customer details, quantities, bumps, add-ons, or discounts.
-
Use live events or the SDK handle result to unlock UI, redirect, or call your backend after checkout.
Public checkout endpoints
Endpoint
Load checkout
Loads checkout data for a published offer so a custom surface can render the correct theme, pages, and first step.
/api/checkout Query parameters
offerstringrequiredPublished offer slug, Sqid route key, or UUID. The route also accepts offer_id for compatibility.
Load checkout request
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 uses this before it starts collecting buyer changes.
/api/checkout/sessions Request body
offerstringrequiredPublished offer slug, Sqid route key, or UUID. The route also accepts offer_id.
customerobjectOptional customer identity fields or a signed customer token passed by your integration.
metadataobjectOptional implementation metadata, such as source page, campaign, or account ID.
Create session request
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 session = await response.json(); Checkout session response
{
"id": "cs_123",
"offer_id": "off_123",
"status": "open",
"currency": "USD",
"subtotal": 4900,
"discount_total": 0,
"total": 4900
} Endpoint
Retrieve checkout session
Returns the current checkout session state for a custom checkout surface or recovery flow.
/api/checkout/sessions/{session} Path parameters
sessionstringrequiredCheckout session route key returned by the create session call.
Retrieve session request
curl "https://api.plandalf.com/api/checkout/sessions/cs_123" \
-H "Accept: application/json"const response = await fetch("https://api.plandalf.com/api/checkout/sessions/cs_123", {
headers: { Accept: "application/json" }
});
const session = await response.json(); Checkout session state
{
"id": "cs_123",
"status": "open",
"selected_items": [],
"customer": null,
"totals": {
"subtotal": 4900,
"discount": 0,
"total": 4900
}
} Endpoint
Mutate checkout session
Applies a structured checkout change, such as customer details, quantity changes, add-ons, order bumps, or selected options.
/api/checkout/sessions/{checkoutSession}/mutations Path parameters
checkoutSessionstringrequiredCheckout session route key.
Request body
typestringrequiredMutation type handled by the checkout surface, such as customer.update, line_item.update, or component.select.
payloadobjectrequiredMutation payload. Keep it narrow to the fields changed by this interaction.
Mutation request
curl -X POST "https://api.plandalf.com/api/checkout/sessions/cs_123/mutations" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"type": "customer.update",
"payload": {
"email": "buyer@example.com"
}
}'const response = await fetch(
"https://api.plandalf.com/api/checkout/sessions/cs_123/mutations",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify({
type: "customer.update",
payload: { email: "buyer@example.com" }
})
}
);
const session = await response.json(); Mutation response
{
"id": "cs_123",
"status": "open",
"customer": {
"email": "buyer@example.com"
},
"totals": {
"subtotal": 4900,
"discount": 0,
"total": 4900
}
} Endpoint
Apply discount
Applies a coupon or discount code to an open checkout session and returns recalculated totals.
/api/checkout/sessions/{checkoutSession}/apply-discount Path parameters
checkoutSessionstringrequiredCheckout session route key.
Request body
codestringrequiredCoupon or discount code entered by the buyer.
Apply discount request
curl -X POST "https://api.plandalf.com/api/checkout/sessions/cs_123/apply-discount" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"code":"LAUNCH20"}'const response = await fetch(
"https://api.plandalf.com/api/checkout/sessions/cs_123/apply-discount",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify({ code: "LAUNCH20" })
}
);
const session = await response.json(); Discounted session response
{
"id": "cs_123",
"status": "open",
"discounts": [
{
"code": "LAUNCH20",
"amount_off": 980
}
],
"totals": {
"subtotal": 4900,
"discount": 980,
"total": 3920
}
} SDK-first routes
The newer SDK checkout surface also calls /api/sdk/checkout/offers/{slug}, /api/sdk/checkout/compute, /api/sdk/checkout/prepare-payment, and /api/sdk/checkout/commit. Prefer those through the SDK wrapper unless you are implementing a lower-level adapter.
await plandalf.present("pro-plan");