> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pocketsflow.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Plans and limits

> What each Pocketsflow plan includes, the platform fee per plan, yearly billing, feature keys, and how to handle a FEATURE_LOCKED error in the API.

Every Pocketsflow account can sell from day one. Plans add growth features
(custom domains, upsells, abandoned checkout recovery, affiliates and more),
raise the newsletter limits, add team seats and, on the Volume plans, lower the
platform fee.

Selling never needs a paid plan: products, checkout, payouts, discount codes,
exports, the API, webhooks, MCP and Zapier work on every plan.

## Plans

| Plan | Plan id | Monthly | Yearly | Platform fee | Subscribers | Emails / month | Seats |
| - | - | -: | -: | -: | -: | -: | -: |
| Free | `free` | \$0 | \$0 | 2% | 1,000 | Test sends only | 1 |
| Starter | `tier1` | \$15 | \$150 | 2% | 3,000 | 10,000 | 1 |
| Growth | `tier2` | \$49 | \$490 | 2% | 10,000 | 40,000 | 5 |
| Pro | `tier3` | \$119 | \$1,190 | 2% | 25,000 | 100,000 | 15 |
| Scale | `tier4` | \$299 | \$2,990 | 2% | 75,000 | 300,000 | 50 |
| Volume | `volume` | \$500 | \$5,000 | 1% | 75,000 | 300,000 | Unlimited |
| Volume Max | `volume_max` | \$799 | \$7,990 | 0.5% | 75,000 | 300,000 | Unlimited |
| Enterprise | `enterprise` | Contact us | Contact us | 2% | Uncapped | Uncapped | Unlimited |

Each plan includes everything in the plans above it. The plan ids are what the
API returns; the names are what the dashboard shows.

<Note>
  The platform fee is one part of the transaction cost on each sale (see
  [Pricing and fees](/payments/fees)). On Volume it is 1% and on Volume Max
  0.5% instead of 2%; the rest of the transaction cost does not change. The
  rate is locked on each sale at checkout, so changing plan never rewrites
  past orders.
</Note>

### Yearly billing

Every paid plan can be billed monthly or yearly. Yearly costs ten times the
monthly price, so two months are free. Pick the interval on the billing page
(**Profile → Billing**); the API reports it as `billingInterval` (`month` or
`year`).

### When a paid plan ends

A canceled plan keeps its features until the end of the period already paid.
After that the account is on Free: features that need a plan stop working on
your buyer pages (a custom domain sends buyers to your Pocketsflow subdomain,
ad pixels stop loading, recovery emails stop), but nothing is deleted.
Upgrading again brings everything back as it was.

## Feature keys

The API names each plan feature with a key. These are the features available
today and the cheapest plan that includes each one:

| Feature key | Plan | What it gates | API |
| - | - | - | - |
| `customDomains` | Starter | Connecting your own domain | Dashboard only |
| `premiumTemplates` | Starter | Premium store templates | `POST` / `PUT /creator-pages` with a premium `themeV2.templateId` |
| `adPixels` | Starter | Ad tracking pixels on your buyer pages | `POST /users/update` (pixel fields) |
| `upsells` | Growth | Checkout upsells (order bumps) | `POST /upsells`, `POST /upsells/{id}` |
| `abandonedCheckout` | Growth | Recovery email to buyers who left checkout | `PATCH /products/{id}/abandoned-checkout` |
| `affiliates` | Growth | Your affiliate program | Dashboard only |

`GET /users/entitlements` returns one entry for **every** feature key,
including features that are on the way (for example `trackedLinks`, `teams`,
`memberships`, `lowerFee`). New keys appear as features ship, so treat
unknown keys as "not needed by my integration" rather than as an error.

Only turning a feature **on** is checked. Reading, turning a feature off and
deleting are always allowed, so an account that moves to a smaller plan can
always tidy up.

<Note>
  Plan limits on the six features above are being rolled out gradually. Until
  they apply, `enforced` is `false` and those features stay open to every
  account (`reason: "not_enforced"`); accounts that already used them keep
  them for a grace period (`reason: "grandfathered"`). Features added from now
  on are checked from day one. Always read `allowed` rather than comparing
  plans yourself.
</Note>

## Check what an account can use

Call `GET /users/entitlements` with the account's API key before you use a paid
feature:

```bash theme={"system"}
curl https://api.pocketsflow.com/users/entitlements \
  -H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxxxxxx"
```

