Skip to main content
FloKit is in private beta. This changelog tracks significant releases, integration changes, and breaking changes to the API and data model. For early access to the private beta, visit flokitai.com or contact the FloKit team.

August 12, 2026 — Paddle-hosted checkout (optional surface)

Flows / Payments — additive. The same-origin @flokitai/checkout-js overlay is unchanged and remains the default checkout experience.
  • Apps whose Paddle connection requires Paddle’s own hosted checkout page now redirect through two Flow-gateway routes, GET /pc/paddle-hosted/launch and GET /pc/paddle-hosted/return. Both are same-origin with the Flow page; the launch id is single-use and the bridge record expires.
  • Whether a given app uses this path depends on its per-connection checkout configuration, not on a global setting.
  • Confirmation still comes from the Paddle webhook, never from the browser return — a return hit alone never grants an entitlement.

August 5, 2026 — Custom delivery domains and clean Flow URLs

Flows — additive; no existing URL stopped working.
  • Custom delivery domains. You can now serve Flows from your own subdomain. Point a CNAME at edge.flokitai.com and add the _flokit-verification.<host> TXT record, then verify and promote the domain from the dashboard’s Domains tab. Until a custom domain is primary, Flows keep serving from their *.funnels.flokitai.com fallback host. See Custom subdomain setup.
  • Clean public Flow URLs. Generated Flows are now published at a single-segment path, https://<your-host>/<slug>. The older /f/<flowId>/<frozenSlug> form still resolves and issues a 308 redirect to the clean URL, so existing links and ad destinations keep working. Retired paths answer 410 rather than 404, so a removed Flow is distinguishable from a typo.
  • A slug is reserved once used: reusing it for a different Flow is rejected rather than silently repointing an existing public URL.

July 30, 2026 — Canonical subscription domain (SDK v2.0.0)

Breaking — entitlement reads, receipt submission, and the Entitlement shape all changed.
  • Entitlement read: GET /api/paywall/entitlementGET /api/entitlements/current. The old path was deleted and now 404s.
  • Receipts: POST /api/paywall/receiptPOST /api/iap/receipts. The body schema is unchanged.
  • Entitlement.product_identitlement_key, and it is now opaque — the store product id for native purchases, the Package key for web. Do not parse it.
  • expires_at is now string | null; null means open-ended.
  • New fields on Entitlement: state, source_event_id, updated_at.
  • EntitlementProvider widened to apple | google | paddle | lemon_squeezy | stripe_direct | stripe_managed_payments | custom.
Payments gateway
  • GET /api/paywall/config now returns 410 with {"code": "PAYWALL_CONFIG_REMOVED"}. Remote paywall configuration no longer exists — paywalls are Flow-owned and served with the Flow page. The path is still proxied so older SDK builds get an honest 410 rather than a 404.
  • GET /api/monetization/provider-profile was deleted.
  • POST /api/providers/generic-subscription/webhook was deleted. Third-party subscription events must arrive through a per-connection provider receiver.
See Entitlements API, Paywall API, and SDKs.

July 28, 2026 — SDK v1.3.1

Breaking — Subscriptions SDK
  • startWebCheckout() now always throws CheckoutUnavailableError with code: 'WEB_CHECKOUT_MIGRATED'. Web checkout moved to the Flow page, driven same-origin by @flokitai/checkout-js.
  • previewOfferPrice() and the PricePreview type were removed.
  • trackPaywallEvent({ offerId }) was retired.

July 27, 2026 — RevenueCat and Adapty webhook receivers removed

Payments gateway — breaking for anyone who configured these URLs.
  • POST /api/providers/revenuecat/webhook and POST /api/providers/adapty/webhook no longer exist. There is no RevenueCat or Adapty adapter in the platform; the endpoints were documented but are not served. Deliveries to either URL are dropped.
  • Route third-party subscription events through a per-connection provider receiver instead. Apple, Google Play, Paddle, Stripe, and Lemon Squeezy receivers are unchanged.
Superseded by the July 30, 2026 entry above. The generic-subscription receiver named in the original version of this entry (POST /api/providers/generic-subscription/webhook) has since been deleted, as has GET /api/monetization/provider-profile.
The v1 REST API preview pages no longer print a base URL. That API is not served on a public host yet — see Authentication.

July 20, 2026 — Daily activity and entitlement telemetry (SDK v1.3.0)

