get_plan
Fetch one plan by UUID — the same kind-tagged row list_plans emits, with its one nested block and its cadence string.
Purpose
Read one plan in full. The row is the same one list_plans emits, so an
agent that found a plan in the list reads exactly the same fields back, and the row
update_plan returns after a change is comparable field for field.
Reads go through the plan service, so the tenant scope and the token's scope:project: allow-list
both apply. An id the token cannot see answers RESOURCE_NOT_FOUND, indistinguishable from an id
that never existed.
`kind` names the ONE block you will find
Every plan carries a kind — subscription, pass or pass_series — and
the kind decides which single nested object accompanies it: billing, pass
or pass_series. The other two are absent, not null. Read the tag and you
know what you are holding; there is no nullable object to probe.
Every row also carries cadence, the human-readable duration the portal and the bot show — "Per Month", "Per 3 Hours", "For all 10 passes". Use it rather than deriving a duration yourself.
Required ability
project-subscription-plan:view
Input schema
{
"type": "object",
"required": ["plan_id"],
"properties": {
"plan_id": {
"type": "string",
"description": "UUID of the plan to fetch."
}
}
}Output shape
{
"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": 10,
"sales_cap_sold": 3,
"position": 0,
"paused_reason": null,
"created_at": "2026-05-18T10:05:00+00:00",
"billing": {
"billing_cycle": "months",
"billing_cycle_count": 1,
"recurring": true,
"trial_days": 7,
"trial_cardless": false
}
}
}price is a decimal string; currency is an ISO code. The block changes with the kind:
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:00+00:00",
"ends_at": "2026-09-20T16:00:00+00:00"
}
}
}pass.next_window is the next window still on sale, in UTC, or null when the schedule has nothing
left to sell — which also means the plan is not purchasable right now. For the full schedule call
list_pass_windows.
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:00+00:00",
"ends_at": "2026-11-29T22:00:00+00:00",
"seat_cap": 50,
"seats_remaining": 13,
"successor_plan_id": null
}
}seat_cap and seats_remaining are null on an uncapped season. successor_plan_id is set once
start_next_season has run; it is the plan current holders are
offered in the presale.
Example prompts
"Show me plan
c4e82f16-93a7-4d5b-b81c-6e0f27a94d3bin full."
"What billing cycle and trial does the Premium Monthly plan have?"
"Is the Match Day Pass still selling, and when is its next window?"
Failure modes
RESOURCE_NOT_FOUND— unknownplan_id, a plan on another team's project, one outside the token'sscope:project:allow-list, or a plan that has been deleted.AUTHENTICATION_REQUIRED— no authenticated user on the request.TOKEN_MISSING_ABILITY— token lacksproject-subscription-plan:view.
Related
list_plans— find the id.update_planpublish_planlist_pass_windows— the dates behind apassorpass_series.- Plans API — the REST equivalent and the full shape reference.
- Subscription Plans — the feature walkthrough.
How is this guide?