Skip to main content

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’s hmac endpoint is accepted; an unsigned, forged or cross-organization request, or one whose organization is unknown, gets 401 in every environment, and the Engine answers 503 if the key cannot be read so that Core retries. Engine webhook endpoints must use the hmac signature algorithm: jwt endpoints 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_SECRET setting 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_review for 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.terminated and subscription.started webhooks 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.error webhook is sent. Renaming a Stripe connection code registers the endpoint if it was missing, reports a missing webhook permission as payment_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 createOrUpdatePlanConfig answers not_found for 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 /can does 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 /can accepts optional subscription_id and entity_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 answers 200 with allowed: false and reason: subscription_required, and POST /billing/upgrade answers 409 subscription_required. Before, both used the most recently started subscription. A customer with one current subscription sees no change. Send subscription_id or entity_id for 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. /can reports the real used of a metered Feature that is only priced by a charge, with limit and remaining null. Before it was 0.
  • /can usage 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/check and POST /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.333333333334 for 1 event at 1 credit per 3). Before, it answered 422 credit_usage_configuration_invalid. A boolean or config Feature answers 422 feature_not_consumable instead of 500 (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_backlog now 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/overview returns 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 to nozle_eu_* in tax_codes and GET, PUT and DELETE /taxes/{code}; and CSV exports repeat the id columns at the end under their old names. The nozle_* 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}/entitlements and /subscriptions/{external_id}/entitlements) changes only the metered settings it sends. {"hard_limit": false} keeps the usage limit, and an omitted min_margin_percent, margin_enforcement_mode or enforce_plan_margin is 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. POST still replaces the whole entitlement. Restoring a removed feature or dropping an override now reaches /can within its usual refresh (3.5.1).
  • Onboarding’s launch check: GraphQL Event.matchCustomer and Event.matchSubscription now 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_invoice while 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). cost and finalizedMargin can be null, and the new costStatus is loaded or not_loaded (3.6.0). See Finalized revenue.
  • An immediate upgrade with proration_behavior: none that 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 422 and usage_thresholds: [feature_not_available] on a plan without progressive billing, and lifetime usage answers 403 feature_not_available without 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 a checkout_default_return_url, through PUT /organizations and GraphQL updateOrganization (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-purchases checks 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 its credit_top_up_purchase.created activity 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/overview returns mrr_total_default_cents, arr_total_default_cents and fx_date, and GET /analytics/invoices-summary returns outstanding_total_default_cents, overdue_total_default_cents and fx_date: the amounts of every currency converted into currency, the organization’s default currency. fx_date is 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_percent and plan_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 nozleAnalyticsOverview adds mrrTotalDefaultCents, arrTotalDefaultCents and fxDate, and nozleAnalyticsInvoicesSummary adds outstandingTotalDefaultCents, overdueTotalDefaultCents and fxDate: 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, REST GET /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 as null, and a log without device info or resources returns {}.
  • Revenue analytics, analytics dashboards and forecasted usage remain unavailable. Their GraphQL queries and GET /analytics/usage answer analytics_unavailable in 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 curl carries it. Before, it copied the masked key and the request failed with 401. 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 is onboarding- 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 /customers needs customer:write, POST /check-and-deduct credit_system:write, GET /auth/centrifugo-token customer_usage:read, POST /cost-events event:write, cost models and Cost Intelligence analytic:read or analytic:write, and /analytics/*, /margin/* and POST /margin/simulate analytic:read. A key without it gets 403 permission_denied. Organizations without API key permissions see no change. See Engine routes.
  • POST /analytics/snapshot and POST /onboarding/chat are internal to Nozle and accept only its internal service token. Secret keys get 403.
  • The publishable-key plan catalog, GET /plans and GET /plans/{code}, answers CORS from any origin with Access-Control-Allow-Origin: * and no credentials, so PricingTable and usePlans load plans on your own site. Every other route keeps the origin allow-list. See the public plan catalog.
  • GET /analytics/overview returns currency and mrr_by_currency (currency, mrr_cents, arr_cents per plan currency). GET /analytics/invoices-summary returns currency and by_currency (currency, outstanding_cents, overdue_cents per invoice currency). mrr_cents, arr_cents, outstanding_cents and overdue_cents are in currency: 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 answer 503 analytics_unavailable, instead of zero revenue or 500 internal_error. A missing analytics schema still answers 503 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 nozleAnalyticsOverview adds currency and mrrByCurrency (currency, mrrCents, arrCents), and nozleAnalyticsInvoicesSummary adds currency and byCurrency (currency, outstandingCents, overdueCents), from Engine 1.4.0. When analytics cannot be computed, these queries answer a GraphQL error with the code analytics_unavailable and status: 503 instead 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 of 404, and every plan, listed or read by code, carries all its entitlements and charges, including those of hidden features. Plans pending deletion still answer 404 to 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 answers plan_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: false shows it again. Invoice, credit note and payment receipt PDFs now always show it. GraphQL CurrentOrganization.canHideBranding says whether your plan lets you hide it. See Powered by Nozle.
  • Approving a one-off quote version (GraphQL approveQuoteVersion) no longer needs totalAmountCents in each add-on item. Nozle computes it as round(unitAmountCents × units), also in overrides that change the units or the unit amount, and replaces any total the client sends.
  • Breaking: the GraphQL mutations createRole, updateRole and destroyRole and their input types are removed. Custom roles are no longer part of the product. The built-in roles are admin, finance and manager, and the roles query lists them.
  • Revenue analytics, analytics dashboards and forecasted usage are not available. GET /analytics/usage answers 503 analytics_unavailable.

Node.js SDK 0.13.1

October 21, 2026
  • @nozle-js/node 0.13.1: Behaviour change: wrapOpenAI and wrapAnthropic return 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, 2026
  • nozle-sdk 0.13.1: Behaviour change: wrap_openai and wrap_anthropic return 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, isinstance checks 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/check and /usage/track accept an optional subscription_id, the external id of the active subscription that pays. With entity_id, the Entity’s own active subscription pays, else the customer’s own; customers with one subscription per Entity no longer get 422 active_subscription_ambiguous on 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 names subscription_id and entity_id. Event ingestion and the LLM proxy choose subscriptions as before.
  • With API key permissions, /usage/check needs credit_system:read and /usage/track needs credit_system:write; a key without it gets 403 permission_denied. Before, any secret key could spend credits. See Key permissions.
  • /can gives 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 with no_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 revoke operations with the reason top_up_credit_note or top_up_dispute_lost. Credit operations add requested_credit_amount on revoke. See Refunds and lost disputes.
  • The Entity credit balance reads pool_policy and effective_available from the subscription that pays for that Entity’s usage.
  • The /admin/* routes accept only Nozle’s internal service token. Organization secret and publishable keys get 403.
  • Reliability: an event accepted by POST /events is 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, and GET /plans/{code} answered 404 plan_not_found. Send show_on_pricing: false (GraphQL showOnPricing: false) to create it hidden. Existing families keep their visibility.
  • Usage limits stay per plan inside a plan family. Entitlement writes set usage_limit and hard_limit on the plan in the path only; features and privileges are still shared by the family. GraphQL updatePlanFamilyEntitlements accepts planId.
  • Stripe invoice checkout keeps one payable Checkout Session per invoice: calling it again returns the open session, and a payment in progress answers 422 with payment_already_processing. A second successful payment for an invoice that is already paid is refunded in full, and you get the invoice.payment_failure webhook with duplicate_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_up on recurring rules, as documented. Before, it was dropped, and a rule meant to grant free credits created a paid top-up invoice. true on a rule that is not method: target returns 422 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 own plan_transition_policy permission. 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/react 0.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: component appearance over BillingProvider appearance over 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 BillingProvider code 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 the appearance you 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, 2026
  • GET /api/v1/plans returns meta.sdk_appearance, the appearance saved for the organization ({} when none), for publishable and secret keys. It can hold the global settings and, under components, the settings of single SDK components, plus hideBranding. 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 custom fetch, including the Vercel AI SDK, LangChain and Gemini. On Python and Go, it captures through the provider’s HTTP client. It serves billing screens through createBillingHandler() and the React billing hooks, verifies webhooks with the SDK helpers, and reads errors by NozleApiError status and code.
  • It also follows the current API: plan families, change_at and pay-first plan changes, 422 for an event that matches no active subscription or several, and null limits from can().
  • 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 --write command again in each app, because the hook path contains the version.

Node.js SDK 0.13.0

October 17, 2026
  • @nozle-js/node 0.13.0: new Nozle() reads NOZLE_SECRET_KEY when you pass no apiKey. The host option (default https://api.nozle.app) fills in baseUrl and eventsUrl. Opt-in retries with maxRetries and retryDelayMs repeat only requests that are safe to repeat. See Installation.
  • Every call that gets a non-2xx response throws NozleApiError, which now carries requestId and retryAfter. The message keeps its <operation> failed: <status> <statusText> form and the class still extends Error. See Errors and retries.
  • captureFetch() returns a fetch that records the token usage of OpenAI-compatible, Anthropic and Gemini responses, for any client that accepts a custom fetch. recordUsage() records usage your code read itself. Capture reports feature_not_found once per event code through onError when no Feature has that code. See LLM auto-capture.
  • getSubscriptions(), currentUsage() and pastUsage() read Core subscriptions and usage. The invoices namespace lists invoices (with paymentOverdue and other filters), reads one and returns its PDF URL. The alerts namespace manages usage and wallet balance alerts. See Billing.
  • webhooks.verify() and createWebhookHandler() check the X-Nozle-Signature of 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: wrapOpenAI and wrapAnthropic keep the SDK’s own APIPromise and Stream, so withResponse(), asResponse(), chat.completions.parse(), messages.stream() / finalMessage(), stream.controller and toReadableStream() work on a wrapped client. Usage is recorded once, when the response is read (not for asResponse()); a stream records when it is fully iterated. The optional peer dependency is @anthropic-ai/sdk. checkAndDeduct() is deprecated: use usage.check() and usage.track() with a credit system. See LLM auto-capture.
  • Usage events recorded by wrapOpenAI, wrapAnthropic and captureFetch use 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 with 409 idempotency_key_reused.
  • Breaking: CanResult.limit and CanResult.remaining are typed number | null, null when the feature has no limit. Code that checked === undefined should check == null. PingResult.version and SubscriptionOptions.blocked_reason are 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/react 0.11.0 adds customer billing hooks built on TanStack Query: useSubscription, useEntitlement, useCreditBalance, useCreditHistory, useUsage, useUpgradePreview, useBillingRefresh, useInvoices and useInvoiceDownload. They read your backend route set as BillingProvider billingEndpoint (served by createBillingHandler from @nozle-js/node 0.13.0), so the browser never holds a secret key. See Provider and hooks.
  • New components: CurrentPlan, CreditBalance, CreditHistory, UsageBreakdown, UsageTrend and PoweredByNozle.
  • PricingTable, PlanCard and PlanComparison show what each plan gives from the public catalog (entitlements, credit grants and usage prices) and sort plans by price, cheapest first. planFeatures(), comparisonRows() and sortPlansByPrice() return the same data for your own layout.
  • Appearance themes and variables; see React themes below.
  • Fixed: PricingTable shows the real billing interval instead of /month for every plan that is not yearly, PlanCard prints the plan’s own currency, and the annual toggle no longer shows a hard-coded “Save 20%”. Component buttons are type="button", so they no longer submit a surrounding form.
  • Breaking: @tanstack/react-query 5 or later is a required peer dependency.
  • Breaking: the customer hooks need billingEndpoint on BillingProvider and a backend route that serves them.
  • Breaking: PlanCard takes a catalog plan instead of id, name, monthlyPrice, annualPrice, description, isAnnual and children, and the Plan type export is removed. PlanComparison takes catalog plans, and its features rows are keyed by plan code.
  • Breaking: components no longer read Tailwind or shadcn variables, and PricingTable marks contact-sales plans from contactSalesPlans instead 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, 2026
  • nozle-sdk 0.13.0 adds AsyncNozle for asyncio apps, with the same arguments, namespaces and methods as Nozle, awaited. See Installation.
  • Nozle() reads NOZLE_SECRET_KEY when you pass no api_key. The host argument (default https://api.nozle.app) fills in base_url and events_url. Opt-in retries with max_retries and retry_delay repeat only requests that are safe to repeat. NozleAPIError adds request_id and retry_after.
  • wrap_http_client(), capture_http_client() and capture_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() and past_usage() read Core usage. invoices.list() (with payment_overdue and other filters), invoices.get() and invoices.download_url() read invoices, and the alerts namespace manages usage and wallet balance alerts. See Billing.
  • webhooks.verify() checks the X-Nozle-Signature of the webhooks Nozle sends. See Receive Nozle webhooks.
  • entity_subscriptions.change_plan() accepts billing_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.version and SubscriptionOptions.blocked_reason are 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, 2026
  • github.com/nozle-dev/nozle-go v0.12.0: New reads NOZLE_SECRET_KEY when the key argument is blank. WithHost (default https://api.nozle.app) fills in the Engine and Core URLs. Opt-in retries with WithMaxRetries and WithRetryDelay repeat only calls that are safe to repeat. APIError adds RequestID and RetryAfter. See Installation.
  • WrapHTTPClient records the token usage of any LLM SDK that takes an *http.Client, and RecordUsage records usage your code read itself. See LLM usage capture.
  • CurrentUsage and PastUsage read Core usage. ListInvoices (with PaymentOverdue and other filters), GetInvoice and InvoiceDownloadURL read invoices, and ListAlerts, GetAlert, CreateAlert, UpdateAlert and DeleteAlert manage usage and wallet balance alerts. See Billing.
  • VerifyWebhook and WebhookHandler check the X-Nozle-Signature of the webhooks Nozle sends. See Receive Nozle webhooks.
  • Track, CurrentUsage and PastUsage without 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 "" or null. ChangeEntitySubscriptionPlan sends BillingTime when set. TrackUsage reuses 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, Env and Version, and CanResult.CostPerUseCents, RevenuePerUseCents, MarginPerUseCents and MinMarginPercent (use CanResult.Economics).
  • Install with go get github.com/nozle-dev/nozle-go@v0.12.0.

React themes

October 17, 2026
  • @nozle-js/react 0.11.0 adds appearance on BillingProvider and every component, with predefined themes from @nozle-js/react/themes: light, dark, minimal, neobrutal, nozle and nozleDark, and every colour adjustable. PricingTable adds highlightStyle (outline or filled) and highlightLabel. See Appearance.
  • Components render without Tailwind. PricingTable marks contact-sales plans from contactSalesPlans instead 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 422 instead of 405, with the same code (for example not_voidable or plan_transition_policy_required). A conflict with another operation in progress returns 409. The SDKs branch on code, so their behavior is unchanged. See Errors.
  • Bad bodies and unreachable dependencies return JSON errors with a code instead of 500: 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_required otherwise. Customer create keeps payment_provider and payment_provider_code without sync_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_progress for 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 sends payment_provider.error; payment_method.detached clears 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 new X-Nozle-Subscription header, which is not forwarded. A customer with no matching active subscription returns 422 active_subscription_not_found, several without the header 422 active_subscription_ambiguous; the provider is not called.
  • POST /events and /events/batch accept external_customer_id without external_subscription_id: the event is billed to the customer’s single active subscription. No or several active subscriptions return 422 active_subscription_not_found or 422 active_subscription_ambiguous (in a batch, under the event’s position). An event with neither id returns 422 validation_errors with external_subscription_id: ["value_is_mandatory"]. See Events.
  • can() estimates revenue for the units of the call: 1 for a count Feature, the Feature’s field_name value in metadata for a sum Feature. Other aggregations, or a sum call without that value, report economics unavailable, and the margin policy’s on_unavailable decides. 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.canceled webhook), 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_pending while 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.
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/node 0.12.0: customers.upsert({ billingConfiguration }). nozle-sdk 0.12.0: customers.upsert(..., billing_configuration=...). github.com/nozle-dev/nozle-go v0.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.0 or go 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, Python 0.11.0, and Go v0.10.0 send Feature Events to https://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/node 0.10.0 on npm and nozle-sdk 0.10.0 on PyPI. Both add typed API errors (NozleApiError and code in Node, NozleAPIError.code and has_code() in Python), richer checkout result types, and Stripe and Razorpay README sections. check-and-deduct no longer needs feature.
  • Released @nozle-js/react 0.10.2 with the same checkout result types and a Stripe and Razorpay README section.
  • Released github.com/nozle-dev/nozle-go v0.9.1 with APIError.Code() and HasCode(), richer CheckoutResult fields, and a Stripe and Razorpay README section. Consume and LLM are 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, so track() no longer keeps using a stale subscription. pending_subscription_id is removed from the Node.js, Python and React scheduled checkout result types (the pending subscription is subscription_id). React 0.10.2 PricingTable shows Plans could not be loaded: <reason> when its catalog request fails. Go v0.9.1 removes URL, PublishableKey, StripeAccount and PendingSubscriptionID from CheckoutResult (checkout never returned them).
  • Breaking: Node 0.10.0, Python 0.10.0 and Go v0.9.1 read nozle_id for credit systems. Ship them together with the server release that sends nozle_id; against an older server the credit system ID is empty or the call fails.
  • POST /subscribe returns 404 customer_not_found for an unknown customer instead of creating an empty one. See Subscribe.
  • Margin and analytics date ranges accept YYYY-MM-DD or RFC 3339, plus from_date and to_date. A plain-date to includes the whole day, and an invalid or reversed range returns 400 invalid_date_range.
  • Corrected the documentation for entitlement reason values, the required usage timestamp, credit balance decimals, the credit operations limit range, 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.0 or go get github.com/nozle-dev/nozle-go@v0.9.1.

React SDK 0.10.1

  • Released @nozle-js/react 0.10.1.
  • Fixed usePlans error handling for failed catalog requests, stale results and superseded responses. Upgrade with npm 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/node 0.9.1 on npm and nozle-sdk 0.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.1 or pip install nozle-sdk==0.9.1. React was at 0.10.0 at that release; use the 0.10.1 patch above. Go remains at v0.9.0.

Go SDK 0.9.0

  • Released github.com/nozle-dev/nozle-go v0.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/node 0.9.0 and nozle-sdk 0.9.0 with selected-subscription options, signed plan-change quotes, pending-change withdrawal, and scoped checkout recovery for merchant backends.
  • Released @nozle-js/react 0.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 /can margin fields with a side-effect-free economics estimate 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 /can snapshots 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/node 0.5.0 and nozle-sdk 0.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/node 0.4.2 and nozle-sdk 0.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, and margin_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.