August 20, 2026
New Features
Organization-level proration defaults
GET /organizations/settings/ and PATCH /organizations/settings/ now expose two settings for controlling how subscription changes are prorated:Both settings accept
IMMEDIATE_CHARGE, PRORATE_NEXT_INVOICE, or NO_PRORATION.Organization checkout customization
Checkout branding and appearance can now be stored as organization defaults. UseGET /organizations/checkout-settings/ to retrieve the settings and PATCH /organizations/checkout-settings/ to update the brand name, light and dark logos, favicon, background image, and checkout customization object.The hosted checkout session response now includes these settings so the organization’s branding can be applied consistently across checkout sessions.Migrate individual subscriptions
POST /subscriptions/{subscriptionId}/migrate/ migrates an existing subscription to the latest version of its current plan. Set at least one of updateFeatures or updatePricing to true:Changes
Identify custom-priced subscriptions
GET /subscriptions/ and GET /subscriptions/{subscriptionId}/ now include isCustomPricing. It is true when the subscription uses a custom price instead of the plan’s configured price, and false otherwise.August 14, 2026
New Features
Control how subscription updates are billed
POST /subscriptions/{subscriptionId}/update/ and its /preview/ counterpart now accept prorationBehavior, which controls when the customer is billed for a mid-period change:If omitted, your organization’s existing default is used, so existing integrations are unaffected.
400 naming the accepted values, instead of a generic error.Improvements
amountChargedImmediately on the update preview endpoint is now correct for billing-interval changes. It previously reported 0 for a MONTHLY to YEARLY change unless prorationBehavior was IMMEDIATE_CHARGE, even though the customer was charged right away.Deprecations
The undocumentedprobation_behaviour request field is deprecated in favour of prorationBehavior (probation was a typo for proration). It is still accepted and continues to work unchanged.August 12, 2026
New Features
Preview subscription updates
UsePOST /subscriptions/{subscriptionId}/update/preview/ to see the financial effect of a plan, billing-period, or feature change before applying it. Send the same planIdentifier, chargePeriod, and features payload used to update a subscription.The response includes the new recurring amount, any amount that would be charged immediately, and the previewed next invoice with its line items. Amounts are returned in both major currency units and integer minor units. The preview does not update the subscription, create an invoice, or charge the customer.Custom amounts for one-time charges
POST /charges/ now accepts customAmount to override a plan’s configured one-time price. Pass the amount in the currency’s major unit and include currencyCode. You can also set taxBehavior to INCLUSIVE or EXCLUSIVE; it defaults to EXCLUSIVE.August 10, 2026
New Features
Trial ending webhook
You can now subscribe tosubscription.trial_will_end. Kelviq sends this a few days before a subscription’s trial ends, mirroring Stripe’s own customer.subscription.trial_will_end timing. It’s skipped if the subscription has already converted to active or has no trial days left by the time the notice would go out. data.object uses the same subscription payload shape as subscription.created and subscription.updated.August 10, 2026
New Features
Invoices API
You can now list and retrieve invoices directly, rather than only receiving them through webhooks:GET /invoices/— a paginated list of invoices for your organization, filterable bysubscription_idandcustomer_id.GET /invoices/{invoiceId}/— a single invoice by its Kelviq invoice ID.
attemptCount— number of payment attempts made against the invoice.nextPaymentAttempt— when Stripe will next retry collection, if a retry is scheduled.failureDetails—code,message, andpaymentMethodTypefor the most recent failed payment attempt.nullonce the invoice is paid.
Filter subscriptions by modification date
GET /subscriptions/ now accepts modified_on_after / modified_on_before query parameters, for filtering by when the subscription was last modified.Subscription timestamps
GET /subscriptions/ and GET /subscriptions/{subscriptionId}/ now return createdOn and modifiedOn on the subscription object.August 5, 2026
New Features
Payment links in invoice webhooks
The invoice object sent byinvoice.created, invoice.paid, and invoice.payment_failed now includes payment_link. This URL takes the customer directly to the invoice payment page, so integrations can surface payment recovery without constructing the link themselves.payment_link is present when the invoice is open or payment has failed. If the invoice is already paid when it is created, payment_link is null because no payment action is required.Example:Changes
Portal sessions require a customer email
POST /portal/session/ now returns 400 Bad Request when the selected customer does not have an email address. Portal session tokens are tied to the customer’s email, so add an email to the customer before creating a session.August 1, 2026
New Features
Subscription cancellation details
GET /subscriptions/ and GET /subscriptions/{subscriptionId}/ now return cancellation metadata:canceledAt— when the cancellation was recorded.cancellationReason— whether it was initiated by the customer, merchant, or provider.cancellationFeedback— structured feedback such asTOO_EXPENSIVE,MISSING_FEATURES, orUNUSED.cancellationComment— an optional free-form comment.
POST /subscriptions/{subscriptionId}/cancel/ now accepts the optional cancellationFeedback and cancellationComment fields. The cancellation endpoint records the merchant as the initiator; cancellations submitted through the customer portal record the customer as the initiator.Failed invoice webhook
You can now subscribe toinvoice.payment_failed. Kelviq sends this event when a subscription invoice payment fails or requires customer action. Its data.object uses the same invoice payload shape as invoice.created and invoice.paid.Refund webhook context
Therefund.created and refund.updated webhook objects now include:customer— the associated customer’s ID, name, email, customer identifier, and billing address.subscription_id— the associated subscription ID, ornullfor an order without a subscription.
Refunded order total
Order responses fromGET /orders/ and GET /orders/{id}/ now include refundedTotalUnits, the total amount refunded against the order in the sale currency’s minor units.July 29, 2026
Fixes
subscription.updated now fires when a cancellation is scheduled for period-end
Scheduling a subscription to cancel at the end of the current billing period (rather than immediately) previously sent no webhook at all — status stays active until the period actually ends, so nothing was detected as changed. This now correctly sends subscription.updated (with the new end_date and a previous_attributes.end_date of null) at the moment the cancellation is scheduled. subscription.cancelled still only fires once the subscription actually reaches cancelled status — for a period-end cancellation, that’s later, when the period ends.July 29, 2026
New Features
Checkout sessions and checkout session events
Three endpoints are now part of the public API:GET /checkout/sessions/— paginated list of checkout sessions for the authenticated organization.GET /checkout/sessions/{session_id}/— a single checkout session, including the order, subscription, and payment method it produced (if any).GET /checkout/sessions/{session_id}/events/— the session’s timeline events (session created, customer details updated, payment attempted, payment completed, etc.).
July 29, 2026
New Features
Orders, order events, and webhook delivery logs
Four endpoints are now part of the public API:GET /orders/— paginated list of orders.PENDINGorders (payment never attempted/completed) are never included. Acceptsstatus,billing_type(ONE_TIME/SUBSCRIPTION), andis_renewal(true/false) filters.GET /orders/{id}/— a single order.GET /orders/{id}/events/— the order’s timeline events (order created, order completed, order receipt sent, invoice paid, etc.). This returns events for every order tied to the same underlying subscription as{id}, not just that single order record.GET /webhook/logs/— one row per webhook delivery attempt, including retries.
GET /webhook/logs/ also accepts start_date/end_date query params. Results are always limited to the trailing 30 days — these params can narrow that window but can’t widen it beyond 30 days back. They filter against lastAttempt (when that specific delivery attempt happened), not createdOn (when the underlying event was first created) — the two can differ for retried deliveries.July 29, 2026
New Features
Filter subscriptions by status
GET /subscriptions/ now accepts a status query parameter. Pass a comma-separated list to match any of several statuses, e.g. ?status=active,trialing.status) call:- Without
status: exactly one row per subscription — its most recent state, with expired (end_datein the past) and superseded records excluded. - With
status: that deduplication and exclusion is skipped, and matching records are returned directly. A subscription that has passed through the requested status more than once, or whose only matching record has since expired or been superseded, can appear more than once or in a state you didn’t expect.
status for point-in-time queries (“show me everything currently active”); omit it for the current, deduplicated view of each subscription.Fixes
HTTPS pagination links
Paginated list responses’next and previous links now correctly use https:// when the request was made over HTTPS. Previously they were always rendered as http://, regardless of the request’s actual scheme.July 28, 2026
Changes
Itemized Merchant of Record fees
Transaction responses fromGET /transaction/ now include morFeeBreakdown, an array that itemizes the Merchant of Record fee charged for the transaction.Each component includes its name, percentage rate, amount in minor units (valueUnits), and currency. Fixed fees return null for percentage. Transactions without an applicable Merchant of Record fee return an empty array.base_fee, fixed_fee, international_fee, subscription_fee, and conversion_fee. A fee_adjustment component (also null percentage) is included when the calculated fee is raised to match a processor-fee floor.July 17, 2026
New Features
28-day subscription billing
Checkout and subscription creation now support a four-week billing period. PassTWENTY_EIGHT_DAYS as chargePeriod when creating an eligible checkout session or subscription.This is useful for products sold in fixed four-week cycles: renewals happen on the same weekday every four weeks, and metered usage can reset on the same schedule instead of following calendar months.EVERY_28_DAYS as their usage reset period.The new billing period works across renewals, orders, invoices, emails, and subscription reporting. Organizations must enable the 28-day period before using it on a plan.Subscription end dates in webhook payloads
Subscription webhook payloads now includeend_date inside data.object. The field contains an ISO 8601 date when the subscription has a known end date and null when no end date is set.Fixes
Reliable invoice.paid webhook delivery
Kelviq now emits invoice.paid when an invoice is created with a PAID status. Previously, these invoices could emit only invoice.created, which meant integrations waiting for invoice.paid did not receive confirmation that payment had been collected.The event payload has not changed. Continue to use data.object.status, data.object.paid_at, and data.object.subscription_id when processing the event.July 17, 2026
Changes
Multiple customers can use the same email
More than one customer record can now use the same email address. This removes the previous one-customer-per-email restriction.Each record must still have a uniquecustomerId. Archiving a customer does not release that ID, so it cannot be assigned to a new record.July 16, 2026
New Features
List, Create, and Retrieve Refunds
The Refunds API now supports the complete refund workflow:GET /refunds/— List refunds: Returns a paginated list of refunds for the authenticated organization, with search, status, date-range, and pagination filters.POST /refunds/— Create a refund: Creates a full or partial refund for an order. ProvideamountUnitsoramountfor a partial refund, or omit both to refund the remaining balance.GET /refunds/{refundId}/— Retrieve a refund: Returns a refund by its Kelviq UUID.
orderId to identify the order. List results, newly created refunds, and retrieved refunds share the same response format, including the refund amount, reason, status, failure details, internal note, and associated order.July 14, 2026
New Features
Subscription List, Create, and Retrieve APIs
The Subscriptions API now includes three new endpoints for reading and creating subscriptions:GET /subscriptions/— List subscriptions: Retrieves a paginated list for a customer. Thecustomer_idquery parameter is required.POST /subscriptions/create/— Create a subscription: Creates a subscription directly for a customer without requiring a checkout session.GET /subscriptions/{subscriptionId}/— Retrieve a subscription: Retrieves a subscription by its Kelviq UUID.
files— downloadable files attached to the subscription’s plan.links— external links attached to the plan.license— issued licenses associated with the subscription.
One-Time Charges
The newPOST /charges/ endpoint immediately charges a customer’s saved payment method without creating a checkout session. The chargePeriod must be ONE_TIME.May 7, 2026
New Features
Enhanced Checkout Configuration
You can now pass additional configuration parameters when creating a checkout session via the API. These new fields allow for tighter control over the customer experience:lockEmail: When set totrue, the email address field on the checkout page is disabled, preventing customers from changing the email associated with the session.discountsEnabled: A boolean to explicitly allow or disallow discount code application on the checkout page.defaultBillingCountry: Pre-fills the billing country field (e.g.,"IN").
May 7, 2026
New Features
Custom Dynamic Amount Support
Added support for custom dynamic amounts on the checkout page. You can now pass a specificcustom_amount directly via the checkout API, which is ideal for usage-based, variable, or custom-quoted pricing models.-
custom_amount: The specific numeric amount to be charged to the customer. This overrides static plan pricing and is ideal for usage-based, variable, or custom-quoted pricing models. -
tax_behavior: Specifies how taxes should be applied to the custom amount. For example, setting it to “INCLUSIVE” means the tax is already factored into the custom_amount, while “EXCLUSIVE” would add the tax on top of the base amount. -
currency_code: The three-letter ISO currency code (e.g., “INR”, “USD”) that defines the currency in which the custom_amount should be processed.