```json theme={"system"}
{
  "plan": "tier1",
  "planName": "Starter",
  "billingInterval": "year",
  "feeRate": 0.02,
  "seats": 1,
  "enforced": true,
  "features": {
    "customDomains": { "allowed": true, "requiredPlan": "tier1", "requiredPlanName": "Starter", "reason": "plan", "grandfatheredUntil": null },
    "upsells": { "allowed": false, "requiredPlan": "tier2", "requiredPlanName": "Growth", "reason": "locked", "grandfatheredUntil": null }
  }
}
```

| Field | Meaning |
| - | - |
| `plan` | The plan that applies right now. A paid plan that has ended reads `free`. |
| `feeRate` | Platform fee on new sales, as a proportion (`0.02` = 2%). |
| `seats` | Team seats included; `null` means unlimited. |
| `enforced` | Whether plan limits apply to features that existed before plans did. |
| `features.<key>.allowed` | Whether you can turn the feature on now. |
| `features.<key>.reason` | `plan` (included), `grandfathered` (kept until `grandfatheredUntil`), `not_enforced` (open to everyone for now), or `locked` (needs an upgrade). |

The public plans catalogue (prices, fees, caps, seats and the feature keys of
each plan) needs no API key:

```bash theme={"system"}
curl https://api.pocketsflow.com/users/billing-tiers
```

<Note>
  Plans are bought and changed in the dashboard only, at
  [app.pocketsflow.com/profile/billing](https://app.pocketsflow.com/profile/billing).
  The API never charges an account.
</Note>

## The FEATURE\_LOCKED error

A request that would turn on a feature the account's plan does not include
answers `403` with this body. Nothing is saved.

```json theme={"system"}
{
  "error": "FEATURE_LOCKED",
  "code": "FEATURE_LOCKED",
  "upgradeRequired": true,
  "message": "This feature is part of a higher plan. Please upgrade your plan to use it.",
  "details": {
    "feature": "upsells",
    "currentPlan": "free",
    "requiredPlan": "tier2",
    "requiredPlanName": "Growth",
    "requiredPlanPrice": 49,
    "upgradeRequired": true
  }
}
```

How to handle it:

1. Do not retry. The same request fails until the plan changes.
2. Tell the creator which plan they need (`details.requiredPlanName`) and send
   them to [app.pocketsflow.com/profile/billing](https://app.pocketsflow.com/profile/billing).
3. Branch on `code`, not on `message`: the message can change and is
   translated in the dashboard.

```ts theme={"system"}
const res = await fetch("https://api.pocketsflow.com/upsells", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.POCKETSFLOW_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    mainProductIds: ["665f1c2a9b3e4a0012ab34cd"],
    upsellProductId: "665f1c2a9b3e4a0012ab34ce",
    upsellPrice: 19,
  }),
});

if (res.status === 403) {
  const body = await res.json();
  if (body.code === "FEATURE_LOCKED") {
    // Ask the creator to upgrade; do not retry.
    console.log(
      `Upsells need the ${body.details.requiredPlanName} plan: ` +
        "https://app.pocketsflow.com/profile/billing",
    );
  }
}
```

Other `403` answers, such as `COUNTRY_RESTRICTED` or `ACCOUNT_BLOCKED`, are
about the account, not its plan.

## Platform fee on orders

Every order returns the platform fee it was charged and the rate behind it, so
you can reconcile sales on the Volume plans:

| Field | Meaning |
| - | - |
| `platformFee` | The platform fee locked at checkout, in the order currency. |
| `platformFeeRate` | The rate it was charged at: `0.02`, `0.01` (Volume) or `0.005` (Volume Max). `null` on legacy sales with no platform line. |
| `platformFeeSource` | `stored` (locked at checkout), `estimated` (older sale, 2% estimate), or `none`. |

See [`GET /orders`](/api-reference/endpoints#orders).

## AI agents (MCP)

The [MCP server](/api-reference/mcp-server) exposes the same rules as tools:
`get_entitlements` (and its alias `get_plan`), `list_plans`,
`get_abandoned_checkout_summary` and `set_abandoned_checkout`. Agents are told
to call `get_entitlements` before using a paid feature, and a
`FEATURE_LOCKED` tool error carries the plan to upgrade to and the billing
link.

## Related topics

* [Pricing and fees](/payments/fees)
* [REST endpoint reference](/api-reference/endpoints#plans)
* [Node.js SDK](/api-reference/sdk#plans-and-entitlements)
* [Upsells and bundles](/selling/upsells-and-bundles)
* [Custom domains](/selling/custom-domains)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.