Pricing

Three subscription tiers for what Substratal Apps itself charges — the platform’s own customer, in every tier below, is the Application owner (the developer), never their app’s end users.

  1. Who pays whom, again
  2. What “seat” means here
  3. The three tiers
  4. Enforcement
  5. Enterprise tenancy tier options
  6. Why these three, and not something finer-grained
  7. Keeping these numbers honest

Illustrative, proposed numbers — grounded in the real infrastructure costs already established in Deployment Architecture and Tenancy, not a published price list. See Decisions → Platform subscription billing processor for what’s still unconfirmed.

Who pays whom, again

Keep this straight before reading tiers: Decision #4 already resolved that Substratal Apps is not a payment processor for a developer’s own end users — a developer bills their customers however they choose, entirely outside this API. This page is the other, previously-unaddressed direction: what Substratal charges the developer for the platform itself — user accounts, settings, organizations, tenancy, and storage, per Home. Two separate billing relationships, two separate pages; Decision #4 covers the first, this page covers the second.

What “seat” means here

A seat is a distinct User holding an active Entitlement — personal or Organization-granted — to any Application this Tenant owns. Computed directly from existing Entitlement rows; no new tracking primitive. Deliberately provisioned, not activity-based (not “monthly active users”) — a seat count a customer can predict and budget against, consistent with Entitlement already being a persistent on/off state rather than a usage log.

The three tiers

  Starter Team Enterprise
For A single developer (the “single-user consumer” case — this is you, building your first Application; Team is where “3+ Applications” belongs) A company with one or more Organizations under a single Tenant A corporate account at real scale, with infrastructure requirements of its own
Price $0/month $49/month + $6/seat beyond 25 included From $999/month + volume seat pricing + tenancy tier
Applications 1 5 Unlimited
Organizations Not available — see Enforcement Unlimited Unlimited
Seats included 1,000 25 Negotiated (typically 500+)
Tenant tier available shared only shared only Choice of all three — see below
Custom AppRoles Up to 3 Unlimited Unlimited
Webhooks 1 subscription 10 subscriptions Unlimited
Audit log hot-storage window 30 days 1 year Negotiated, Compliance-driven
Support Community / best-effort email Business-hours email Dedicated channel, custom SLA

“Audit log hot-storage window” is how long an Audit Event stays in fast, directly-queryable storage — it is not a retention/deletion period. Every Audit Event is retained indefinitely regardless of plan; see Non-Functional Requirements → Data retention for the cold-storage mechanism that keeps that true without keeping every plan’s hot storage the same size.

Enforcement

Every limit in the table above is checked server-side, at write time, on the Tenant that would own the new resource — independent of whether the calling credential otherwise has permission to make the call, the same “two independent gates” pattern API Keys → Agent keys already uses for restrict_destructive. A platform admin’s applications.manage lets them call POST /v1/applications; it does not let them push a Starter Tenant past its own cap of 1.

Limit Checked on Rejected with
Applications POST /v1/applications — counts existing Applications owned by the same Tenant 409, code: "plan_limit_reached", details: {"resource": "applications", "limit": 1, "current": 1}
Custom AppRoles POST /v1/roles where scope is an application_id — counts existing Roles already defined for that Application 409, code: "plan_limit_reached", details: {"resource": "app_roles", ...}
Webhooks POST /v1/webhooks — counts the calling Application’s (or platform key’s) existing subscriptions 409, code: "plan_limit_reached", details: {"resource": "webhooks", ...}
Organizations Not a count — see below —

“Organizations: Not available” on Starter isn’t a count limit (a Tenant has exactly one owner either way) — it’s that a Starter Tenant’s owner must be a User, never an Organization: check (plan != 'starter' or owner_type = 'user') on tenants, the same database-level pattern already used for isolated/dedicated_region being Enterprise-only — see Database Schema → tenants. An Application’s owner being an Organization auto-provisions that Organization a Tenant on plan: team, never starter, specifically so this constraint is never actually reachable as a runtime error — see Tenancy → What it represents.

Enterprise tenancy tier options

