Subscription events are triggered when mailbox subscriptions are renewed, updated, or cancelled. A subscription is the ongoing service that keeps mailbox accounts active after they're created.
Overview#
Subscriptions are separate from domain registrations. Here's the relationship:Domain → Registered once, renewed periodically (yearly)
Subscription → Billing period for mailboxes (monthly, yearly, etc.), can be renewed or cancelled independently
A mailbox subscription depends on the domain being active. If the domain expires or enters a grace period, the subscription renewal will fail.
Common Payload Fields#
All subscription events share a common set of fields in addition to any event-specific ones.| Field | Type | Description |
|---|
event | string | The event type (e.g. "subscription.renewal.success") |
eventId | string | Unique identifier for this event |
data.userId | string | User who owns the subscription |
data.userEmail | string | User's email address |
data.subscriptionId | string | The subscription's identifier |
data.domainId | string | Domain linked to this subscription |
data.domain | string | Domain name |
data.workspaceType | string | "GOOGLE" or "MICROSOFT" |
data.quantity | number | Number of mailboxes in this subscription |
data.periodStart | string | Start of the current billing period (ISO 8601) |
data.periodEnd | string | End of the current billing period (ISO 8601) |
data.autoRenew | boolean | Whether auto-renewal is enabled |
data.description | string | Human-readable description of the subscription |
data.subscriptionStatus | string | Current subscription status |
subscription.renewing#
This event is triggered when a subscription renewal is initiated and the subscription transitions to the RENEWING state.When it occurs#
Renewal date arrives and renewal is queued
Payment is being processed
Subscription status changes from ACTIVE → RENEWING
Example Payload#
{
"event": "subscription.renewing",
"eventId": "6SSHBXWQ3N3JEKHRQ763KW3D76N6",
"data": {
"userId": "PWM7Y25RYZ450YNM8K8FX9GK5AHX",
"userEmail": "johndoe@company.com",
"subscriptionId": "YC2H6C87PPKPG5WXVNQ682GAVFTM",
"domainId": "AH2BD0WYWSMQC9NQHTMES3TFK4TX",
"domain": "company.com",
"workspaceType": "GOOGLE",
"quantity": 3,
"periodStart": "2025-01-01T00:00:00.000Z",
"periodEnd": "2025-02-01T00:00:00.000Z",
"autoRenew": true,
"description": "GOOGLE workspace subscription for company.com",
"subscriptionStatus": "RENEWING"
}
}
subscription.renewal.success#
This event is triggered when a mailbox subscription is successfully renewed for the next billing period.When it occurs#
A subscription renewal period arrives (e.g., monthly renewal date)
The linked domain is active and not expired
Billing is processed successfully
Subscription is extended for another period
Example Payload#
{
"event": "subscription.renewal.success",
"eventId": "6SSHBXWQ3N3JEKHRQ763KW3D76N6",
"data": {
"userId": "PWM7Y25RYZ450YNM8K8FX9GK5AHX",
"userEmail": "johndoe@company.com",
"subscriptionId": "YC2H6C87PPKPG5WXVNQ682GAVFTM",
"domainId": "AH2BD0WYWSMQC9NQHTMES3TFK4TX",
"domain": "company.com",
"workspaceType": "GOOGLE",
"quantity": 3,
"periodStart": "2025-02-01T00:00:00.000Z",
"periodEnd": "2025-03-01T00:00:00.000Z",
"autoRenew": true,
"description": "GOOGLE workspace subscription for company.com",
"subscriptionStatus": "ACTIVE",
"price": 15.00,
"invoiceUrl": "https://invoice.stripe.com/i/acct_xxx/...",
"invoiceNumber": "INV-0001"
}
}
Payload Schema (additional fields)#
| Field | Type | Description |
|---|
data.price | number | Total renewal charge |
data.invoiceUrl | string | null | Link to the Stripe invoice |
data.invoiceNumber | string | null | Invoice reference number |
subscription.renewal.failed#
This event is triggered when a subscription renewal fails. This specifically means the mailbox subscription couldn't be renewed because the linked domain is not active.When it occurs#
Subscription renewal date arrives
Linked domain is in GRACE_PERIOD — expired but recoverable
Linked domain is EXPIRED — past grace period, deleted at registrar
Mailbox accounts can't be renewed without an active domain
No billing is attempted until the domain is fixed
Example Payload#
{
"event": "subscription.renewal.failed",
"eventId": "6SSHBXWQ3N3JEKHRQ763KW3D76N6",
"data": {
"userId": "PWM7Y25RYZ450YNM8K8FX9GK5AHX",
"userEmail": "johndoe@company.com",
"subscriptionId": "YC2H6C87PPKPG5WXVNQ682GAVFTM",
"domainId": "AH2BD0WYWSMQC9NQHTMES3TFK4TX",
"domain": "company.com",
"workspaceType": "GOOGLE",
"quantity": 3,
"periodStart": "2025-01-01T00:00:00.000Z",
"periodEnd": "2025-02-01T00:00:00.000Z",
"autoRenew": true,
"description": "GOOGLE workspace subscription for company.com",
"subscriptionStatus": "ACTIVE",
"domainStatus": "GRACE_PERIOD",
"reason": "Domain is in GRACE_PERIOD; subscription renewal was not attempted. Please renew the domain at registrar."
}
}
Payload Schema (additional fields)#
| Field | Type | Description |
|---|
data.domainStatus | string | null | "GRACE_PERIOD" or "EXPIRED" |
data.reason | string | Human-readable explanation |
Domain Status Meanings#
GRACE_PERIOD — Domain expired but registrar still allows renewal (usually 30 days)
EXPIRED — Domain has passed grace period and is deleted at registrar. Recovery may require registrar intervention.
subscription.past_due#
This event is triggered when a subscription enters the PAST_DUE state. The subscription remains accessible for a 7-day grace window before expiry.When it occurs#
Payment for a renewal fails (Stripe payment intent failed)
Subscription period ends without a successful renewal (caught by hourly safety-net cron, 26 hours after periodEnd)
Subscription status changes to PAST_DUE
Example Payload#
{
"event": "subscription.past_due",
"eventId": "6SSHBXWQ3N3JEKHRQ763KW3D76N6",
"data": {
"userId": "PWM7Y25RYZ450YNM8K8FX9GK5AHX",
"userEmail": "johndoe@company.com",
"subscriptionId": "YC2H6C87PPKPG5WXVNQ682GAVFTM",
"domainId": "AH2BD0WYWSMQC9NQHTMES3TFK4TX",
"domain": "company.com",
"workspaceType": "GOOGLE",
"quantity": 3,
"periodStart": "2025-01-01T00:00:00.000Z",
"periodEnd": "2025-02-01T00:00:00.000Z",
"autoRenew": true,
"description": "GOOGLE workspace subscription for company.com",
"subscriptionStatus": "PAST_DUE"
}
}
Recommended Actions#
When you receive this event:Notify your customer that their subscription payment failed and they have a 7-day grace window
Prompt payment resolution or domain renewal (if subscription.renewal.failed was previously received)
If autoRenew is false and the issue is unresolved within 7 days, a subscription.expired event will follow
If autoRenew is true, the subscription will remain PAST_DUE and retry renewal once the underlying issue is resolved — subscription.expired will not fire
subscription.cancelled#
This event is triggered when a mailbox subscription is cancelled because the user disabled auto-renewal and the current billing period has ended.When it occurs#
User disables auto-renewal for the subscription
Current billing period expires
Subscription is no longer active
Mailbox accounts will be deactivated
Example Payload#
{
"event": "subscription.cancelled",
"eventId": "6SSHBXWQ3N3JEKHRQ763KW3D76N6",
"data": {
"userId": "PWM7Y25RYZ450YNM8K8FX9GK5AHX",
"userEmail": "johndoe@company.com",
"subscriptionId": "YC2H6C87PPKPG5WXVNQ682GAVFTM",
"domainId": "AH2BD0WYWSMQC9NQHTMES3TFK4TX",
"domain": "company.com",
"workspaceType": "GOOGLE",
"quantity": 3,
"periodStart": "2025-01-01T00:00:00.000Z",
"periodEnd": "2025-02-01T00:00:00.000Z",
"autoRenew": false,
"description": "GOOGLE workspace subscription for company.com",
"subscriptionStatus": "CANCELLED"
}
}
subscription.expired#
This event is triggered when a subscription's 7-day grace period ends and the subscription has auto-renewal disabled. Mailboxes are deactivated and the subscription is permanently expired.When it occurs#
Subscription has been in PAST_DUE state for 7 days
autoRenew is false — the subscription is not expected to self-recover
Mailboxes are disabled and removed from the provider
Note: If autoRenew is true, the subscription remains in PAST_DUE after the grace period and is not automatically expired — it will be picked up by the renewal mechanism once the underlying issue (payment or domain) is resolved. subscription.expired will not fire for those subscriptions.
Example Payload#
{
"event": "subscription.expired",
"eventId": "6SSHBXWQ3N3JEKHRQ763KW3D76N6",
"data": {
"userId": "PWM7Y25RYZ450YNM8K8FX9GK5AHX",
"userEmail": "johndoe@company.com",
"subscriptionId": "YC2H6C87PPKPG5WXVNQ682GAVFTM",
"domainId": "AH2BD0WYWSMQC9NQHTMES3TFK4TX",
"domain": "company.com",
"workspaceType": "GOOGLE",
"quantity": 3,
"periodStart": "2025-01-01T00:00:00.000Z",
"periodEnd": "2025-02-01T00:00:00.000Z",
"autoRenew": false,
"description": "GOOGLE workspace subscription for company.com",
"subscriptionStatus": "EXPIRED"
}
}
Recommended Actions#
When you receive this event:Notify your customer that their mailboxes have been deactivated
Update your records to reflect the expired state
To restore mailboxes a new subscription order is required
subscription.updated#
This event is triggered when a subscription crosses the 12-month mark at renewal. The subscription price updates to $5 per mailbox per month to reflect increased vendor pricing from Google and Microsoft for long-running accounts.This event fires once per subscription — only at the first renewal where the 12-month threshold is crossed.When it occurs#
Subscription renewal date arrives
Subscription has been active for 12 months or more
This is the first time the subscription qualifies for the one plus year tier
Renewal is charged at the updated $5/mailbox/month rate
Example Payload#
{
"event": "subscription.updated",
"eventId": "6SSHBXWQ3N3JEKHRQ763KW3D76N6",
"data": {
"userId": "PWM7Y25RYZ450YNM8K8FX9GK5AHX",
"userEmail": "johndoe@company.com",
"subscriptionId": "YC2H6C87PPKPG5WXVNQ682GAVFTM",
"workspaceType": "GOOGLE",
"description": "Subscription YC2H6C87PPKPG5WXVNQ682GAVFTM is now one plus year"
}
}
Payload Schema#
| Field | Type | Description |
|---|
event | string | Always "subscription.updated" |
eventId | string | Unique identifier for this event |
data.userId | string | User who owns the subscription |
data.userEmail | string | User's email address |
data.subscriptionId | string | Subscription that has been updated |
data.workspaceType | string | "GOOGLE" or "MICROSOFT" |
data.description | string | Human-readable description of the change |
Recommended Actions#
When you receive this event:Notify your customer that their renewal price has updated to $5 per mailbox per month
Update your billing records with the new rate
If your customer does not want to continue at the updated price, use the Recreation API to provision a fresh subscription at standard pricing
Understanding the Subscription Flow#
Successful renewal cycle#
Subscription active
↓
Renewal date arrives
↓
subscription.renewing
↓
subscription.renewal.success ✓
↓
Next billing period starts
↓
(Cycle repeats at next renewal date)
Failed renewal (domain issue)#
Subscription active
↓
Renewal date arrives
↓
Domain check: EXPIRED or GRACE_PERIOD
↓
subscription.renewal.failed ✗
↓
Mailboxes stay active until period ends
↓
subscription.past_due (26hr safety net)
↓
User must renew domain and trigger retry
Payment failure flow#
Subscription active
↓
Renewal date arrives
↓
subscription.renewing
↓
Payment fails
↓
subscription.past_due ✗ (7-day grace begins)
↓
7 days pass without recovery
↓
autoRenew = false → subscription.expired ✗ → Mailboxes deactivated
autoRenew = true → Stays PAST_DUE, retries renewal when issue is resolved
Cancellation flow#
Subscription active
↓
User disables auto-renewal
↓
Current period expires
↓
subscription.cancelled ✗
↓
Mailboxes deactivated
One plus year transition#
Subscription active (approaching 12 months)
↓
Renewal date arrives
↓
subscription.renewing
↓
subscription.updated (price → $5/mailbox/month)
↓
subscription.renewal.success ✓
↓
Partner notifies customer
↓
Customer continues OR partner triggers recreation
Notes#
Subscription and domain are independent — You can have a domain without a subscription, or a subscription without owning the domain (white label)
Auto-renewal can be toggled — Users can enable/disable via dashboard
subscription.updated fires once — It will not repeat on subsequent renewals after the 12-month flag is set
Deduplication — Status events (renewing, past_due, expired, cancelled) are deduplicated: if the subscription is already in a given status, the webhook will not fire again until a different status is reached
subscription.expired requires autoRenew: false — Subscriptions with auto-renewal still enabled are never automatically expired after the grace period; they stay PAST_DUE and retry renewal once payment or domain issues are resolved
See Also#
Modified at 2026-06-27 06:26:57