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 emit subscription.trial_will_end — see the resource page callout).

Common pitfalls

  • Reading status once. A subscription can be created trialing and transition to active minutes later if the trial is zero days but admin-tools force it. Always re-fetch on the next event.
  • Ignoring metadata. If your CRM stuffs userId or tenantId into metadata at create time, propagate it — downstream events carry the same map.
  • Not deduping. Outbox is at-least-once.

Related events

Next