Version
READ

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.

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

Read-only

It reads and never changes anything.

Arguments

project_idstringoptional

Optional project UUID to narrow the list to a single project.

limitintegeroptional

Maximum plans to return per page (1..100).

min1max100
pageintegeroptional

1-indexed page number.

min1

What 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_ABILITY

token lacks project-subscription-plan:view-any.

RESOURCE_NOT_FOUND

project_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