Subscriptions SDK — additive.
  • day_active — emitted once per local calendar day on that day’s first foreground. The DAU spine: counting distinct users off app_open works, but it leaves the definition of “active today” duplicated in every query that asks.
  • entitlement_granted / entitlement_revoked — access-state transitions, distinct from the commercial events. convert is “they paid”; entitlement_granted is “they can use it”. A restore, a web checkout completing, or a server-side grant produces one without the other. First observation carries first_observation: true.
  • Entitlement is revalidated on foreground (60s TTL), so a trial that lapsed or a cancellation that took effect overnight is caught instead of served stale from cache.

July 20, 2026 — Package renamed, SDK becomes the measurement client (SDK v1.2.0)

Breaking — the package was renamed. @flokit/subscriptions-sdk is no longer published anywhere. Distribution moved to GitHub Packages, whose registry requires the package scope to match the repository owner. Re-pin to @flokitai/subscriptions-sdk and add @flokitai:registry=https://npm.pkg.github.com to your .npmrc. See SDKs.
Breaking — Subscriptions SDK
  • purchase() now owns its whole funnel: purchase_start on entry, then exactly one terminal event (convert, trial_start, cancel, or purchase_failed). Hosts must delete their own emissions of these — hand-rolling them is what produced double-counted purchase_start, trial_start recorded against failed purchases, and every error filed as a user cancellation.
  • resolveSdkMarket() / ResolveSdkMarketOptions removed. They were the sole consumer of a private file: dependency that an external consumer could not resolve, which blocked publishing outright. They shipped only in 1.1.0, which was never released, so nothing can depend on them. previewOfferPrice() is unaffected.
Added — Subscriptions SDK
  • track(eventName, properties?) for general-purpose funnel events, drawn from a canonical vocabulary shared verbatim with the hosted web funnel, so a web session and an app session describe one journey.
  • Sessions and lifecycle: session_id on every event, plus first_open, app_open, session_start, session_end. Pass appState at init to get transitions and a flush when the app backgrounds.
  • Device/app context on every event (sdk_version, app_version, build_number, os_version, device_model, locale), all host-supplied.
  • Campaign attribution now survives: handoff-supplied campaignId / campaignCreationSessionId were previously discarded, and are now persisted and stamped on every later event across restarts.
  • Revenue on conversions — purchase({ priceUsdCents, currency }) stamps revenue on the terminal event only, never on purchase_start.
  • getDiagnostics() gains droppedEvents and sessionId.
API
  • POST /api/paywall/events accepts the full vocabulary — 31 event types across paywall render, app lifecycle, entitlement transitions, the shared web-funnel moments, and checkout/identity. purchase_failed and paywall_dismiss do not require paywall_id/variant_id.

July 12, 2026 — Localized pricing (SDK v1.1.0, never released)

v1.1.0 was superseded by v1.2.0 and never released. resolveSdkMarket(), announced here originally, was removed before release — see the v1.2.0 entry above. previewOfferPrice() shipped in v1.2.0 and was removed in v1.3.1 — see the July 28, 2026 entry.
Subscriptions SDK
  • previewOfferPrice() returns a localized PricePreview (currency, formatted subtotal / tax / total, and per-price line items) before checkout.
API
  • POST /api/billing/offers/:offerId/price-preview returns a country-localized price breakdown for a published offer.

July 12, 2026 — Subscriptions SDK v1.0 (placement-first)

Breaking — Subscriptions SDK
  • @flokit/subscriptions-sdk v1.0 is a clean break with no 0.x compatibility. Paywalls are now addressed by placement: apps register a placement name (onboarding_complete) and the dashboard maps it to a published paywall and A/B variant, so which paywall shows where — and which experiment runs — changes with no app release.
  • Context-first API. initSubscriptionsSdk() is required for the main surface; every function resolves baseUrl / appId / user / credentials from the context. getPaywall(placement) replaces fetchPaywallConfig; <RemotePaywall placement> replaces the per-prop form. Identity is anonymous-first (userId optional at init).
  • New: onEntitlementChange() listener, automatic app-session token mint + refresh (no manual fetchAppToken), and identify() now also posts the server-side identity alias edge.
API
  • GET /api/paywall/config accepts placement_id (resolved to a published paywall) as an alternative to paywall_id; the response echoes placement_id. An unmapped placement returns the empty fallback, never a 404.
  • Paywall funnel events accept an optional top-level placement_id, surfaced in reporting via the paywall_funnel_events warehouse view.

July 8, 2026 — Customer onboarding guide

Docs
  • Added Customer onboarding, a production rollout guide from workspace setup through app identity, revenue, attribution, events, identity validation, first payback report review, guardrails, and recommendations.
  • Added the onboarding guide to the Start here navigation area.
  • Refreshed the changelog with a dated entry for the onboarding docs update.

