Subscription

subscription.created

A subscription was created for the workspace.

When it fires

After CreateSubscription inserts the subscription row. The only caller is HandleSubscriptionCreated, reached from the inbound Polar webhook at POST /webhooks/polar when Polar sends its own subscription.created event.

If the workspace already has a live subscription (active or trialing), the handler skips the insert and no event is emitted.

EmitWorkspaceEvent is called with actor: null, because these events are system-driven from the billing provider and not from a dashboard user. The delivered envelope still carries an actor object, with userId, name and email all set to null.

Payload

ts
{
    type: 'subscription.created',
    data: {
        subscription: {
            id: string
            status: string                // 'active' | 'trialing' | 'past_due' | 'canceled'
            polarSubscriptionId: string
            polarProductId: string
            currentPeriodStart: string
            currentPeriodEnd: string
        }
    }
}

currentPeriodStart and currentPeriodEnd are never null. The handler refuses the Polar webhook with a 400 when either is missing, and both columns are notNull on SubscriptionSchema.

status is whatever Polar sent. The four values above are the ones Envless recognises in SUBSCRIPTION_STATUS.

Example

json
{
    "id": "0192a1b2-c3d4-7000-8000-0000000000e1",
    "type": "subscription.created",
    "apiVersion": "2026-05-31",
    "createdAt": "2026-05-31T09:12:44.000Z",
    "workspaceId": "0192a1b2-c3d4-7000-8000-0000000000a0",
    "actor": {
        "userId": null,
        "name": null,
        "email": null
    },
    "data": {
        "subscription": {
            "id": "0192a1b2-c3d4-7000-8000-0000000000c0",
            "status": "active",
            "polarSubscriptionId": "sub_abc123",
            "polarProductId": "prod_xyz789",
            "currentPeriodStart": "2026-05-31T00:00:00.000Z",
            "currentPeriodEnd": "2026-06-30T23:59:59.999Z"
        }
    }
}