subscription.created
Fires when a new subscription is created. The customer agreed to a plan; billing has either started (if no trial) or is queued to start at trialEnd. Subscribe to this event to provision recurring access — flip the feature flag, send the welcome email, log the cohort.
When it fires
Once per successful POST /v1/payment/subscriptions. Idempotency keys protect against re-fires from duplicate API calls; the outbox protects against re-fires from retry.
Payload
{
"id": "evt_01HX...",
"type": "subscription.created",
"createdAt": "2026-05-13T10:42:00Z",
"accountId": "acc_01HX...",
"data": {
"id": "sub_01HX...",
"accountId": "acc_01HX...",
"customerId": "cust_01HX...",
"planId": "plan_01HX...",
"status": "trialing",
"currentPeriodStart": "2026-05-13T10:42:00Z",
"currentPeriodEnd": "2026-05-20T10:42:00Z",
"trialEnd": "2026-05-20T10:42:00Z",
"metadata": {},
"createdAt": "2026-05-13T10:42:00Z",
"updatedAt": "2026-05-13T10:42:00Z"
}
}
If trialDays > 0, status is trialing and trialEnd is populated. Otherwise status is active and the first charge has already fired (you'll see a paired subscription.payment_succeeded).
Handler examples
// Node
if (event.type === 'subscription.created') {
const s = event.data;
await access.grant(s.customerId, s.planId);
if (s.status === 'trialing') {
await emails.sendTrialWelcome(s.customerId, { endsAt: s.trialEnd });
} else {
await emails.sendPaidWelcome(s.customerId);
}
}
# Python
if event["type"] == "subscription.created":
s = event["data"]
access.grant(s["customerId"], s["planId"])
if s["status"] == "trialing":
emails.send_trial_welcome(s["customerId"], ends_at=s["trialEnd"])
// Go
if event.Type == "subscription.created" {
var s storlaunch.Subscription
_ = json.Unmarshal(event.Data, &s)
access.Grant(ctx, s.CustomerID, s.PlanID)
}
What to do
- Provision access at the subscription's entitlement level.
- Record the cohort in analytics.
- For
trialing, schedule your own "trial ending" reminder (Storlaunch doesn't currently emitsubscription.trial_will_end— see the resource page callout).
Common pitfalls
- Reading
statusonce. A subscription can be createdtrialingand transition toactiveminutes later if the trial is zero days but admin-tools force it. Always re-fetch on the next event. - Ignoring
metadata. If your CRM stuffsuserIdortenantIdinto metadata at create time, propagate it — downstream events carry the same map. - Not deduping. Outbox is at-least-once.
Related events
subscription.renewed— first renewal.subscription.payment_succeeded— the charge.subscription.canceled— the end.