subscription.renewed
Fires when a subscription successfully renews to its next billing cycle. The renewal charge has succeeded, currentPeriodStart / currentPeriodEnd have rolled forward, and failedPaymentCount is reset to 0.
You'll usually receive subscription.payment_succeeded at the same moment — that event carries the charge details; this event carries the lifecycle signal.
When it fires
In the renewal cron, after the charge succeeds and the cycle has advanced:
- Cron tick lands on a subscription whose
currentPeriodEndis in the past. - The renewal charge fires against the customer's default payment method.
- On success:
currentPeriodStart= oldcurrentPeriodEnd, newcurrentPeriodEnd= +interval, then this event fires.
A successful retry after a failed renewal also emits subscription.renewed (treat it the same way).
Payload
{
"id": "evt_01HX...",
"type": "subscription.renewed",
"createdAt": "2026-06-01T00:00:15Z",
"accountId": "acc_01HX...",
"data": {
"subscriptionId": "sub_01HX..."
}
}
Slim by design — the event is a notification. Fetch the subscription via GET /v1/payment/subscriptions/:id for the full state, or read it from the sibling subscription.payment_succeeded payload.
Handler examples
// Node
if (event.type === 'subscription.renewed') {
const { subscriptionId } = event.data;
const sub = await client.subscriptions.retrieve(subscriptionId);
await access.extend(sub.customerId, sub.planId, sub.currentPeriodEnd);
}
# Python
if event["type"] == "subscription.renewed":
sub = client.subscriptions.retrieve(event["data"]["subscriptionId"])
access.extend(sub["customerId"], sub["planId"], sub["currentPeriodEnd"])
// Go
if event.Type == "subscription.renewed" {
var d struct{ SubscriptionID string `json:"subscriptionId"` }
_ = json.Unmarshal(event.Data, &d)
sub, _ := client.Subscriptions.Retrieve(ctx, d.SubscriptionID)
access.Extend(ctx, sub.CustomerID, sub.PlanID, sub.CurrentPeriodEnd)
}
What to do
- Extend the entitlement to the new
currentPeriodEnd. - Log the recurring-revenue event.
- Send a renewal receipt if you handle receipts yourself (Storlaunch sends one by default).
Common pitfalls
- Treating it as the only renewal signal. If you also subscribe to
subscription.payment_succeeded, watch out for double-handling. The Plugipay flow fires both for renewals; pick one as your renewal trigger and dedupe the other. - Forgetting the retry-success path. A successful retry after dunning emits this event too — you should restore access from any past-due downgrade, not just extend it.
Related events
subscription.payment_succeeded— the charge that powered the renewal.subscription.payment_failed— the negative path.subscription.past_due— what fires when the renewal can't be collected.