July 2026 — Subscriptions SDK hardening (v0.3.0, v0.4.0)

Subscriptions SDK
  • @flokit/subscriptions-sdk v0.3.0 — app-session tokens: fetchAppToken() mints a short-lived token via POST /api/paywall/token; every call and the RemotePaywall prop now accept appToken, sent as x-app-token (takes precedence over appKey). Optional and backwards compatible.
  • @flokit/subscriptions-sdk v0.4.0 — optional initSubscriptionsSdk() wires a persisted, retrying funnel-event queue (EventQueue + injectable StorageAdapter), on-device identity (identify / resetIdentity with a persisted anonymous_ref), a stale-while-revalidate entitlement cache (getEntitlement / restore), the web→app handoff bridge (exchangeHandoffCode), the hosted Paddle web-checkout bridge (startWebCheckout), and diagnostics (getDiagnostics / setDebugLogger). Fully additive — existing standalone calls are unchanged. See SDKs.
Live gateway endpoints
  • Web→app handoff — POST /api/paywall/handoff/exchange redeems a one-time handoff code and returns the flow-session context.
  • Web checkout — POST /api/paywall/checkout opens a hosted Paddle checkout for the web-to-app funnel.

June–July 2026 — Remote paywalls, live gateway endpoints, measurement ingest

Subscriptions SDK
  • @flokit/subscriptions-sdk v0.2.0 (React Native, TypeScript) — remote paywall rendering via RemotePaywall / Paywall / fetchPaywallConfig, native purchase support (purchase, submitReceipt with an injected StoreKit 2 / Play Billing adapter), entitlement gate (fetchEntitlement), paywall funnel events (trackPaywallEvent), and the app-scoped publishable key credential (appKeyx-app-key). See SDKs.
Live gateway endpoints
  • Paywall config — GET /api/paywall/config with deterministic A/B variant selection and a safe fallback response. See Paywall API.
  • Receipt verification — POST /api/paywall/receipt for Apple StoreKit 2 (JWS) and Google Play receipts.
  • Entitlements — GET /api/paywall/entitlement and alias GET /api/entitlements/current. See Entitlements API.
  • Paywall funnel analytics — POST /api/paywall/events accepting impression, offer_tap, purchase_start, trial_start, convert, and cancel events (1–50 per request) with edge-side country resolution.
  • Provider webhook passthrough — raw-body receiver endpoints for Stripe, Apple, Google, RevenueCat, Adapty, generic subscription providers, and MMP attribution callbacks.
Measurement ingest
  • MMP server-callback ingestion at GET/POST /ingest/:vendor with per-vendor secret auth, event deduplication (30-day window), and a { received, written, duplicate, dropped } outcome — Adjust is the first supported vendor. See Measurement ingest.
Docs
  • New live-endpoint reference section (paywall, entitlements, measurement ingest).
  • Architecture, flow, and lifecycle diagrams across getting-started, integrations, send-data, product, recipes, and API reference pages.
  • Examples and SDKs sections added to the navigation.
  • v1 REST API pages labeled as design-partner preview.

June 2025 — Private Beta Launch

Integrations
  • RevenueCat integration — connect via API key and optional webhook for real-time subscription events.
  • Adapty integration — connect via API key and webhook for subscription and paywall events.
  • AppsFlyer integration — connect via V2.0 API token for install and attribution data.
  • Adjust integration — connect via API token and app token for install and attribution data.
Reports
  • Payback reports with cohort windows at 30, 60, 90, 180, and 365 days.
  • CAC, trial conversion rate, renewal rate, ROAS, and projected LTV by campaign, channel, country, creative, and offer.
  • Action outcomes report — track performance impact of approved actions.
Actions
  • Action queue with budget shift and creative pause recommendation types.
  • Action lifecycle: draft → ready_for_approval → approved → running → completed | rolled_back.
  • Guardrails configuration — spend caps, confidence thresholds, excluded entities, rollback triggers.
  • Manual approval required for all action types in beta.
API
  • Events API — send server-side subscription and lifecycle events directly to FloKit (POST https://YOUR-FLOKIT-API-HOST/v1/events).
  • Reports API — query payback and cohort data programmatically (GET https://YOUR-FLOKIT-API-HOST/v1/reports/payback).
  • Actions API — approve and rollback actions via API (POST https://YOUR-FLOKIT-API-HOST/v1/actions/{id}/approve).
Webhooks
  • action.status_changed — fired when an action moves between lifecycle states.
  • guardrail.triggered — fired when a guardrail prevents an action from entering the approval queue or triggers a rollback.
See Webhooks for payload schemas and delivery configuration.