This is the pricing dimension that maps directly onto Tenant.tier — an Enterprise customer picks how their data is physically isolated, and pays accordingly. Nothing new is invented here; these are the exact three tiers Decision #12 already resolved, priced:

Tier What it is Price Why this number
shared Included in the Enterprise base price $0 extra Same infrastructure as every other tenant, logically isolated by Row-Level Security — see Tenancy → Tiers. Most Enterprise customers start here; it’s the volume/SLA terms that justify the Enterprise price, not the infrastructure.
isolated A dedicated Aurora Serverless v2 cluster, same region +$750/month The raw infrastructure add-on is ~$45–55/month (see Deployment Architecture) — the rest of this price is the value of real blast-radius isolation and the operational overhead of running and monitoring a dedicated cluster, not a cost pass-through.
dedicated_region A dedicated cluster in the customer’s chosen AWS region +$1,500/month Roughly double isolated’s surcharge, matching Tenancy → Tiers: “the isolated floor again, in a second region” — plus the compliance value of a genuine data-residency guarantee, the kind Compliance → GDPR data residency conversations actually ask for.

A tier change still goes through the exact process in Tenancy → How a tier change happens today — support-run, scheduled maintenance window, tenants.manage-gated. Pricing doesn’t change that; choosing isolated on this page is the commercial side of the same support conversation, not a self-service toggle.

Why these three, and not something finer-grained

Three tiers is deliberately the whole menu:

  • Starter is free, not just cheap. Growth trajectory’s first horizon — dozens of users, a handful of Applications — sits entirely inside Starter’s limits, and the shared-tier infrastructure cost of serving that is near-zero against the floor already being paid regardless (see Deployment Architecture → Illustrative Tier 0 floor cost). Charging for it would tax exactly the adoption this product needs most right now.
  • Team’s per-seat price is value-based, not cost-plus. The marginal infrastructure cost of one more seat on shared Tier 0 is effectively zero until a Scale-out trigger fires — $6/seat is priced against what Team replaces (weeks of building user/org/settings/tenancy infrastructure, per Home), not against AWS’s bill for that seat.
  • Enterprise is the only tier where infrastructure choice is a pricing lever, because it’s the only tier where a customer’s own requirement (compliance, data residency) drives a real, named infrastructure cost — see Enterprise tenancy tier options above. Below Enterprise, that choice isn’t offered at all, which is itself a deliberate simplification: a Starter or Team customer who needs isolated/dedicated_region has outgrown those tiers by definition.

Keeping these numbers honest

The MCP servers researched alongside this pricing work are the ones that keep it grounded in reality rather than going stale:

  • AWS Pricing MCP Server — verify the per-component cost assumptions in Deployment Architecture’s floor cost table against live AWS pricing before this page’s infrastructure-derived numbers (the isolated/dedicated_region surcharges above) are treated as current.
  • AWS Billing and Cost Management MCP Server — once Tier 0 is live, pull actual spend and compare it against the floor-cost assumptions this page’s margins are built on; its Cost Anomaly Detection integration is also the fastest way to notice an Enterprise isolated Tenant’s real cost has drifted from the ~$45–55/month this page assumes.
  • AWS Labs Postgres MCP Server — per-cluster health/usage data for isolated and dedicated_region Tenants specifically, informing whether a given Enterprise account’s actual resource consumption still matches the tier (and price) it’s on.
  • Stripe’s official MCP server — now that Decision #15 has these prices actually flowing through Stripe Billing (see root DEPLOYMENT.md → Stripe Billing), it’s the direct source for whether the Products/Prices configured in Stripe still match what this page states — the two are meant to be kept in sync by hand, the same relationship Conventions → Machine-readable already describes between this site’s prose and openapi.yaml.

None of these are wired into the product — they’re the tooling recommendation for whoever maintains this page, so the numbers above get revisited against real data rather than left as a one-time guess.


Back to top

Substratal Apps Platform API — living specification. This site is the system of record; see git history for how it has changed over time.

This site uses Just the Docs, a documentation theme for Jekyll.