# Billing & Plans

Decide whether your app charges money. If it does, Foundation handles the hard parts —
subscriptions, payments, invoices, and enforcing what each plan includes — while you keep your own
Stripe account. You set the plans; your app just reads who's on what.

## Configure

The part you decide — set it in the dashboard, the wizard, or by telling your agent. Four steps:

### 1. Does your app charge?

| Choice | What happens |
|---|---|
| **No payments** | Leave billing off — you're done. Skip the rest of this page. |
| **Stripe** | Turn on payments and connect Stripe. Everything below applies. |

### 2. Connect Stripe

Two ways to connect — your Stripe account stays **yours** either way:

| | What it is | Best when |
|---|---|---|
| **Stripe Connect** | You're sent to Stripe, approve, and you're back. No keys to handle. | You'd rather not deal with keys. |
| **API keys** | Paste a scoped publishable + secret key from your account. | You want explicit control. |

> Foundation sets up a webhook in your Stripe account and keeps your plans and prices in sync — automatically.

### 3. Define your plans

For each plan, set a **name**, **price**, **billing interval**, and **what it unlocks**:

| Plan | Price | Includes |
|---|---|---|
| Free | $0 | 100 API calls/mo · 1 GB storage |
| Pro | $20/mo | 10,000 API calls/mo · 50 GB · AI features |

### 4. Choose how limits are enforced

| Option | Who handles gating |
|---|---|
| **Built-in** | Foundation shows upgrade prompts and enforces limits for you. |
| **Self-managed** | Your app reads the plan + usage and decides what to show ([see below](#use-in-your-app)). |

## Use in your app

You don't have to write any of this — **your agent does**, using the Foundation SDK. Tell it what you
want in plain language; the code is right there too, if you'd rather write it yourself or check the
agent's work.

### Read the plan and usage

**Tell your agent:** "Load the signed-in user's plan and current usage so I can show it on the account page."

```ts
const account = await foundation.account.get()   // current user, including their plan
const usage = await foundation.account.usage()   // metered consumption vs configured limits
const plans = foundation.config.plans            // every plan you defined, from backend config
```

### Gate a feature by plan

**Tell your agent:** "Show an upgrade prompt when someone hits their API limit, and hide AI features for plans that don't include them."

```ts
const usage = await foundation.account.usage()

// Fields on `usage` mirror the capabilities you configured above —
// e.g. an "apiCalls" capability surfaces here as usage.apiCalls.
if (usage.apiCalls.used >= usage.apiCalls.limit) {
  showUpgradePrompt()
}

// Hide what the plan doesn't include — read it from config, don't hard-code tiers:
if (!foundation.config.features.aiFeatures) {
  // this plan doesn't unlock AI — don't render the AI panel
}
```

### Upgrade prompts

**Tell your agent:** "Use Foundation's built-in upgrade prompts" — or "build a custom upgrade screen from the plan and usage data."

- **Built-in gating** — Foundation renders the limit and upgrade UI automatically. Nothing to wire up.
- **Custom** — your agent drives prompts off the plan and usage data above.

Full method signatures: [SDK reference](/api/sdk).

## Reference

- SDK methods used here: `foundation.account.get()`, `foundation.account.usage()`,
  `foundation.config.plans`, `foundation.config.features` — see the
  [SDK reference](/api/sdk)
- [Roles & Scopes](/platform/roles) for per-permission gating
- [MCP & API Overview](/api/overview)
