List your subscriptions
The portal.subscriptions.list operation: GET /api/v1/portal/me/subscriptions in the REST API and the portal_subscriptions_list tool in the MCP server.
GET
/api/v1/portal/me/subscriptionsLists the signed-in customer's subscriptions with this brand, newest first: status, plan and quantity, the
current period, discounts, a scheduled change or cancellation, and what the brand's portal settings let the
customer do with each (actions). Customer portal only (portal:read).
At a glance
- REST:
GET /api/v1/portal/me/subscriptions - MCP tool:
portal_subscriptions_list - Operation ID:
portal.subscriptions.list - Scope: Brand
- Permission:
portal:read - Risk tier:
read - Dry run: Not supported
- Idempotency: Not needed (read only)
- Modes: Test and live
- Pagination:
limit(at most 100) andstarting_after - Authentication: A customer signed in to the customer portal (API keys can't call it)
- Since: M9
Request
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
limit | integer (1 to 100) | No | Page size, 1 to 100 (default 20). |
starting_after | string | No | The next_cursor of the previous page. |
Response
200 OK with a JSON object, a page of the list (newest first):
| Field | Type | Description |
|---|---|---|
object | "list" | |
data | array of object | |
data[].id | sub_… ID | |
data[].object | "portal_subscription" | |
data[].status | one of incomplete, incomplete_expired, trialing, active, past_due, unpaid, paused, canceled | |
data[].currency | string | |
data[].items | array of object | |
data[].items[].priceId | price_… ID | |
data[].items[].productId | prod_… ID | |
data[].items[].productName | string | |
data[].items[].priceName | string or null | The price's nickname, e.g. “Pro, monthly”. |
data[].items[].interval | object | |
data[].items[].interval.interval | one of day, week, month, year | |
data[].items[].interval.intervalCount | integer | |
data[].items[].usageType | one of licensed, metered | |
data[].items[].unitAmount | money or null | A per-unit price's amount per unit and period (null for tiered and metered prices). |
data[].items[].taxBehavior | one of inclusive, exclusive | exclusive: tax is added on the invoice. |
data[].items[].id | si_… ID | |
data[].items[].quantity | integer | |
data[].items[].amount | money or null | The item's full-period amount at its quantity, before discounts (null for metered items). |
data[].collectionMethod | one of charge_automatically, send_invoice | charge_automatically (your card is charged) or send_invoice (paid by bank transfer). |
data[].paymentMethodId | pm_… ID or null | The card this subscription charges (null: your default card). |
data[].currentPeriodStart | date-time | |
data[].currentPeriodEnd | date-time | |
data[].trialEnd | date-time or null | |
data[].cancelAtPeriodEnd | boolean | |
data[].cancelAt | date-time or null | |
data[].canceledAt | date-time or null | |
data[].endedAt | date-time or null | |
data[].cancellation | object or null | |
data[].discounts | array of object | |
data[].discounts[].id | disc_… ID | |
data[].discounts[].name | string | The coupon's name. |
data[].discounts[].percentOffPpm | string or null | Parts per million as a string (20% = "200000"). |
data[].discounts[].amountOff | money or null | |
data[].discounts[].start | date-time | |
data[].discounts[].end | date-time or null | When it stops applying (null: for as long as the subscription runs). |
data[].scheduledChange | object or null | A change that applies at effectiveAt (a downgrade waits for the period end). |
data[].actions | object | What you can do with this subscription now, as the brand's portal settings allow. |
data[].actions.switch_plan | boolean | |
data[].actions.change_quantity | boolean | |
data[].actions.apply_promotion_code | boolean | |
data[].actions.cancel | boolean | |
data[].actions.reactivate | boolean | |
data[].actions.change_payment_method | boolean | |
data[].cancelBehavior | one of period_end, immediate | How cancelling here ends the subscription. |
data[].collectCancelReason | boolean | Cancelling asks why (optional answers). |
data[].version | integer | Send it back as expectedVersion to change what you saw. |
data[].createdAt | date-time | |
has_more | boolean | |
next_cursor | string or null |
Examples
One active plan
HTTP
GET /api/v1/portal/me/subscriptions
Authorization: Bearer or_test_…
Response (200):
JSON
{
"object": "list",
"data": [
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf48c0",
"object": "portal_subscription",
"status": "active",
"currency": "EUR",
"items": [
{
"priceId": "price_01m4tx5nj8emwbyf7y9vcf48c2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf48c4",
"productName": "Genno Plus",
"priceName": "Plus, monthly",
"interval": {
"interval": "month",
"intervalCount": 1
},
"usageType": "licensed",
"unitAmount": {
"amount": "9000000",
"currency": "EUR"
},
"taxBehavior": "inclusive",
"id": "si_01m4tx5nj8emwbyf7y9vcf48c1",
"quantity": 1,
"amount": {
"amount": "9000000",
"currency": "EUR"
}
}
],
"collectionMethod": "charge_automatically",
"paymentMethodId": null,
"currentPeriodStart": "2026-10-20T09:00:00.000Z",
"currentPeriodEnd": "2026-11-20T10:00:00.000Z",
"trialEnd": null,
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"discounts": [],
"scheduledChange": null,
"actions": {
"switch_plan": true,
"change_quantity": false,
"apply_promotion_code": true,
"cancel": true,
"reactivate": false,
"change_payment_method": true
},
"cancelBehavior": "period_end",
"collectCancelReason": true,
"version": 4,
"createdAt": "2026-09-20T09:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | A pagination value is malformed. | Fix the fields listed in details.issues and send the request again. |
livemode_not_allowed | 403 | The portal session is in the other mode than the request. | Use test mode, or credentials for the target's mode. Developers need live access granted by an organization owner or admin. |
permission_denied | 403 | The caller isn't a customer signed in to this brand's portal (operators and API keys use the subscription and wallet operations). | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: api_version_unsupported, authentication_required, api_key_invalid, scope_required, resource_not_found, dry_run_not_supported, rate_limited, internal_error.