subscription,
and every webhook carries it under data.access, payment_status and access_until are what
GET /v1/access answers for the same subscription, so
you know whether it grants access without asking again. So are
blocked_since and blocked_reason, null unless its charges are
blocked.
Lifecycle says what each status means.Where it stands. Unlike GET /v1/access, may be expired: a checkout nobody signed. cancelled while the cancellation runs, ended once its end passed. For a few minutes after a plan's end date it can still read active or unpaid with access false, never ended with access true.
One ofpendingactiveunpaidcancelledstoppedendedfailedexpiredsuperseded
True on a seat parked over the project's subscriber limit, its status unchanged. subscription.paused and subscription.unpaused are sent when it changes.
Why it ended. Set only when status is ended. Null on every other status, and on an old subscription that ended with no reason recorded.
One ofcancelledplan_removedplan_replacedplan_endedclosed_elsewhereclosed
Why a payment is late, as the last failed charge found it. Set only when status is unpaid, or stopped for the payment it stopped on. Null on every other status, and when Mesub cannot name the cause.
One ofinsufficient_balanceapproval_revokedauthority_closed
Why it stopped. Set only when status is stopped. Null on every other status, and on a subscription that stopped before Mesub recorded why.
- out_of_retries: every retry of the missed payment failed. The subscription stays open on Solana: the subscriber can come back, or cancel it and close it once the period ends.
- retry_deadline_passed: on the Free tier, the last day to pay the missed payment passed.
- authority_closed: the wallet closed the account that lets Mesub charge it, for good. Nobody can charge this subscription again, and the subscriber cannot come back on it. They can close it now (closable) to get its deposit back.
One ofout_of_retriesretry_deadline_passedauthority_closed
Whether this subscription grants access now, as GET /v1/access answers it. False from the plan's end date on, whatever period was paid for.
late while a charge missed and a retry is pending. none where nothing is being billed.
One ofpaidlatenone
Since when every charge of this subscription is held for a reason that is not the customer's. Null when none is. status and payment_status do not change for it, and Mesub keeps trying. access ends at access_until, and comes back with the first charge that goes through, with nothing for the customer to sign.
Why the charges are held. Null with blocked_since. Nine values name the plan's own setup, yours to fix or, for the last two, the token issuer's to lift: puller_not_allowed (Mesub's puller was taken off the plan on chain), receiver_not_allowed (the receiving wallet is not among the plan's destinations), receiver_account_missing (it has no account for the plan's token, and nobody else can be paid), receiver_account_frozen (its account for the plan's token is frozen), receiver_account_needs_memo (that account requires a memo on every transfer in, which Mesub's charges do not carry), receiver_account_confidential_only (that account takes confidential transfers only), mint_gone (the token no longer exists), mint_paused (the token's issuer paused it: no payment in it moves, and Mesub charges again once the pause is lifted) and mint_transfer_hook (the token's issuer made its transfers run a program of theirs, which Mesub does not support yet: it charges again if the issuer removes it). mesub is any cause on Mesub's side: nothing for you to fix. Mesub may add a value: keep a default branch.
One ofpuller_not_allowedreceiver_not_allowedreceiver_account_missingreceiver_account_frozenreceiver_account_needs_memoreceiver_account_confidential_onlymint_gonemint_pausedmint_transfer_hookmesub
The plan's slug.
The wallet that pays.
Where the customer's notices go, as given at creation.
Your own id for the customer, as given at creation.
The start of the period last paid for. Null before the first.
The end of that period.
The next charge on a running subscription. Null when a retry is pending instead, and when the plan's end date leaves no charge to make: a subscription in its last period has none.
The next retry on a late one. Null when the plan ends before it.
On Free only: when retries by hand close for the missed period, or the plan's end date when that comes first.
Which retry comes at next_retry_at: 1 is the first after the missed charge. Null unless Mesub retries on its own, and when next_retry_at is null.
How many retries the missed period gets. Null unless Mesub retries on its own.
When access ends unless a charge renews it. Never later than the plan's end date, where access stops for everybody. Null while access is false. On a subscription whose charges are blocked (blocked_since), the date access ends if nothing is collected by then: the end of the period after the one paid for, or sooner when the cause is the plan's setup, the end of the grace the plan gives a late payment.
Whether the subscriber can close the subscription on Solana now, which returns its deposit to their wallet: a cancellation whose end has passed, a subscription that ended with its plan, or one stopped with stop_reason authority_closed. As Mesub last knew the chain: the close reads the chain again, and may still be refused.
When the subscriber can close it, if not now: the end of the period a cancellation set. Null when closable is true, and when no date is known yet: a running subscription, or one stopped with out_of_retries, must be cancelled first. As Mesub last knew the chain, like closable.
When it was reserved.
When its first payment landed.
{ "id": "cmg1x0abc0001", "status": "active", "paused": false, "end_reason": null, "late_reason": null, "stop_reason": null, "access": true, "payment_status": "paid", "blocked_since": null, "blocked_reason": null, "plan": "pro", "wallet": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin", "email": "[email protected]", "external_id": "user_42", "current_period_start": "2026-01-01T00:00:00.000Z", "current_period_end": "2026-01-31T00:00:00.000Z", "next_charge_at": "2026-01-31T00:00:00.000Z", "next_retry_at": null, "retry_deadline": null, "next_retry_number": null, "retries_allowed": null, "access_until": "2026-01-31T00:00:00.000Z", "closable": false, "closable_from": null, "created_at": "2026-01-01T00:00:00.000Z", "confirmed_at": "2026-01-01T00:00:05.000Z" }