- DATE:
- AUTHOR:
- The Kinde team
Sell more than subscriptions
Sell one-time charges alongside your plans
Kinde billing now supports one-time charges, so you can sell things that do not fit a recurring subscription — setup fees, credit top-ups, add-on packs, and other buy-once items. When editing a plan, add a one-time charge alongside your recurring features: each charge can be a flat price or package-priced (for example, $20 per 1,000 credits), metered or unmetered, and can either never expire or expire at the end of the current billing cycle. You can also cap the maximum units a customer can hold, and publishing the plan syncs everything to Stripe automatically.
Your customers buy them in the self-serve portal (for both B2C and B2B), choosing a quantity, seeing an itemized quote, and paying with their saved card or a new one. Free (zero-amount) items are granted instantly without a payment step, and purchase history and expiry dates are shown right on the plan details page. You can also assign a one-time purchase to a customer directly from their billing record in the admin area, charging their stored payment method automatically — useful for sales-led deals and support scenarios. When a metered one-time charge is purchased, the customer is granted the corresponding usage allowance, and usage you report via the API draws down against it. Plan changes and cancellations are handled safely too: customers with unexpired one-time purchases are clearly warned and must acknowledge that those purchases will be forfeited, and any in-flight (unpaid) purchases are voided rather than charged.
Report on purchases and usage via the Management API
Two new Management API endpoints round out one-time charges. GET /api/v1/billing/one_time_purchases lists a customer's one-time purchases (requiring the read:billing_one_time_purchases scope), and GET /api/v1/billing/meter_usage lists meter usage records (read:meter_usage) — handy for reconciling granted allowances against reported usage. Both support pagination and filtering by customer, agreement, or feature code.
Founder MCP tool hints
Admins can now override tool annotation hints (read-only, destructive, idempotent, open world) per connection and per tool for the founder proxy MCP server. For example, you can mark a specific DELETE tool as non-destructive or a POST search tool as read-only. Overrides are stored with the connection, and the runtime cache refreshes when they change.
Always know which environment you're in
Ever made a change in production thinking you were in your dev environment? You can now show a colored environment bar across the top of the Kinde admin area, so it's always clear which environment you're working in. Turn it on per environment from the environment's details page, pick from thirteen colors, and the bar displays the environment's name across the top of every admin page — with a live preview as you change the settings, before you save. The bar only appears in the admin area, never in your customer-facing portal.
SCIM and directory sync improvements
Directory sync is more reliable and harder to misconfigure this release. Linking a SCIM group to a role no longer returns a 500 error, editing a predefined attribute mapping now works, and saving a mapping backfills values for existing SCIM users. To prevent bad configurations, text attributes can no longer be mapped to boolean user properties, and any existing invalid mappings are now flagged directly in the dialog.
We've also tightened how directory-synced users are managed, so changes can't be made out of band and then overwritten by the next sync. These users no longer show Delete, Remove from org, Suspend, or Reset password in the user list menu (matching their profile page), and they can no longer be added to other organizations. Every path that could previously do this — import, admin add-user, the create-user API, SCIM, and access requests — now returns a clear blocked message, and the bulk organization users endpoints include a new users_blocked field so you can see when this happens programmatically.
Billing and self-serve plan fixes
B2C subscribers can now cancel their own plan from the self-serve portal under My Account → Plan → Cancel plan. If you've attached a cancellation request workflow, the button instead reads Request to cancel.
Plans assigned through the Management API or by admin manual assignment now charge the customer's default payment method automatically, matching self-serve signup — previously these were invoiced. If you rely on invoicing for manually assigned plans, this is a behaviour change worth noting.
We also fixed a range of cancellation bugs: denied workflows with no description now open the denied dialog, malformed agreement ids no longer cause a 500, expired plans no longer show a false "Plan cancelled" toast, and tightened authorization on plan cancellation.
Bring your own SMS with Sinch Engage
Sinch Engage (formerly MessageMedia) joins Twilio as a bring-your-own SMS provider for phone authentication. Connect your Sinch Engage account with your API key and secret, choose your account region (Asia Pacific or Europe), and set your sender number — and Kinde will deliver verification codes through your own Sinch Engage account. Configure it under your phone connection settings, right alongside the existing Twilio option.
Customize your auth pages’ browser tab titles
You can now edit the browser tab title of your hosted auth pages, so the sign-up, sign-in, verification code, and other authentication pages show exactly the wording you want in the browser tab. Each page's title is edited individually in the page content editor, supports the business name placeholder, and can be translated per language like other page content. If you're rendering pages with custom code, Kinde will let you know that your code controls the tab title on those pages.
Collect billing details before the first invoice
Organization customers can now enter their legal business name, billing address and tax ID alongside their payment method at checkout, so these details are on the first invoice instead of being added afterwards. Turn it on under Settings → Billing → Collect billing details on payment step for organization billing. It's off by default for existing environments and on for new ones. If Stripe rejects an address or tax ID, the customer is returned to the payment page with an explanation rather than having sign-up fail. Billing address, tax IDs, phone and description now also appear in the admin area and the self-serve portal for both organization and user customers. Admins with update:plan_details and customers with org:write:billing or family:write:billing can edit them. New organizations created with a placeholder name are also renamed to their legal business name once their billing details are accepted.
OAuth2 response caching
All OAuth2 responses are now marked no-store, so CDNs and other caches no longer keep or serve one user's profile or authorization details to another caller. The user profile endpoints also send Vary: Origin, Authorization as a secondary safeguard.
Minor fixes and improvements
The sign-up confirmation code page now documents the
${email_address_obfuscated}and${email_address_unobfuscated}placeholders${email_address}stays obfuscated by default, and you can opt in to showing the full email with${email_address_unobfuscated}Kinde domains are now capped at 50 characters, so business and environment domains no longer exceed the 63-character DNS label limit and silently fail to resolve.
SDKs
Here's some other changes to SDKs:
PKCE JS SDK: Fixed token refresh issues from lingering tab-sync and visibility listeners, restored legacy
org_codemapping in login, register and create-org, and updatedjs-yamlfor securityNode Express SDK: Security fix upgrading qs to resolve a reported vulnerability, plus updated Kinde TypeScript SDK dependency (v2.15.1)
Android SDK: Added in-code configuration with KindeConfig, enabling apps to connect to different Kinde environments, such as one per region, without using AndroidManifest meta-data
SvelteKit SDK: Added configurable session cookie expiry via KINDE_SESSION_MAX_AGE, plus dependency updates
JWT Decoder SDK: Security update to vitest 4.1.11, plus routine tooling and dependency updates
JS Utils SDK: Updated dependencies including eslint, @types/chrome, pnpm, and vite
Expo SDK: Fixed an issue where tokens could be lost to the keychain while the device was locked, and updated dependencies