list_plans
Paginated list of subscription plans visible to the current token, optionally scoped to one project.
List subscription plans. Results are always scoped to the caller's team; pass an optional project_id to narrow further. Ordered by newest-first.
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
project_idstringoptionalOptional project UUID to narrow the list to a single project.
limitintegeroptionalMaximum plans to return per page (1..100).
1max100pageintegeroptional1-indexed page number.
1What it returns
{ "data": [ { "id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b", "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13", "name": "Premium Monthly", "description": "All-access pass", "price": "29.00", "currency": "USD", "kind": "subscription", "cadence": "Per Month", "active": true, "sales_cap": null, "sales_cap_sold": 0, "position": null, "paused_reason": null, "created_at": "2026-05-18T10:05:00Z", "billing": { "billing_cycle": "months", "billing_cycle_count": 1, "recurring": true, "trial_days": 7, "trial_cardless": false } } ], "meta": { "page": 1, "limit": 25, "total": 3, "has_more": false }}Every row is tagged by kind
kind names the ONE nested block that accompanies it — billing, pass or pass_series.
The other two are absent, not null. So a billing cycle never appears on a plan where a
cycle means nothing, and you never have to probe for a nullable object to work out what you
are holding.
Every row also carries cadence, the human-readable duration string the portal and the
bot show — "Per Month", "Per 3 Hours", "For all 10 passes". Use it rather than
deriving a duration yourself; deriving one from a pass's cycle fields is how integrations end
up printing "1 Month" beside a three-hour window.
kind: pass
{
"kind": "pass",
"cadence": "Per 3 Hours",
"pass": {
"timezone": "America/New_York",
"recurrence": "weekly",
"sales_cutoff_minutes": 60,
"sales_cutoff_anchor": "before_start",
"next_window": {
"id": "3d5a8c72-b016-4e94-8fa7-61c209d4e738",
"starts_at": "2026-09-20T13:00:00Z",
"ends_at": "2026-09-21T03:00:00Z"
}
}
}Window timestamps are UTC; pass.timezone is the zone the schedule was authored in and the
one a buyer should see. pass.next_window is null when the schedule has no window left to
sell, which also means the plan is not purchasable right now. On a plan whose sales cutoff is
anchored to the window end, that window may be one already running rather than a future one.
kind: pass_series
{
"kind": "pass_series",
"cadence": "For all 10 passes",
"pass_series": {
"timezone": "America/New_York",
"window_count": 10,
"starts_at": "2026-09-20T13:00:00Z",
"ends_at": "2026-11-29T22:00:00Z",
"seat_cap": 50,
"seats_remaining": 13,
"successor_plan_id": null
}
}A series sells a slate of other pass plans' windows for one payment. It owns none of its
own, so there is no schedule here — use list_pass_windows
to see the individual dates, and the Plans API for the full slate with
the plan each date came from.
How it fails
TOKEN_MISSING_ABILITYtoken lacks project-subscription-plan:view-any.
RESOURCE_NOT_FOUNDproject_id names a project the token cannot see: unknown, another team's, or outside the token's scope:project: allow-list. Without a project_id, the list spans only the projects the allow-list admits.
How is this guide?
Last updated on