Subscription Tools
A subscription is one member's purchase of one plan, and it is never created through a tool: checkout and access codes do that.
A subscription is one member's purchase of one plan, and it is never created through a tool: checkout and access codes do that. These tools read subscriptions and their access grants, and drive the rest of a purchase's life, cancelling, pausing, reactivating and reissuing access, each through the same action the dashboard uses.
Tools
cancel_subscriptionCancel SubscriptionREADget_subscriptionGet SubscriptionREADlist_subscription_grantsList Subscription GrantsDESTRUCTIVEpause_subscriptionPause SubscriptionDESTRUCTIVEreactivate_subscriptionReactivate SubscriptionDESTRUCTIVEreissue_subscription_grantsReissue Subscription GrantsDESTRUCTIVEremind_pass_holderRemind Pass HolderDESTRUCTIVEunpause_subscriptionUnpause Subscriptioncancel_subscription
DESTRUCTIVEQueue a subscription cancellation. Provider-side cancellation and local state mutation run asynchronously on the webhooks queue.
Cancel a subscription. Delegates to an Action which queues a job — provider-side cancellation (Stripe / PayPal / Razorpay / Paystack), local state mutation, and the subscription.cancelled event all fire on the webhooks queue. Already-cancelled subscriptions return SUBSCRIPTION_ALREADY_ACTIVE instead of silently succeeding.
Requires ability
The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.
Runs the same action as
The REST endpoint and this tool share one action, so validation, permissions and events are identical.
Fires one event
Delivered to every endpoint subscribed to it once the change is made.
Annotations
A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time. It reaches beyond Subscriby: a connector, a provider or a member.
Arguments
subscription_id*stringUUID of the subscription to cancel.
What it returns
{ "data": { "subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4", "status": "cancellation_queued" }}How it fails
RESOURCE_NOT_FOUNDunknown subscription_id, or the subscription belongs to a team outside the token's scope.
SUBSCRIPTION_ALREADY_ACTIVEsubscription already cancelled.
TOKEN_MISSING_ABILITYtoken lacks project-subscription:update.
get_subscription
READOne subscription by UUID — plan, subscriber, payment method, status, price, trial and end dates, and whether it was cancelled. Read it before acting on it.
Read a subscription's current state back rather than assuming it. Every subscription write tool —
cancel_subscription,
pause_subscription,
unpause_subscription,
reactivate_subscription,
remind_pass_holder — refuses a subscription in the wrong state,
and this is how an agent finds out which state it is in first. The fields are the ones the REST
subscription payload carries.
`canceled` and `ends_at` together tell the story
A subscription cancelled at period end has canceled: true and an ends_at
still in the future — the member keeps access until then, and
reactivate_subscription can still call the cancellation off. Once ends_at
has passed there is nothing to reactivate.
Requires ability
The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.
Runs the same action as
The REST endpoint and this tool share one action, so validation, permissions and events are identical.
Annotations
It reads and never changes anything.
Arguments
subscription_id*stringUUID of the subscription to fetch.
What it returns
{ "data": { "id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4", "plan_id": "9b7c2e15-4d63-4f80-a2b1-7e5d0c9f3a46", "subscriber_id": "2a91c4e7-6f38-4b52-8e0d-9c1a7b3f5d80", "method_id": "a15d70c8-3e46-4b92-b70f-58c9d2140e63", "payment_status": "active", "payment_price": "12.00", "currency_id": "0f6c3b2a-8e19-4d57-b4a2-1c9e7d5f3a80", "trial_ends_at": null, "ends_at": "2026-10-06T10:05:00+00:00", "canceled": false, "compensation_seconds": 0, "redeemed_at": null, "created_at": "2026-09-06T10:05:00+00:00", "updated_at": "2026-09-06T10:05:00+00:00", "grants": [] }}compensation_seconds is the outage time Outage Compensation banked on the purchase; ends_at already includes it, so on a recurring plan the gateway's renewal is ends_at minus compensation_seconds.
grants lists the access grants the subscription holds, one row per resource and dated window, in the shape list_subscription_grants documents.
payment_price is a decimal string in the plan's currency; parse it as a decimal, not a float.
redeemed_at is set only for a subscription that came from an access code, and method_id is null
for those.
How it fails
RESOURCE_NOT_FOUNDunknown subscription_id, or a subscription outside the token's scope.
AUTHENTICATION_REQUIREDno authenticated user on the request.
TOKEN_MISSING_ABILITYtoken lacks project-subscription:view.
List the access grants a subscription holds — one per resource and dated window, with the connector, how access was given, where it stands and why it failed if it did.
Read the access ledger for one purchase: every grant the subscription holds, one per resource (and per dated window for a pass), with the connector that gave it, the mode (an invite link, a membership, a role, a task for the creator), the state (pending_identity, pending, held, granted, revoked, failed) and, for a failure, the classified reason and the sentence a creator reads. Use it to answer "does this member actually have access to the channel?" instead of inferring it from the subscription's payment status.
Requires ability
The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.
Runs the same action as
The REST endpoint and this tool share one action, so validation, permissions and events are identical.
Annotations
It reads and never changes anything.
Arguments
subscription_id*stringUUID of the subscription whose grants to list.
What it returns
{ "data": [ { "id": "7d1c3e9a-2b64-4f0e-9a58-3c6b1d8e2f47", "subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4", "resource_id": "c9e21f37-8a4b-4d56-b1e0-2f7c9d3a6e15", "window_id": null, "identity_id": "0c2d8a7e-4b1f-4d3e-9a6b-2f5e8c1d7a90", "connector": "telegram", "mode": "bearer_link", "state": "granted", "reference": "https://t.me/+AbCdEfGhIjKlMnOp", "granted_at": "2026-09-12T10:05:00+00:00", "revoked_at": null, "failure_kind": null, "failure_detail": null, "created_at": "2026-09-12T10:04:58+00:00" } ]}mode is one of bearer_link (a personal invite link the member comes through), membership (the connector added the member), role (a role was assigned) or creator_task (the creator has to do something by hand). reference is the connector's handle on the grant — the invite link on Telegram — and is null before anything was issued. A failed grant carries failure_kind (unreachable, not_permitted, target_missing, rate_limited, configuration, transient, other) and failure_detail.
How it fails
RESOURCE_NOT_FOUNDsubscription_id is not a valid UUID, or the subscription belongs to another team or a project outside the token's scope.
AUTHENTICATION_REQUIREDno authenticated user on the request.
TOKEN_MISSING_ABILITYtoken lacks project-subscription:view.
pause_subscription
DESTRUCTIVEPause an active or trialing subscription — billing stops and the member keeps their place. The reversible alternative to cancelling.
Put a subscription on hold: billing stops and the member is not cancelled, so their place, their
history and their plan survive. This is the tool to reach for when a human says "stop billing", "put
them on hold" or "freeze the account", because it can be undone with
unpause_subscription while
cancel_subscription cannot.
Emits subscription.paused. Idempotent: pausing an
already-paused subscription is a no-op.
The member loses resource access while paused
Pausing suspends the member's access to the plan's resources for the duration, not just the billing. Confirm the target with a human before calling.
Requires ability
The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.
Runs the same action as
The REST endpoint and this tool share one action, so validation, permissions and events are identical.
Fires one event
Delivered to every endpoint subscribed to it once the change is made.
Annotations
A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time. It reaches beyond Subscriby: a connector, a provider or a member.
Arguments
subscription_id*stringUUID of the subscription to act on.
What it returns
{ "data": { "subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4", "plan_id": "9b7c2e15-4d63-4f80-a2b1-7e5d0c9f3a46", "payment_status": "paused", "outcome": "paused" }}How it fails
VALIDATION_FAILEDthe subscription is not in a state that can be paused (for example, already cancelled or expired).
RESOURCE_NOT_FOUNDunknown subscription_id, or a subscription outside the token's scope.
AUTHENTICATION_REQUIREDno authenticated user on the request.
TOKEN_MISSING_ABILITYtoken lacks project-subscription:update.
reactivate_subscription
DESTRUCTIVEUndo a scheduled cancellation and put the subscription back on its normal billing cycle. Refuses one that was never cancelled.
A cancellation made "at period end" leaves the subscription running until its current period ends. Until then it can be called off, and that is what this tool does: the member goes back on their normal billing cycle as if nothing had happened. It is the recovery path for a cancellation made in error and the tool to reach for on a win-back — "they changed their mind". Safe to call: it restores an intent the member already had.
Refuses a subscription that was never cancelled, and one whose cancellation has already taken
effect. Emits subscription.reactivated.
Stripe only for the true undo
Calling off a scheduled cancellation is something Stripe supports natively. On the other gateways a cancellation ends the agreement outright, so there is nothing to reactivate and the member has to buy again.
Requires ability
The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.
Runs the same action as
The REST endpoint and this tool share one action, so validation, permissions and events are identical.
Fires one event
Delivered to every endpoint subscribed to it once the change is made.
Annotations
A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time. It reaches beyond Subscriby: a connector, a provider or a member.
Arguments
subscription_id*stringUUID of the subscription to act on.
What it returns
{ "data": { "subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4", "plan_id": "9b7c2e15-4d63-4f80-a2b1-7e5d0c9f3a46", "payment_status": "active", "outcome": "reactivated" }}How it fails
VALIDATION_FAILEDthe subscription was never cancelled, or its cancellation has already taken effect.
RESOURCE_NOT_FOUNDunknown subscription_id, or a subscription outside the token's scope.
AUTHENTICATION_REQUIREDno authenticated user on the request.
TOKEN_MISSING_ABILITYtoken lacks project-subscription:update.
reissue_subscription_grants
DESTRUCTIVERevoke the access grants a member holds on a subscription — every resource or one — and have fresh ones issued. The members page's "Refresh invite links", for agents.
Give a member a clean set of grants. The grants they hold on the subscription's resources are
revoked (on Telegram, their personal invite links die) and the dispatcher that grants at
purchase runs again, so fresh grants are issued and the bot sends the member the new links.
Use it when a member says a link is expired or was leaked, or after a channel's admins cleared
a ban; pass resource_id to touch one resource and leave the others as they are.
Every revoked grant raises member.resource_reissued,
and each fresh grant raises member.resource_added
moments later. Read the result back with list_subscription_grants.
This revokes live access and messages a real person
The old links stop working the moment this runs, and the member is sent the
new ones. Read the subscription back with
get_subscription first, and do not run it in
a loop.
Requires ability
The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.
Runs the same action as
The REST endpoint and this tool share one action, so validation, permissions and events are identical.
Fires events
Delivered to every endpoint subscribed to it once the change is made.
Annotations
A client that honours annotations asks a person before running it.
Arguments
subscription_id*stringUUID of the subscription whose grants to reissue.
resource_idstringoptionalUUID of one resource of the plan to reissue alone; omit to reissue every resource the subscription grants.
What it returns
{ "data": { "subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4", "reissued": 2, "status": "reissue_queued" }}reissued counts the grants that were revoked; the fresh ones are issued by a queued job and
appear on the ledger seconds later.
How it fails
VALIDATION_FAILEDthe subscription is not active, so there is nothing to reissue.
RESOURCE_NOT_FOUNDunknown subscription_id, a subscription outside the token's scope, or a resource_id the plan does not grant.
AUTHENTICATION_REQUIREDno authenticated user on the request.
TOKEN_MISSING_ABILITYtoken lacks project-subscription:update.
remind_pass_holder
DESTRUCTIVENudge one pass holder who bought a window but has not come through their grant yet. Answers whether anything was sent.
The members page's per-holder nudge: re-sends one subscriber's invite links for the window they
bought, when they have not yet come through their grant. Use it when a specific member says
"I never got the link"; to reach everyone still missing from a window at once, use
remind_pass_window_queue.
reminded: false is a normal answer, not an error. It means there was nothing to send: the
subscription holds no window, the window has ended or been cancelled, the holder has already
queued, or they cannot be reached on their connector. It is the dashboard's "Nothing sent" notice.
This messages a real person
Read the subscription back with
get_subscription first, and do not repeat the
nudge within the same window.
Requires ability
The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.
Runs the same action as
The REST endpoint and this tool share one action, so validation, permissions and events are identical.
Annotations
A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time.
Arguments
subscription_id*stringUUID of the pass holder's subscription.
What it returns
{ "data": { "subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4", "reminded": true }}How it fails
VALIDATION_FAILEDthe reminder was refused for the subscription's current state.
RESOURCE_NOT_FOUNDunknown subscription_id, or a subscription outside the token's scope.
AUTHENTICATION_REQUIREDno authenticated user on the request.
TOKEN_MISSING_ABILITYtoken lacks project-subscription:update.
unpause_subscription
DESTRUCTIVEResume a paused subscription — billing restarts and resource access is restored. Refuses anything that is not paused.
The reverse of pause_subscription: billing restarts on the
plan's schedule and the member's access to the plan's resources is restored, with fresh invite links
where they are needed. Safe to call — it restores service rather than removing it.
Refuses a subscription that is not currently paused, so it cannot be used to revive a cancelled or
expired one; that is reactivate_subscription for a scheduled
cancellation, or a new purchase. Emits
subscription.unpaused.
Requires ability
The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.
Runs the same action as
The REST endpoint and this tool share one action, so validation, permissions and events are identical.
Fires one event
Delivered to every endpoint subscribed to it once the change is made.
Annotations
A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time. It reaches beyond Subscriby: a connector, a provider or a member.
Arguments
subscription_id*stringUUID of the subscription to act on.
What it returns
{ "data": { "subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4", "plan_id": "9b7c2e15-4d63-4f80-a2b1-7e5d0c9f3a46", "payment_status": "active", "outcome": "active" }}How it fails
VALIDATION_FAILEDthe subscription is not paused.
RESOURCE_NOT_FOUNDunknown subscription_id, or a subscription outside the token's scope.
AUTHENTICATION_REQUIREDno authenticated user on the request.
TOKEN_MISSING_ABILITYtoken lacks project-subscription:update.
How is this guide?