October 2026
Engine webhook verification (Engine 2.0.3)
October 21, 2026- Core webhooks to Nozle’s Engine are verified with the sending organization’s own
hmac_key. Every organization’shmacendpoint is accepted; an unsigned, forged or cross-organization request, or one whose organization is unknown, gets401in every environment, and the Engine answers503if the key cannot be read so that Core retries. Engine webhook endpoints must use thehmacsignature algorithm:jwtendpoints are rejected. See Webhooks to the Engine. - A signed webhook that names another organization’s subscription no longer creates that subscription’s credit grants.
- The
NOZLE_WEBHOOK_SECRETsetting is removed and ignored.
Razorpay, Stripe and plan configuration fixes (API 3.8.11)
October 21, 2026- Razorpay customers created in the dashboard, or assigned to a Razorpay connection without a link, can pay credit top-ups, invoice payment URLs and overdue-invoice payment links without a plan checkout first: the missing link is created on the next attempt (3.8.3). See Razorpay.
- Razorpay customer sync links a buyer who already exists in your Razorpay account, sends a new request after the customer’s details are corrected, reconciles requests with an unknown outcome, and sends the phone as E.164 digits (3.8.4).
- Retry payment on an invoice whose UPI AutoPay debit failed debits the mandate again right away instead of doing nothing for 24 hours, and each failed attempt sends exactly one failure notification (3.8.5). See Recurring payments with UPI AutoPay.
- Razorpay reconciliation stops checking abandoned checkouts after their expiry plus one hour and checks older operations hourly. Razorpay rate limits (HTTP
429) on orders, links, debits, refunds and customer sync are retried instead of failing the refund or the collection (3.8.6). See Reconciliation and rate limits. - Razorpay invoice and payment-request checkouts paid before their expiry settle the invoice even when the payment is processed later, and checkout status reports
needs_reviewfor a capture held behind another payment in progress (3.8.7). See Status. - At a downgrade, the terminating invoice, the new plan’s pay-in-advance fee and the
subscription.terminatedandsubscription.startedwebhooks are produced only after the change is saved, so they always describe the committed state (3.8.8). - Fees of a deleted Feature count again in the minimum commitment true-up (no more over-billing), appear in the invoice’s recurring breakdown and are returned by
GET /fees?feature_code=(3.8.9). See Fees of deleted Features. - Connecting Stripe during a short Stripe outage or rate limit retries the webhook registration, and when it still fails a
payment_provider.errorwebhook is sent. Renaming a Stripe connection code registers the endpoint if it was missing, reports a missing webhook permission aspayment_provider.error, and Stripe events sent to the previous code’s URL are still accepted until the endpoint URL is updated (3.8.10). See Webhook setup. - GraphQL
createOrUpdatePlanConfiganswersnot_foundfor a plan of another organization or an unknown plan, and a plan never shows a plan configuration written by another organization. Such configurations written before are removed (3.8.11). - Includes API 3.8.3, 3.8.4, 3.8.5, 3.8.6, 3.8.7, 3.8.8, 3.8.9 and 3.8.10.
Dashboard 1.7.0
October 21, 2026- Cost Sheet form: the margin policy is created after the Cost Sheet is published. If publishing fails, no policy is created and the draft stays. If only the policy cannot be saved, the Cost Sheet stays published, the dashboard says that no margin policy is active for the Feature, and opens the sheet.
- New When cost can’t be estimated select (Allow, Warn, Deny): what
/candoes when the Feature has no cost estimate, as in the AI-token path (detailed_events_only). With that path it follows the policy mode until you change it, so a Deny policy now denies. Before, the dashboard always sent Warn. See Margin policy. - Overview, hub and invoice aging report: MRR, ARR, Outstanding and Overdue tiles show only the total in your default currency, with the unit inline (“$1,677.23 /mo"). An info icon beside the figure shows the per-currency split ("By currency: ₹143,994.00 · $153.00”) and appears only when more than one currency is involved. The “Converted to … at the ECB rate of …” line of 1.6.0 is gone, from the tiles and the aging report export.
Engine 2.0.2: subscription selection, running totals and billing periods
October 21, 2026- Breaking (2.0.0):
GET /canaccepts optionalsubscription_idandentity_id. Without them, a customer with several current subscriptions is evaluated on its one own (not Entity-owned) subscription; when there is none or more than one, it answers200withallowed: falseandreason: subscription_required, andPOST /billing/upgradeanswers409 subscription_required. Before, both used the most recently started subscription. A customer with one current subscription sees no change. Sendsubscription_idorentity_idfor customers with several. See Which subscription is checked. - Usage counters are kept per subscription, so one Entity’s seat never counts against another subscription’s limit. Only subscriptions that are current now count.
- Recurring Features (seats, storage) keep one running total across billing periods, so a hard limit no longer reopens on the first day of a period.
/canreports the realusedof a metered Feature that is only priced by a charge, withlimitandremainingnull. Before it was 0. /canusage follows the billing period Nozle invoices in, for every plan interval, calendar and anniversary billing, and the customer’s time zone (2.0.1). Semiannual plans reset every six months; yearly and semiannual plans that bill charges monthly reset monthly; weekly calendar periods start on Monday; anniversary dates on the 29th to the 31st use the last day of shorter months. See Usage and billing periods.- Credit usage (
POST /usage/checkandPOST /usage/track) accepts every credit rate: an amount that does not end within 12 decimals is rounded up to 12 decimals, so usage is never under-charged (0.333333333334for 1 event at 1 credit per 3). Before, it answered422 credit_usage_configuration_invalid. A boolean or config Feature answers422 feature_not_consumableinstead of500(2.0.2). See Amount rounding and Features. - One dead-lettered usage event no longer blocks credit usage for the whole organization.
503 credit_usage_publication_backlognow means 1,000 or more events still being retried, or the oldest older than 5 minutes, and clears by itself. Failed deliveries are retried for about a day before an event is dead-lettered (1.9.1). See usage track. - Wrapped LLM calls are costed when the parent Feature has no cost composition (for example an AI-token Cost Sheet with “Linked feature: none”): each cost event is rated on its own meter and attributed to the parent’s customer, subscription and Feature, and counts in margin. Cost events recorded before need a replay (parent Feature Event first, then its cost events) (1.9.2). See AI token billing.
GET /analytics/overviewreturns invoiced revenue (invoiced_revenue_cents,previous_period_invoiced_revenue_cents,invoiced_revenue_mom_percent,invoiced_revenue_by_currency, and the dates of both windows) next to the estimated usage revenue, and month over month compares the same days of the previous month. Before, on October 2 with flat revenue it showed -96.7% (1.10.0). See Overview revenue.- Includes Engine 1.9.1, 1.9.2, 1.10.0, 1.11.0, 2.0.0, 2.0.1 and 2.0.2.
Legacy keys, entitlement fixes and checkout origins (API 3.8.2)
October 21, 2026- The old key names are back until January 19, 2027, then removed. Since API 1.0.0 the REST, webhook and CSV keys had been renamed from the former product prefix to
nozle_(nozle_id) or to no prefix (customer_id) without notice. Until January 19, 2027 (inclusive), REST responses and webhook payloads carry each old key beside its new key, with the same value, on every object that had it; the old EU tax codes resolve tonozle_eu_*intax_codesandGET,PUTandDELETE /taxes/{code}; and CSV exports repeat the id columns at the end under their old names. Thenozle_*keys stay. Read the new keys before that date: after it the old names are removed. The key list is on API standards, and the exact old names are in the OpenAPI specification. - Entitlement
PATCH(/plans/{code}/entitlementsand/subscriptions/{external_id}/entitlements) changes only the metered settings it sends.{"hard_limit": false}keeps the usage limit, and an omittedmin_margin_percent,margin_enforcement_modeorenforce_plan_marginis unchanged. Before, every omitted setting was reset (no usage limit, hard limit, no margin floor,enforce). On a subscription, omitted settings keep the subscription’s override, or the plan’s value.POSTstill replaces the whole entitlement. Restoring a removed feature or dropping an override now reaches/canwithin its usual refresh (3.5.1). - Onboarding’s launch check: GraphQL
Event.matchCustomerandEvent.matchSubscriptionnow match events stored in Postgres to their customer and subscription, so a correct event no longer shows “No customer owns this event” (3.5.2). - A plan change that takes effect now is refused with
422 outstanding_invoicewhile the subscription has a paid invoice whose payment was lost in a dispute, and a termination or plan change no longer credits the unused part of such a period (3.5.3). See Outstanding invoices and lost disputes. - The finalized revenue of the Cost Intelligence report is by service period, in major units of each currency (JPY was 100 times too low, KWD 10 times too high).
costandfinalizedMargincan benull, and the newcostStatusisloadedornot_loaded(3.6.0). See Finalized revenue. - An immediate upgrade with
proration_behavior: nonethat keeps the billing anchor now invoices the current plan for its period up to the change. The new plan’s fee starts at the next anchor and no credit note is issued. Before, nothing was billed (3.6.1). See Proration on a mid-cycle upgrade. - Usage thresholds are refused with
422andusage_thresholds: [feature_not_available]on a plan without progressive billing, and lifetime usage answers403 feature_not_availablewithout lifetime usage or progressive billing. Before, thresholds were dropped and lifetime usage returned amounts that were never computed (3.7.1). See Premium features. - Each organization can register
checkout_return_origins(up to 20 HTTPS origins) and acheckout_default_return_url, throughPUT /organizationsand GraphQLupdateOrganization(developers:manage). Checkout return URLs are accepted on those origins and on the deployment’s own. Without a return URL the customer returns to the default URL, else the first origin, else the provider’s success URL (3.8.0). See Return URLs. POST /credit-top-up-purchaseschecks the customer’s payment provider before it creates anything: a provider error leaves no invoice, purchase or webhook, and a retry creates nothing. A successful purchase writes itscredit_top_up_purchase.createdactivity log (3.8.1).- Automatic dunning runs for organizations whose Nozle plan includes it (Growth and up). A customer or billing entity accepts only a dunning campaign of its own organization (another’s answers
not_found), and applying the billing entity’s current campaign again succeeds (3.8.2). See Payments. - Includes API 3.5.1, 3.5.2, 3.5.3, 3.6.0, 3.6.1, 3.7.0, 3.7.1, 3.8.0 and 3.8.1.
Dashboard 1.6.0
October 21, 2026- Settings > Billing settings > Plan: the plan cards show the prices, limits and descriptions of nozle.dev/pricing, including $0.04 per 1,000 events over the included amount on Starter, Growth and Scale and ”+ 0.6%” / ”+ 0.5%” revenue share. A note says that passing the MRR limit upgrades the workspace automatically, from Starter to Growth and from Growth to Scale. See Nozle plans and pricing.
- The current plan shows two usage bars: Events used this period (events used against the included events) and MRR tracked (tracked MRR in USD against the plan’s MRR limit). A bar without a number reads Not reported instead of 0%. See Usage on the Plan page.
- Overview and analytics: MRR, ARR, Outstanding and Overdue show one total converted to your organization’s default currency, with a label that names the currency and the ECB rate date, and the amount per currency underneath (“By currency: ¥50,000 · $434.80”). This covers the Overview tiles, the overdue balance panel, the attention queue, the overdue balance card and the invoice aging report. Before, these amounts were shown as USD whatever the currency. An organization that bills only in its default currency sees no extra lines.
- Analytics panels that are not available, such as MRR movement and retention, say so and offer no Retry button. Before, they showed “Could not load” with a Retry that could never work.
- Includes dashboard 1.5.0.
Workspace billing and converted totals (Engine 1.8.1)
October 21, 2026- Your workspace’s usage is now billed through Nozle’s own billing: its processed events are reported to your Nozle plan every hour, and events over the included amount are billed at $0.04 per 1,000 events at the end of the month. A plan change in the middle of a month bills every event once. See Nozle plans and pricing.
- The Growth and Scale revenue share is charged on collected revenue: your paid invoices excluding tax, minus refunds, converted to USD at the rate of the payment date (the official peg for AED, SAR, QAR, BHD, OMR and JOD, otherwise the ECB reference rate, with a second daily public source for currencies the ECB does not publish). See Revenue share.
GET /analytics/overviewreturnsmrr_total_default_cents,arr_total_default_centsandfx_date, andGET /analytics/invoices-summaryreturnsoutstanding_total_default_cents,overdue_total_default_centsandfx_date: the amounts of every currency converted intocurrency, the organization’s default currency.fx_dateis the date of the market rates used; it is null when nothing needed converting or only pegs were needed. A total is null when one of its currencies has no rate. The per-currency split (mrr_by_currency,by_currency) is unchanged.- Nozle’s billing status of your workspace adds
events_used,events_included,events_used_percent,mrr_tracked_usd_cents,mrr_limit_usd_cents,mrr_used_percentandplan_limits, which the Plan page shows as usage bars. The billing status of your own customers is unchanged. See Plan status fields. - Includes Engine 1.5.0, 1.6.0, 1.7.0 and 1.8.0.
Nozle plans, converted totals and security logs (API 3.4.0)
October 21, 2026- Nozle plans: events over the included 50K (Starter), 10M (Growth) or 100M (Scale) are billed at $0.04 per 1,000 events in 1,000-event blocks at the end of the month and are never blocked. The revenue share, 0.6% on Growth and 0.5% on Scale, is charged on collected revenue in USD. The MRR limits are $5K, $100K and $1M. See Nozle plans and pricing.
- Your tracked MRR is checked once a day. Passing the limit upgrades Starter to Growth and Growth to Scale, with the same plan change as the dashboard’s upgrade: charged and applied at once with a saved payment method, otherwise when its checkout is paid. There is no automatic downgrade. Scale over $1M stays on Scale; contact sales for Enterprise. Usage emails at 50%, 80%, 90% and 100% are coming later. See MRR limit and automatic upgrade.
- Premium features come with your plan. Growth includes remove branding, auto-dunning, progressive billing and lifetime usage; Scale adds API key permissions, security logs, custom from-email, payment receipts, manual payments and multi-entity. They switch on when you pay for the plan and off when you downgrade or the subscription ends. See Premium features.
- Upgrading from Growth to Scale works. Before, it was refused with
plan_transition_policy_required. - Your Nozle invoice stays a draft for one day after the period ends, so usage that arrives late within that day is still billed in its own period. The Growth and Scale fee of a renewal is collected one day later.
- GraphQL
nozleAnalyticsOverviewaddsmrrTotalDefaultCents,arrTotalDefaultCentsandfxDate, andnozleAnalyticsInvoicesSummaryaddsoutstandingTotalDefaultCents,overdueTotalDefaultCentsandfxDate: the amounts of all currencies converted to your default currency, from Engine 1.8.1. All are nullable; existing fields are unchanged. - Listing security logs (GraphQL
securityLogs, RESTGET /security_logs) no longer fails with a server error when a log holds a null value, such as no operating system for an API client or a rotated API key without a name. Null values are returned asnull, and a log without device info or resources returns{}. - Revenue analytics, analytics dashboards and forecasted usage remain unavailable. Their GraphQL queries and
GET /analytics/usageansweranalytics_unavailablein every case, never an internal error. - Includes API 3.1.18, 3.1.19, 3.2.0 and 3.3.0.
Dashboard 1.4.8
October 21, 2026- Onboarding, Connect step: Reveal and copy shows and copies the full secret key, and the sample
curlcarries it. Before, it copied the masked key and the request failed with401. A key created in the step is the one shown. - The sample event no longer sends a
timestamp, so Nozle stamps the time it receives it and the event counts for a new subscription. Its transaction id isonboarding-plus 8 random hex characters, new on each visit to the step, so running the sample again is not dropped as a duplicate. The step’s documentation links open working pages. - Developers > API keys: a publishable key reads Plan catalog · read only. Without API key permissions, every secret key reads Full access (permissions not enforced on this plan). With them, a key reads Full access only when it has read and write on every resource, and otherwise Restricted with its grants, for example Restricted · plan: read. Creating a secret key, or Edit (formerly Rename), shows a read and write picker per resource. See Key permissions.
- Settings > Access: members show their roles, and editing roles keeps the ones they have. Before, every member showed “No role assigned” next to the Admin badge, and adding a role removed Admin. Administrator now stands on its own: ticking it selects Administrator only, and the other roles show as included. A member stored as Administrator plus other roles opens as Administrator, and saving stores Administrator only.
- Includes dashboard 1.4.6 and 1.4.7.
Analytics, API key permissions and catalog CORS (Engine 1.4.0)
October 21, 2026- With API key permissions, every Engine secret-key route now checks the key:
POST /customersneedscustomer:write,POST /check-and-deductcredit_system:write,GET /auth/centrifugo-tokencustomer_usage:read,POST /cost-eventsevent:write, cost models and Cost Intelligenceanalytic:readoranalytic:write, and/analytics/*,/margin/*andPOST /margin/simulateanalytic:read. A key without it gets403 permission_denied. Organizations without API key permissions see no change. See Engine routes. POST /analytics/snapshotandPOST /onboarding/chatare internal to Nozle and accept only its internal service token. Secret keys get403.- The publishable-key plan catalog,
GET /plansandGET /plans/{code}, answers CORS from any origin withAccess-Control-Allow-Origin: *and no credentials, soPricingTableandusePlansload plans on your own site. Every other route keeps the origin allow-list. See the public plan catalog. GET /analytics/overviewreturnscurrencyandmrr_by_currency(currency,mrr_cents,arr_centsper plan currency).GET /analytics/invoices-summaryreturnscurrencyandby_currency(currency,outstanding_cents,overdue_centsper invoice currency).mrr_cents,arr_cents,outstanding_centsandoverdue_centsare incurrency: the organization’s default currency, or the only currency it bills in. Before, amounts in different currencies were added together. Invoice counts still cover every currency.- MRR is the monthly equivalent of each active subscription’s plan amount: weekly × 52 / 12, monthly × 1, quarterly / 3, semiannual / 6, yearly / 12. ARR is the yearly equivalent. A 1,200.00 yearly plan now counts 100.00 MRR and 1,200.00 ARR (before: 1,200.00 MRR and 14,400.00 ARR). Subscriptions still in their trial and subscriptions of deleted customers are left out. This MRR is subscription-based, so it can differ from the invoice-based
GET /analytics/mrr. - When the billing data or the analytics store cannot be read, the analytics overview, the invoices summary and the
/analytics/*and/margin/*reads answer503 analytics_unavailable, instead of zero revenue or500 internal_error. A missing analytics schema still answers503 analytics_schema_missing. The MRR history gets no zero day from such a failure. See Margin dashboard.
Plan catalog, analytics and branding (API 3.1.17)
October 21, 2026- GraphQL
nozleAnalyticsOverviewaddscurrencyandmrrByCurrency(currency,mrrCents,arrCents), andnozleAnalyticsInvoicesSummaryaddscurrencyandbyCurrency(currency,outstandingCents,overdueCents), from Engine 1.4.0. When analytics cannot be computed, these queries answer a GraphQL error with the codeanalytics_unavailableandstatus: 503instead of an internal error. - Hiding a plan family or a feature from the pricing table only removes it from the pricing table list.
GET /plans/{code}with a publishable key returns a plan of a hidden or deleted family instead of404, and every plan, listed or read by code, carries all its entitlements and charges, including those of hidden features. Plans pending deletion still answer404to publishable keys. See Which plans are returned. - A subscription on an override plan, such as one created from a quote, changes plan with the transition policies of the catalog plan it was made from: options, preview, checkout and transitions no longer answer
plan_transition_policy_required. The new plan is the target catalog plan, so the negotiated price does not carry over. A self-serve change to its own catalog plan answersplan_already_active. See Plan transition policies. - “Powered by Nozle”: organizations whose Nozle plan removes the branding and that never saved a choice keep it hidden in the SDK components and the customer portal, as before 3.1.0; this corrects the React SDK 0.13.0 note of October 19. Saving
hideBranding: falseshows it again. Invoice, credit note and payment receipt PDFs now always show it. GraphQLCurrentOrganization.canHideBrandingsays whether your plan lets you hide it. See Powered by Nozle. - Approving a one-off quote version (GraphQL
approveQuoteVersion) no longer needstotalAmountCentsin each add-on item. Nozle computes it asround(unitAmountCents × units), also inoverridesthat change the units or the unit amount, and replaces any total the client sends. - Breaking: the GraphQL mutations
createRole,updateRoleanddestroyRoleand their input types are removed. Custom roles are no longer part of the product. The built-in roles areadmin,financeandmanager, and therolesquery lists them. - Revenue analytics, analytics dashboards and forecasted usage are not available.
GET /analytics/usageanswers503 analytics_unavailable.
Node.js SDK 0.13.1
October 21, 2026@nozle-js/node0.13.1: Behaviour change:wrapOpenAIandwrapAnthropicreturn a new view of the client and never change the client you pass in. Use the returned client: code that ignored the return value and kept calling the original client no longer records usage.- Fixed: wrapping one shared client for several customers recorded an event for every one of them on each call. Each view now records once, for its own
customerId, so you can keep one provider client and wrap it per request. Wrapping an already wrapped client wraps its original.withResponse(),parse(),stream()and streaming keep working and record once. See Client wrappers. - Install with
npm install @nozle-js/node@0.13.1.
Python SDK 0.13.1
October 21, 2026nozle-sdk0.13.1: Behaviour change:wrap_openaiandwrap_anthropicreturn a view of the client and never change the client you pass in. Use the returned client: code that ignored the return value and kept calling the original client no longer records usage.- Fixed: wrapping one shared client for several customers recorded an event for every one of them on each call. Each view now records once, for its own
customer_id, for sync and async clients and streams. Every other attribute is read from the original client,isinstancechecks still pass, and wrapping an already wrapped client wraps its original. See Client wrappers. - Install with
pip install nozle-sdk==0.13.1.
Dashboard 1.4.5
October 21, 2026- Saving the General, Invoicing, Address or Notifications settings sends only the fields you edited, so it no longer resets the default billing entity’s email, email settings, net payment term or grace period. Notifications edits the default billing entity’s email settings.
- Editing a usage limit in a plan family sets the limit of that plan only, so a monthly and a yearly plan keep their own limits.
- Adding a billing interval to a plan pre-fills the form from the source plan, as Duplicate does: charges, fixed charges, trial and taxes. A note lists what was copied. Amounts are copied unchanged, so adjust them for the new interval.
- Includes dashboard 1.4.4. Version 1.4.5 changes only tests.
Usage, credits and entitlements (Engine 1.3.3)
October 21, 2026/usage/checkand/usage/trackaccept an optionalsubscription_id, the external id of the active subscription that pays. Withentity_id, the Entity’s own active subscription pays, else the customer’s own; customers with one subscription per Entity no longer get422 active_subscription_ambiguouson every call. See Which subscription pays.- A customer with no active subscription can spend credits that do not need one: paid top-ups, opening balances, and plan credits left after a cancellation until they expire. That usage sends no billing event. Before, every call returned
404 active_subscription_not_found. - Several candidate subscriptions and no selector still return
422 active_subscription_ambiguous; the message now namessubscription_idandentity_id. Event ingestion and the LLM proxy choose subscriptions as before. - With API key permissions,
/usage/checkneedscredit_system:readand/usage/trackneedscredit_system:write; a key without it gets403 permission_denied. Before, any secret key could spend credits. See Key permissions. /cangives a subscription on an override plan, such as one created from a quote, the entitlements and usage limits of the catalog plan it was made from. Before, boolean and config features were denied withno_entitlement, and metered features had no limit.- Cancelling and subscribing again no longer grants plan credits twice for a period the cancelled subscription’s unexpired credits still cover; the new grant is reduced by them, prorated by time. Lifetime plan credits are granted once per customer (or Entity) and Credit System. See Included Plan Credits.
- A plan change that moves a Credit System to another cadence, such as monthly to yearly inside a plan family, grants the new cadence once. Before, it granted nothing and usage was denied with
insufficient_credits. A grant that fails for one Credit System no longer holds back the others. - Refunded or lost-dispute top-ups lose their unspent credits once, as
revokeoperations with the reasontop_up_credit_noteortop_up_dispute_lost. Credit operations addrequested_credit_amountonrevoke. See Refunds and lost disputes. - The Entity credit balance reads
pool_policyandeffective_availablefrom the subscription that pays for that Entity’s usage. - The
/admin/*routes accept only Nozle’s internal service token. Organization secret and publishable keys get403. - Reliability: an event accepted by
POST /eventsis always post-processed (pay-in-advance fees, wallet refresh), even when an internal queue is briefly unavailable.
Billing, checkout and API keys (API 3.1.10)
October 21, 2026- Breaking: a plan created through
POST /plans, GraphQL, the dashboard onboarding or the Agent Kit is shown on the pricing table by default again, so the public plan catalog lists it at once. Since 3.0.0 its new plan family started hidden, andGET /plans/{code}answered404 plan_not_found. Sendshow_on_pricing: false(GraphQLshowOnPricing: false) to create it hidden. Existing families keep their visibility. - Usage limits stay per plan inside a plan family. Entitlement writes set
usage_limitandhard_limiton the plan in the path only; features and privileges are still shared by the family. GraphQLupdatePlanFamilyEntitlementsacceptsplanId. - Stripe invoice checkout keeps one payable Checkout Session per invoice: calling it again returns the open session, and a payment in progress answers
422withpayment_already_processing. A second successful payment for an invoice that is already paid is refunded in full, and you get theinvoice.payment_failurewebhook withduplicate_payment_refunded. See Stripe checkout flow. - Payment provider webhooks act only on records of the organization that received them, for Stripe and every other provider.
- A credit note or a lost dispute on a paid top-up invoice takes back the top-up’s unspent credits. See Refunds and lost disputes.
- A customer upsert sends Stripe only the name, email, phone and address that changed, so edits made in Stripe are no longer overwritten. See Assign the connection to customers.
- Wallet endpoints accept and return
grants_target_top_upon recurring rules, as documented. Before, it was dropped, and a rule meant to grant free credits created a paid top-up invoice.trueon a rule that is notmethod: targetreturns422 invalid_recurring_rule. - API key permissions: creating a key with permissions on an organization without API key permissions is refused with
premium_integration_missing. Rotating a key keeps its permissions. Plan transition policies have their ownplan_transition_policypermission. See Key permissions. - Saving organization settings (
PUT /api/v1/organizations) copies to the default billing entity only the fields it changes. Before, a save such as a logo change could blank the billing entity’s email and email settings, and customer emails stopped. Edit the billing entity itself to change its own values. - Executing a signed quote applies package, graduated, volume and percentage charge settings from the dashboard, and stores a charge minimum in cents (a $50 minimum was stored as $0.50). Quotes already signed are fixed without changes.
React SDK 0.13.0
October 19, 2026@nozle-js/react0.13.0: the dashboard page Developers > Customize SDK saves the appearance (theme, colours, plan card options) for your organization, and every SDK component picks it up automatically with no code. Props in code win: componentappearanceoverBillingProviderappearanceover the saved appearance. Set<BillingProvider savedAppearance={false}>to ignore it. See Saved appearance.- Global and component settings. Developers > Customize SDK has two tabs: Global settings (theme, colours, radius, “Powered by Nozle”, and the
BillingProvidercode to paste at the root of your app) and Component settings, where one component gets its own theme and colours that apply to it only. They sit above the global settings and below theappearanceyou pass in code. See Saved appearance. - Plan buttons: with no current plan known, every paid plan gets the primary button; with
currentPlanCode, plans above it get the primary button, the current plan uses the primary colour with no shadow, and plans at or below it get a plain button. Contact-sales plans stay outlined. See Plan buttons. - “Powered by Nozle” shows by default for every organization. A plan that removes the branding can turn it off for all components in Developers > Customize SDK > Global settings > Branding. It now shows by default, also for plans that removed it before, until you turn it off. See Powered by Nozle.
Saved SDK appearance in the plan catalog
October 19, 2026GET /api/v1/plansreturnsmeta.sdk_appearance, the appearance saved for the organization ({}when none), for publishable and secret keys. It can hold the global settings and, undercomponents, the settings of single SDK components, plushideBranding. The saved object is at most 8 KB.GET /plans/{code}does not return it. See the public plan catalog.
Nozle Agent Kit 1.0.4
October 18, 2026- Agent Kit 1.0.4 follows the SDK releases of October 17. On Node, the agent captures LLM usage with
captureFetch()for any client that accepts a customfetch, including the Vercel AI SDK, LangChain and Gemini. On Python and Go, it captures through the provider’s HTTP client. It serves billing screens throughcreateBillingHandler()and the React billing hooks, verifies webhooks with the SDK helpers, and reads errors byNozleApiErrorstatus and code. - It also follows the current API: plan families,
change_atand pay-first plan changes, 422 for an event that matches no active subscription or several, andnulllimits fromcan(). - The agent builds in small phases, in dependency order, and tests and commits each phase locally. Billing runs only through Nozle checkout and Nozle subscriptions with a supported provider, so renewals, plan changes and cancellations stay in Nozle.
- The guards block a client file that imports
@nozle-js/node, and treat capture helpers like the LLM wrappers when they check for double billing. - To update, see Install and update. Codex CLI users run the
hosts codex --writecommand again in each app, because the hook path contains the version.
Node.js SDK 0.13.0
October 17, 2026@nozle-js/node0.13.0:new Nozle()readsNOZLE_SECRET_KEYwhen you pass noapiKey. Thehostoption (defaulthttps://api.nozle.app) fills inbaseUrlandeventsUrl. Opt-in retries withmaxRetriesandretryDelayMsrepeat only requests that are safe to repeat. See Installation.- Every call that gets a non-2xx response throws
NozleApiError, which now carriesrequestIdandretryAfter. The message keeps its<operation> failed: <status> <statusText>form and the class still extendsError. See Errors and retries. captureFetch()returns afetchthat records the token usage of OpenAI-compatible, Anthropic and Gemini responses, for any client that accepts a customfetch.recordUsage()records usage your code read itself. Capture reportsfeature_not_foundonce per event code throughonErrorwhen no Feature has that code. See LLM auto-capture.getSubscriptions(),currentUsage()andpastUsage()read Core subscriptions and usage. Theinvoicesnamespace lists invoices (withpaymentOverdueand other filters), reads one and returns its PDF URL. Thealertsnamespace manages usage and wallet balance alerts. See Billing.webhooks.verify()andcreateWebhookHandler()check theX-Nozle-Signatureof the webhooks Nozle sends. See Receive Nozle webhooks.createBillingHandler()serves the React billing hooks from your backend with your secret key; the customer always comes from your session. See Provider and hooks.- Fixed:
wrapOpenAIandwrapAnthropickeep the SDK’s ownAPIPromiseandStream, sowithResponse(),asResponse(),chat.completions.parse(),messages.stream()/finalMessage(),stream.controllerandtoReadableStream()work on a wrapped client. Usage is recorded once, when the response is read (not forasResponse()); a stream records when it is fully iterated. The optional peer dependency is@anthropic-ai/sdk.checkAndDeduct()is deprecated: useusage.check()andusage.track()with a credit system. See LLM auto-capture. - Usage events recorded by
wrapOpenAI,wrapAnthropicandcaptureFetchuse the provider’s response id as the transaction id, so the same response is never recorded twice. - Fixed:
usage.track()reuses the timestamp it filled in when the same idempotency key is sent again on the same client, so a retry no longer fails with409 idempotency_key_reused. - Breaking:
CanResult.limitandCanResult.remainingare typednumber | null,nullwhen the feature has no limit. Code that checked=== undefinedshould check== null.PingResult.versionandSubscriptionOptions.blocked_reasonare removed from the types; the API never sent them. - Install with
npm install @nozle-js/node@0.13.0 @nozle-js/react@0.11.0 @tanstack/react-query.
React SDK 0.11.0
October 17, 2026@nozle-js/react0.11.0 adds customer billing hooks built on TanStack Query:useSubscription,useEntitlement,useCreditBalance,useCreditHistory,useUsage,useUpgradePreview,useBillingRefresh,useInvoicesanduseInvoiceDownload. They read your backend route set asBillingProviderbillingEndpoint(served bycreateBillingHandlerfrom@nozle-js/node0.13.0), so the browser never holds a secret key. See Provider and hooks.- New components:
CurrentPlan,CreditBalance,CreditHistory,UsageBreakdown,UsageTrendandPoweredByNozle. PricingTable,PlanCardandPlanComparisonshow what each plan gives from the public catalog (entitlements, credit grants and usage prices) and sort plans by price, cheapest first.planFeatures(),comparisonRows()andsortPlansByPrice()return the same data for your own layout.- Appearance themes and variables; see React themes below.
- Fixed:
PricingTableshows the real billing interval instead of/monthfor every plan that is not yearly,PlanCardprints the plan’s own currency, and the annual toggle no longer shows a hard-coded “Save 20%”. Component buttons aretype="button", so they no longer submit a surrounding form. - Breaking:
@tanstack/react-query5 or later is a required peer dependency. - Breaking: the customer hooks need
billingEndpointonBillingProviderand a backend route that serves them. - Breaking:
PlanCardtakes a catalogplaninstead ofid,name,monthlyPrice,annualPrice,description,isAnnualandchildren, and thePlantype export is removed.PlanComparisontakes catalogplans, and itsfeaturesrows are keyed by plancode. - Breaking: components no longer read Tailwind or shadcn variables, and
PricingTablemarks contact-sales plans fromcontactSalesPlansinstead of their names. See “Upgrading from 0.10” on the Appearance page. - Install with
npm install @nozle-js/node@0.13.0 @nozle-js/react@0.11.0 @tanstack/react-query.
Python SDK 0.13.0
October 17, 2026nozle-sdk0.13.0 addsAsyncNozlefor asyncio apps, with the same arguments, namespaces and methods asNozle, awaited. See Installation.Nozle()readsNOZLE_SECRET_KEYwhen you pass noapi_key. Thehostargument (defaulthttps://api.nozle.app) fills inbase_urlandevents_url. Opt-in retries withmax_retriesandretry_delayrepeat only requests that are safe to repeat.NozleAPIErroraddsrequest_idandretry_after.wrap_http_client(),capture_http_client()andcapture_async_http_client()record the token usage of any LLM client built on httpx or httpx2;record_usage()records usage your code read itself. See LLM auto-capture.current_usage()andpast_usage()read Core usage.invoices.list()(withpayment_overdueand other filters),invoices.get()andinvoices.download_url()read invoices, and thealertsnamespace manages usage and wallet balance alerts. See Billing.webhooks.verify()checks theX-Nozle-Signatureof the webhooks Nozle sends. See Receive Nozle webhooks.entity_subscriptions.change_plan()acceptsbilling_time.- Fixed: requests leave out optional fields you did not set instead of sending JSON
null, so the API applies its defaults.usage.track()reuses the timestamp it filled in when the same idempotency key is sent again on the same client. PingResult.versionandSubscriptionOptions.blocked_reasonare removed from the types; the API never sent them.- Install with
pip install nozle-sdk==0.13.0.
Go SDK v0.12.0
October 17, 2026github.com/nozle-dev/nozle-gov0.12.0:NewreadsNOZLE_SECRET_KEYwhen the key argument is blank.WithHost(defaulthttps://api.nozle.app) fills in the Engine and Core URLs. Opt-in retries withWithMaxRetriesandWithRetryDelayrepeat only calls that are safe to repeat.APIErroraddsRequestIDandRetryAfter. See Installation.WrapHTTPClientrecords the token usage of any LLM SDK that takes an*http.Client, andRecordUsagerecords usage your code read itself. See LLM usage capture.CurrentUsageandPastUsageread Core usage.ListInvoices(withPaymentOverdueand other filters),GetInvoiceandInvoiceDownloadURLread invoices, andListAlerts,GetAlert,CreateAlert,UpdateAlertandDeleteAlertmanage usage and wallet balance alerts. See Billing.VerifyWebhookandWebhookHandlercheck theX-Nozle-Signatureof the webhooks Nozle sends. See Receive Nozle webhooks.Track,CurrentUsageandPastUsagewithout a subscription ID look up the customer’s active subscription once and remember it, as the Node.js and Python SDKs do.- Fixed: requests leave out empty optional fields instead of sending
""ornull.ChangeEntitySubscriptionPlansendsBillingTimewhen set.TrackUsagereuses the timestamp it filled in when the same idempotency key is sent again on the same client. - Breaking: removed struct fields the API never sent:
PingResult.OrgID,KeyType,EnvandVersion, andCanResult.CostPerUseCents,RevenuePerUseCents,MarginPerUseCentsandMinMarginPercent(useCanResult.Economics). - Install with
go get github.com/nozle-dev/nozle-go@v0.12.0.
React themes
October 17, 2026@nozle-js/react0.11.0addsappearanceonBillingProviderand every component, with predefined themes from@nozle-js/react/themes:light,dark,minimal,neobrutal,nozleandnozleDark, and every colour adjustable.PricingTableaddshighlightStyle(outlineorfilled) andhighlightLabel. See Appearance.- Components render without Tailwind.
PricingTablemarks contact-sales plans fromcontactSalesPlansinstead of their names. Upgrade notes are on the Appearance page.
Error statuses and checkout fixes
October 17, 2026- Breaking: a request that the resource’s current state refuses now returns
422instead of405, with the samecode(for examplenot_voidableorplan_transition_policy_required). A conflict with another operation in progress returns409. The SDKs branch oncode, so their behavior is unchanged. See Errors. - Bad bodies and unreachable dependencies return JSON errors with a
codeinstead of500:400 bad_request,502 upstream_unavailable. - Checkout charges only through the connection assigned to the customer, for single and bulk Entity checkout, and returns
422 payment_provider_requiredotherwise. Customer create keepspayment_providerandpayment_provider_codewithoutsync_with_provider. - Checking out the same plan again reopens an abandoned new-subscription checkout; a different plan replaces it and returns the new checkout.
409 subscription_checkout_in_progress(entity_subscription_checkout_in_progressfor an Entity) remains only while the provider is still processing a payment for the old checkout. - Stripe: a reused invoice checkout key returns
409 idempotency_key_reused; a rejected webhook URL sendspayment_provider.error;payment_method.detachedclears the stored default. Razorpay credentials are checked when you connect.
Usage, credits and checkout fixes
October 17, 2026- The LLM proxy finds the subscription to bill before it calls the provider, and its usage event carries that
external_subscription_id, so proxy usage is billed. A customer with several active subscriptions needs the newX-Nozle-Subscriptionheader, which is not forwarded. A customer with no matching active subscription returns422 active_subscription_not_found, several without the header422 active_subscription_ambiguous; the provider is not called. POST /eventsand/events/batchacceptexternal_customer_idwithoutexternal_subscription_id: the event is billed to the customer’s single active subscription. No or several active subscriptions return422 active_subscription_not_foundor422 active_subscription_ambiguous(in a batch, under the event’s position). An event with neither id returns422 validation_errorswithexternal_subscription_id: ["value_is_mandatory"]. See Events.can()estimates revenue for the units of the call: 1 for a count Feature, the Feature’sfield_namevalue inmetadatafor a sum Feature. Other aggregations, or a sum call without that value, report economicsunavailable, and the margin policy’son_unavailabledecides. See economics.- The deprecated Check & Deduct moves the wallet’s money balance with the credits:
balance_cents, the ongoing balance and the consumed amount change by credits × the wallet rate, and the wallet transaction amount is that money amount. - Paid credit top-ups grant their credits when the top-up invoice is fully paid, by any route: a card or provider payment, a manual payment for the full amount, a payment request, or marking the invoice paid. A partial manual payment grants nothing until the invoice is fully paid. See Paid Credit Top-ups.
- An unpaid plan or single Entity checkout expires after 23 hours, like an Entity checkout batch: the subscription is canceled with
cancelation_reason: timeout(subscription.canceledwebhook), the payment-gated invoice is closed, and the Stripe Checkout Session or Razorpay order expires. The coupons, credit-note credits and wallet credits the invoice used are returned when the checkout expires or its payment fails. See Unpaid checkout expiry. - Stripe invoice checkout and invoice payment URLs refuse an invoice that is paid, voided, draft, closed, failed or has nothing due with
invalid_invoice_status_or_payment_status, as Razorpay already did. - A paid upgrade checkout returns
409 subscription_change_pendingwhile the subscription has a scheduled cancellation or plan change. Cancelling at period end, scheduling a plan change or applying an immediate downgrade cancels an open upgrade checkout and expires its Stripe Checkout Session or Razorpay order.
Link existing Stripe customers from the SDKs
October 14, 2026- Customer upsert accepts a billing configuration, so a customer can be created and linked to an existing Stripe customer (
cus_…) in one call, without a separate REST request. Nozle stores the link and creates nothing in Stripe; repeating the upsert is safe. @nozle-js/node0.12.0:customers.upsert({ billingConfiguration }).nozle-sdk0.12.0:customers.upsert(..., billing_configuration=...).github.com/nozle-dev/nozle-gov0.11.0:Customer.BillingConfiguration.- Upserts without it send the same request as before. See Customers and Entities and Assign the connection to customers.
- Install with
npm install @nozle-js/node@0.12.0,pip install nozle-sdk==0.12.0orgo get github.com/nozle-dev/nozle-go@v0.11.0.
Nozle Agent Kit
October 13, 2026- Released the Nozle Agent Kit, skills and guard hooks that let Claude Code, Codex CLI, and OpenCode integrate Nozle billing into your application. The agent reads your account through a read-only OAuth connection and edits only the files you approve.
- Agent Kit 1.0.3: the agent installs the packages the approved scope lists, such as
@nozle-js/node, with your project’s package manager, after you approve the command. - See Install and update and Run an integration.
Go event ingestion through Engine
October 13, 2026- Node
0.11.0, Python0.11.0, and Gov0.10.0send Feature Events tohttps://api.nozle.app/engine/api/v1/events. Go batches use/engine/api/v1/events/batch. - Configure the Engine base URL for custom event ingestion. Core URL settings continue to control billing resources and subscription discovery. Event payloads, secret-key authentication, and transaction IDs are unchanged.
- Updated the Events API, SDK setup/tracking guides, and OpenAPI event creation operations to use Engine.
Razorpay and Stripe guides, new SDK releases, API fixes
October 13, 2026- Added a Razorpay integration guide and expanded the Stripe integration guide to the same depth: connection setup, webhooks, checkout and retry behavior, refunds, errors and testing.
- Added the public plan catalog reference.
- Released
@nozle-js/node0.10.0 on npm andnozle-sdk0.10.0 on PyPI. Both add typed API errors (NozleApiErrorandcodein Node,NozleAPIError.codeandhas_code()in Python), richer checkout result types, and Stripe and Razorpay README sections.check-and-deductno longer needsfeature. - Released
@nozle-js/react0.10.2 with the same checkout result types and a Stripe and Razorpay README section. - Released
github.com/nozle-dev/nozle-gov0.9.1 withAPIError.Code()andHasCode(), richerCheckoutResultfields, and a Stripe and Razorpay README section.ConsumeandLLMare removed, because their routes do not exist on the hosted service. - Node.js 0.10.0 and Python 0.10.0 clear a customer’s cached subscription after their own
subscribe,checkout, cancel and plan-change calls, sotrack()no longer keeps using a stale subscription.pending_subscription_idis removed from the Node.js, Python and React scheduled checkout result types (the pending subscription issubscription_id). React 0.10.2PricingTableshowsPlans could not be loaded: <reason>when its catalog request fails. Go v0.9.1 removesURL,PublishableKey,StripeAccountandPendingSubscriptionIDfromCheckoutResult(checkout never returned them). - Breaking: Node 0.10.0, Python 0.10.0 and Go v0.9.1 read
nozle_idfor credit systems. Ship them together with the server release that sendsnozle_id; against an older server the credit system ID is empty or the call fails. POST /subscribereturns404 customer_not_foundfor an unknown customer instead of creating an empty one. See Subscribe.- Margin and analytics date ranges accept
YYYY-MM-DDor RFC 3339, plusfrom_dateandto_date. A plain-datetoincludes the whole day, and an invalid or reversed range returns400 invalid_date_range. - Corrected the documentation for entitlement
reasonvalues, the required usagetimestamp, credit balance decimals, the credit operationslimitrange, the margin simulate request, unknown cost meters and trend granularity. - Install with
npm install @nozle-js/node@0.10.0 @nozle-js/react@0.10.2,pip install nozle-sdk==0.10.0orgo get github.com/nozle-dev/nozle-go@v0.9.1.
React SDK 0.10.1
- Released
@nozle-js/react0.10.1. - Fixed
usePlanserror handling for failed catalog requests, stale results and superseded responses. Upgrade withnpm install @nozle-js/react@0.10.1.
Production integration guidance
- Completed the quickstart prerequisites and aligned tracking and entitlement Feature codes.
- Clarified asynchronous processing and initial credit grants, unavailable or gated features, and retry behavior. See the production integration checklist.
- Compile TypeScript examples against the published SDK packages instead of hand-maintained substitute declarations.
Server SDK 0.9.1
- Released
@nozle-js/node0.9.1 on npm andnozle-sdk0.9.1 on PyPI. - Fixed RFC 3339 Feature Event timestamp serialization to Unix seconds in both SDKs, including OpenAI and Anthropic wrapper events. Numeric timestamps remain supported; malformed timestamps fail before delivery.
- Install with
npm install @nozle-js/node@0.9.1orpip install nozle-sdk==0.9.1. React was at0.10.0at that release; use the0.10.1patch above. Go remains atv0.9.0.
Go SDK 0.9.0
- Released
github.com/nozle-dev/nozle-gov0.9.0 with typed billing, subscription, Entity, credit, usage, Cost Event, entitlement, and margin workflows. - Added automatic OpenAI and Anthropic usage capture for completed calls and streams through wrapped provider HTTP clients, plus explicit capture for custom delivery flows.
- Published the Apache-2.0 licensed module through an immutable Go tag, with test, race, vet, and example checks in the release workflow.
Go SDK documentation and API reference
- Added Go SDK guides for installation, billing and subscriptions, tracking events, product credits, customers and Entities, entitlements, margin queries, errors, and OpenAI/Anthropic usage capture.
- Added Go to SDK navigation and the existing quickstart, billing, credits, entitlement, margin, and React backend guidance.
- Corrected Core API references for customer creation, Entity subscription checkout, and billing-state import; clarified the customer envelope and Unix-second Feature Event timestamps.
- Added automatic Go OpenAI and Anthropic usage capture for completed calls and streams through a wrapped provider HTTP client. Manual capture remains available for queued delivery and custom provider clients.
September 2026
Server SDK 0.9.0 and React SDK 0.10.0
- Released
@nozle-js/node0.9.0 andnozle-sdk0.9.0 with selected-subscription options, signed plan-change quotes, pending-change withdrawal, and scoped checkout recovery for merchant backends. - Released
@nozle-js/react0.10.0 with billing portal and self-service controls that use those backend flows. - Node.js and Python are published through npm and PyPI trusted publishing. The package versions and their release tags are separate from the React package version.
Cost Intelligence foundation
- Added versioned Cost Sheets, Cost Event Meters, and historical Feature cost-composition modes.
- Added exact-decimal Feature Event and Detailed Cost Event rating with durable PostgreSQL ledger entries and rebuildable ClickHouse projections.
- Replaced legacy whole-cent
/canmargin fields with a side-effect-freeeconomicsestimate that identifies rule versions and unknown future costs. - Added effective-dated provider price catalogues, cached-input/cache-write/reasoning token categories, and linked Cost Event capture in the Node.js and Python OpenAI and Anthropic wrappers.
- Added recurring Shared Cost Pool generation, comma-separated value import, allocation previews, immutable allocation runs, and equal inclusion of eligible free and paid customers.
- Added ledger-backed Feature, customer, Cost Event, Shared Cost, and Uncosted reporting with finalized billing revenue kept separate from estimated event revenue.
- Added guarded replay tools for uncosted sources and failed ClickHouse projections, plus PostgreSQL-backed
/cansnapshots with disposable Redis caching.
August 2026
Updated through August 8, 2026.Tenant-safe customer provisioning
- Routed Node.js and Python
customers.upsert()calls directly to Nozle Core using the merchant’s secret key. - Removed master-organization authentication from the Engine customer compatibility endpoint.
- Added local SDK validation and tenant-isolation regressions for customer provisioning.
- Verified Node.js and Python customer creation against the Pullse Testing production organization with disposable canaries.
Mixed Entity checkout and billing anchors
- Added one-invoice, one-payment checkout for mixed Entity plan baskets of up to 100 Entities.
- Added a stable customer-level Entity billing anchor established only after the first successful paid checkout.
- Added anniversary-aligned proration for Entity plans purchased after the anchor is established.
- Added replay-safe checkout batches and fail-closed protection for concurrent first-paid checkouts.
- Clarified that paid top-ups enter the customer pool and are allocated explicitly to Entities.
Entity-owned subscriptions and SDK 0.5.0
- Added independent subscriptions for customer Entities, including mixed monthly and annual plans under one paying customer.
- Added Entity-scoped checkout, plan changes, end-of-period cancellation, stable subscription identities, and payment-gated activation.
- Added suspended, deleted, and recreated Entity protection so stale identities cannot inherit billing state.
- Released the backend integration surface in
@nozle-js/node0.5.0 andnozle-sdk0.5.0. - Verified the Core API and published Python SDK against production with reversible Entity-subscription canaries.
Subscription settlement controls
- Added preview and apply APIs for cancellation, downgrade, and uncancel transitions.
- Added merchant-controlled timing, billing-anchor, proration, credit, refund, offset, and final-invoice policies.
- Added idempotent transition application so uncertain requests can be retried safely.
- Released the settlement controls in
@nozle-js/node0.4.2 andnozle-sdk0.4.2.
Developer experience
- Completed the React, Node.js, and Python SDK references with current signatures and security guidance.
- Added rendered React component previews and a dedicated theming reference.
- Replaced customer-specific examples with neutral, reusable integration examples.
- Restored the complete Nozle Billing API reference with generated request, response, and schema documentation.
July 2026
Product credits
- Introduced exact-decimal credit systems, plan grants, paid top-ups, immutable balance sources, and operation history.
- Added advisory usage checks and atomic, idempotent credit consumption.
- Added durable usage-event publication and reconciliation so committed deductions survive downstream outages.
- Added customer and Entity balance APIs, per-Entity grants, shared-pool policies, and top-up allocation/deallocation.
Payment-first billing
- Paid plan changes now preserve the current plan until payment succeeds.
- Added payment-aware checkout results for hosted Stripe, embedded Stripe, immediate completion, and scheduled changes.
- Added durable upgrade webhook processing and support for end-of-period cancellation.
- Added merchant-configurable billing anchors and transition-policy defaults.
Security and tenancy
- Restricted publishable keys to the public plan catalog.
- Moved customer billing operations behind authenticated merchant backends and least-privilege secret keys.
- Hardened customer, organization, mutation, and internal service authorization.
- Removed automatic seat billing from Entity lifecycle changes; merchants now emit explicit, idempotent seat events.
SDKs and dashboard
- Added product-credit and Entity APIs to the Node.js and Python SDKs.
- Refactored React checkout around merchant-owned callbacks and forwarded validated return URLs to Stripe.
- Added customer and Entity credit dashboards, paid top-up checkout, and refreshed analytics and settings interfaces.
June 2026
Entitlement rework
- Added two-path entitlement resolution for feature gates and usage limits.
- Added margin-aware decision fields:
cost_per_use_cents,revenue_per_use_cents, andmargin_per_use_cents.
Checkout flow
- Introduced invoice-first embedded Stripe checkout.
- Made plan activation payment-gated.
- Added one-off invoice checkout for credit top-ups and add-ons.
SDK updates
- Released initial LLM usage capture for OpenAI and Anthropic in the Node.js and Python SDKs.