Get one of your subscriptions
The portal.subscriptions.get operation: GET /api/v1/portal/me/subscriptions/{subscriptionId} in the REST API and the portal_subscriptions_get tool in the MCP server.
/api/v1/portal/me/subscriptions/{subscriptionId}Returns one of the signed-in customer's subscriptions as portal.subscriptions.list shows it, plus the plans
each item may switch to under the brand's plan-change matrix (planOptions) and the upcoming invoice as it
stands now (upcomingInvoice: the next renewal's lines, tax and amount due; null when nothing is billed next).
Customer portal only (portal:read).
At a glance
- REST:
GET /api/v1/portal/me/subscriptions/{subscriptionId} - MCP tool:
portal_subscriptions_get - Operation ID:
portal.subscriptions.get - Scope: Brand
- Permission:
portal:read - Risk tier:
read - Dry run: Not supported
- Idempotency: Not needed (read only)
- Modes: Test and live
- Authentication: A customer signed in to the customer portal (API keys can't call it)
- Since: M9
Request
Path parameters
| Field | Type | Description |
|---|---|---|
subscriptionId | sub_… ID | One of your subscriptions (sub_…). |
Query parameters
This operation takes no query parameters.
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
id | sub_… ID | |
object | "portal_subscription" | |
status | one of incomplete, incomplete_expired, trialing, active, past_due, unpaid, paused, canceled | |
currency | string | |
items | array of object | |
items[].priceId | price_… ID | |
items[].productId | prod_… ID | |
items[].productName | string | |
items[].priceName | string or null | The price's nickname, e.g. “Pro, monthly”. |
items[].interval | object | |
items[].interval.interval | one of day, week, month, year | |
items[].interval.intervalCount | integer | |
items[].usageType | one of licensed, metered | |
items[].unitAmount | money or null | A per-unit price's amount per unit and period (null for tiered and metered prices). |
items[].taxBehavior | one of inclusive, exclusive | exclusive: tax is added on the invoice. |
items[].id | si_… ID | |
items[].quantity | integer | |
items[].amount | money or null | The item's full-period amount at its quantity, before discounts (null for metered items). |
collectionMethod | one of charge_automatically, send_invoice | charge_automatically (your card is charged) or send_invoice (paid by bank transfer). |
paymentMethodId | pm_… ID or null | The card this subscription charges (null: your default card). |
currentPeriodStart | date-time | |
currentPeriodEnd | date-time | |
trialEnd | date-time or null | |
cancelAtPeriodEnd | boolean | |
cancelAt | date-time or null | |
canceledAt | date-time or null | |
endedAt | date-time or null | |
cancellation | object or null | |
discounts | array of object | |
discounts[].id | disc_… ID | |
discounts[].name | string | The coupon's name. |
discounts[].percentOffPpm | string or null | Parts per million as a string (20% = "200000"). |
discounts[].amountOff | money or null | |
discounts[].start | date-time | |
discounts[].end | date-time or null | When it stops applying (null: for as long as the subscription runs). |
scheduledChange | object or null | A change that applies at effectiveAt (a downgrade waits for the period end). |
actions | object | What you can do with this subscription now, as the brand's portal settings allow. |
actions.switch_plan | boolean | |
actions.change_quantity | boolean | |
actions.apply_promotion_code | boolean | |
actions.cancel | boolean | |
actions.reactivate | boolean | |
actions.change_payment_method | boolean | |
cancelBehavior | one of period_end, immediate | How cancelling here ends the subscription. |
collectCancelReason | boolean | Cancelling asks why (optional answers). |
version | integer | Send it back as expectedVersion to change what you saw. |
createdAt | date-time | |
planOptions | array of object | Per item, the plans you can switch to (empty unless actions.switch_plan). |
planOptions[].itemId | si_… ID | |
planOptions[].targets | array of object | |
planOptions[].targets[].priceId | price_… ID | |
planOptions[].targets[].productId | prod_… ID | |
planOptions[].targets[].productName | string | |
planOptions[].targets[].priceName | string or null | The price's nickname, e.g. “Pro, monthly”. |
planOptions[].targets[].interval | object | |
planOptions[].targets[].interval.interval | one of day, week, month, year | |
planOptions[].targets[].interval.intervalCount | integer | |
planOptions[].targets[].usageType | one of licensed, metered | |
planOptions[].targets[].unitAmount | money or null | A per-unit price's amount per unit and period (null for tiered and metered prices). |
planOptions[].targets[].taxBehavior | one of inclusive, exclusive | exclusive: tax is added on the invoice. |
upcomingInvoice | object or null | The next invoice as it stands now (null when nothing is billed next). |
Examples
A monthly plan that can move up to Pro
GET /api/v1/portal/me/subscriptions/sub_01m4tx5nj8emwbyf7y9vcf48c0
Authorization: Bearer or_test_…
Response (200):
{
"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",
"planOptions": [
{
"itemId": "si_01m4tx5nj8emwbyf7y9vcf48c1",
"targets": [
{
"priceId": "price_01m4tx5nj8emwbyf7y9vcf48c3",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf48c5",
"productName": "Genno Pro",
"priceName": "Pro, monthly",
"interval": {
"interval": "month",
"intervalCount": 1
},
"usageType": "licensed",
"unitAmount": {
"amount": "29000000",
"currency": "EUR"
},
"taxBehavior": "inclusive"
}
]
}
],
"upcomingInvoice": {
"currency": "EUR",
"lines": [
{
"description": "Genno Plus (Plus, monthly)",
"quantity": 1,
"amount": {
"amount": "9000000",
"currency": "EUR"
},
"proration": false,
"periodStart": "2026-11-20T10:00:00.000Z",
"periodEnd": "2026-12-20T10:00:00.000Z"
}
],
"subtotal": {
"amount": "7377049",
"currency": "EUR"
},
"tax": {
"amount": "1622951",
"currency": "EUR"
},
"total": {
"amount": "9000000",
"currency": "EUR"
},
"creditApplied": null,
"amountDue": {
"amount": "9000000",
"currency": "EUR"
}
}
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | The subscription's ID or a pagination value is malformed. | Fix the fields listed in details.issues and send the request again. |
resource_not_found | 404 | You have no such subscription (another customer's reads the same). | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode. |
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, dry_run_not_supported, rate_limited, internal_error.