Plan
Plan, renewal and limits.
Privacy and analytics
We use necessary technical cookies and, only with your consent, analytics and marketing pixels to improve the website and measure campaigns.
Plan, renewal and limits.
Read-only in every door.
Current plan, status, renewal date and how much of each limit is used (works, storage, seats). AI spend is never shown to the brand. Read-only: changing plans happens on the plan screen.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/subscriptions.read |
| MCP tool | subscriptions_read |
| Scope | subscriptions.read |
| Minimum role | Billing |
| Human confirmation | No |
| Doors | Nödo, Voice, MCP, API, Chat, Screens, Apps |
| Status | Available |
| Widget | usage |
Input
{}Output
{
plan: string | null
status: string | null
renewsAt: string | null
limits: Array<{
key: string
label: string
used: number | null
limit: number | null
unit: string | null
}>
}Everything the brand is charged for each period: its platform plan, contracted services and recurring store purchases, each with its next charge date, amount (net, VAT, gross), status and who collects it; plus the saved payment method (brand and last four digits only). Drafts the team is still preparing are left out. For plan limits use subscriptions.read.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/subscriptions.screen.list |
| MCP tool | subscriptions_screen_list |
| Scope | subscriptions.read |
| Minimum role | Billing |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{}Output
{
subscriptions: Array<{
id: string
kind: "plan" | "service" | "store"
name: string
planName: string | null
summary: string
cadence: {
interval: "day" | "week" | "month" | "year"
count: integer // 1–9007199254740991
}
| null
currency: string
amount: {
netMinor: integer // -9007199254740991–9007199254740991
taxMinor: integer // -9007199254740991–9007199254740991
grossMinor: integer // -9007199254740991–9007199254740991
}
| null
nextChargeAt: string | null
endsAt: string | null
status: "active" | "ending" | "paused" | "past_due" | "trialing" | "canceled"
channel: "stripe_auto" | "holded" | "manual" | "stripe" | null
}>
nextCharge: {
subscriptionId: string
name: string
date: string
grossMinor: integer // -9007199254740991–9007199254740991
currency: string
}
| null
monthlyGrossMinor: integer // -9007199254740991–9007199254740991
currency: string
paymentMethod: {
kind: "card" | "sepa_debit" | "other"
brand: string | null
last4: string | null
wallet: string | null
}
| null
}One contracted service subscription: its lines (title, quantity, unit and unit price), the per-period amount with VAT, cadence, start, next charge and end dates, who collects it, the saved payment method and its recent period charges (newest first, up to 12). Not for the platform plan (see subscriptions.read).
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/subscriptions.screen.get |
| MCP tool | subscriptions_screen_get |
| Scope | subscriptions.read |
| Minimum role | Billing |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
subscriptionId: string // uuid
}Output
{
subscription: {
id: string
kind: "plan" | "service" | "store"
name: string
planName: string | null
summary: string
cadence: {
interval: "day" | "week" | "month" | "year"
count: integer // 1–9007199254740991
}
| null
currency: string
amount: {
netMinor: integer // -9007199254740991–9007199254740991
taxMinor: integer // -9007199254740991–9007199254740991
grossMinor: integer // -9007199254740991–9007199254740991
}
| null
nextChargeAt: string | null
endsAt: string | null
status: "active" | "ending" | "paused" | "past_due" | "trialing" | "canceled"
channel: "stripe_auto" | "holded" | "manual" | "stripe" | null
startedAt: string | null
lines: Array<{
key: string
title: string
quantity: number
unit: string
unitNetMinor: integer | null
netMinor: integer | null
}>
charges: Array<{
orderId: string // uuid
periodStart: string | null
periodEnd: string | null
grossMinor: integer // -9007199254740991–9007199254740991
state: "paid" | "due" | "overdue" | "processing" | "scheduled" | "refunded"
}>
}
paymentMethod: {
kind: "card" | "sepa_debit" | "other"
brand: string | null
last4: string | null
wallet: string | null
}
| null
}What the brand uses of its plan this month: Nödo credits (balance and monthly grant once credits decide, else the share of the month used), voice minutes, people and Library storage against the plan's limits (null limit = unlimited), its latest plan invoices with status and PDF link, and who the invoices are made out to (the brand's own billing account; null when its workspace pays), and who pays (paidBy: the brand, or its workspace for every brand and whether the reader may pay from it), and the billing currency of the payer (currency, EUR, USD, GBP or MXN) plans are shown and charged in, and who collects the plan (provider: stripe, apple, google or manual). When App Store or Google Play holds the paid plan, store gives the store's page to change or cancel it, the renewal date and the price the store last charged: such a plan is never changed through Stripe. graceEndsAt is when a past_due plan stops granting access (null when it is not in grace). includedInWorks counts what the brand's works got this month without using the plan (images and Nödo steps inside a work's own steps, paid by Nömad as part of the work; counts only). For the plan itself use subscriptions.read.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/subscriptions.screen.plan |
| MCP tool | subscriptions_screen_plan |
| Scope | subscriptions.read |
| Minimum role | Billing |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
invoices?: integer // 0–24 · default 3
}Output
{
credits: {
mode: "credits"
available: number
monthly: number | null
resetsAt: string
}
| {
mode: "percent"
usedPercent: number | null
enabled: boolean
resetsAt: string
}
| null
voice: {
usedMinutes: number
includedMinutes: number | null
}
| null
people: {
used: number
included: number | null
}
| null
storage: {
usedMb: number
includedMb: number | null
maxFileMb: number | null
}
invoices: Array<{
id: string
date: string
number: string | null
concept: string
interval: "month" | "year" | null
grossMinor: integer // -9007199254740991–9007199254740991
currency: string
status: "paid" | "open" | "void" | "uncollectible" | "draft"
pdfUrl: string | null
}>
invoicesAvailable: boolean
payer: {
name: string
legalName: string | null
taxId: string | null
email: string | null
address: string | null
}
| null
paidBy: {
kind: "brand"
}
| {
kind: "workspace"
name: string
canPay: boolean
}
currency: string // default "EUR"
provider: "stripe" | "apple" | "google" | "manual" // default "stripe"
store: {
provider: "apple" | "google"
manageUrl: string
storeProductId: string | null
state: "active" | "grace" | "billing_retry" | "paused" | "pending" | "expired" | "revoked" | null
interval: "month" | "year" | null
renewsAt: string | null
autoRenew: boolean | null
price: {
grossMinor: integer // -9007199254740991–9007199254740991
currency: string
chargedAt: string
}
| null
sandbox: boolean
}
| null // default null
graceEndsAt: string | null // default null
includedInWorks: {
images: integer // -9007199254740991–9007199254740991
nodoSteps: integer // -9007199254740991–9007199254740991
works: integer // -9007199254740991–9007199254740991
}
| null // default null
}Every function of the brand's plan from the one plan door (public.plan_access_summary, docs/plans.md): its value (true/false for switches, a number for limits and consumption, -1 = unlimited), what the plan alone gives (planValue), where the value comes from (source: plan, grant, trial or default) and, for exceptions, until when (grantEndsAt). used is only what the door counts itself (consumption recorded per period), so screens show usage from subscriptions.screen.plan. Plan and version: planId, planVersion.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/subscriptions.plan.access |
| MCP tool | subscriptions_plan_access |
| Scope | subscriptions.read |
| Minimum role | Billing |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{}Output
{
planId: string | null
planVersion: integer | null
features: Array<{
key: string
name: string
category: string
kind: "switch" | "limit" | "metered" | null
unit: string | null
reset: "week" | "month" | "year" | null
value: boolean | number | null
planValue: boolean | number | null
used: number
source: "plan" | "grant" | "trial" | "default"
grantEndsAt: string | null
resetsAt: string | null
}>
}The saved payment method of whoever pays for the brand (card brand or debit and last four digits only) and the next automatic service charges with net, VAT and gross, and whether the last one failed or asks to be confirmed (with Stripe's hosted page). canManage: the viewer may change the method (the brand's own payers in the client surface).
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/subscriptions.screen.payment |
| MCP tool | subscriptions_screen_payment |
| Scope | subscriptions.read |
| Minimum role | Billing |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{}Output
{
canManage: boolean
method: {
id: string
methodType: string
}
| null
charges: Array<{
subscriptionId: string
name: string
grossMinor: integer // -9007199254740991–9007199254740991
currency: string
}>
}Updated on January 1, 1970