Farther ShoreDocs
Go to Farther Shore
Design and operate commerce
Entitlements vs economics
Cohorts & releases
Plan transitions
Connect Stripe
Subscriptions & usage
Plan changes
Billing strategies
Pricing catalogs
Funding & allowances
Economic agreements
Commercial releases
Bill preview API
Usage & billing policy
Ledger & settlement
Subscription + overage
Freemium that converts
OutcomePrerequisitesDefine the plans and gateValidate and launchVerifyCommon failures and recoveryNext stepsAgent prompt
Add a trial
Add a spend cap
Change a price
Prepaid wallet
Meter AI tokens
commerce HTTP contracts
Status
Docs/Cookbook/Freemium that converts

Freemium that converts

Offer a limited free plan and a paid plan that unlocks more usage and route access.

Outcome

Give Quillby a limited Free plan and a $19/month Pro plan. Free users can try the product; Pro raises the limit and unlocks Brand Voice.

Use freemium when a bounded free experience helps customers understand the product before checkout.

Prerequisites

  • A frontend business and authenticated CLI
  • A reachable HTTPS origin for POST /v1/generate
  • A usage meter or resource that can enforce the free boundary

Define the plans and gate

ts
import * as fs from "@farthershore/business";

const requests = fs.requests();
const words = fs.measure("words_generated");
const wordUsage = fs.meter("word_usage", { measures: [words] });
const wordPricing = fs.pricing("word_usage", {
  meter: wordUsage,
  catalog: [fs.rate.per(1000, fs.money.usd(0.02))],
});
const api = fs.backend("api", {
  transport: { mode: "direct" },
  default: true,
});
const generate = fs.route("/v1/generate", {
  post: { backend: api, costs: [requests.fixed(1)], reports: [wordUsage] },
});
const brandVoice = fs.route("/v1/brand-voice", {
  post: { backend: api, costs: [requests.fixed(1)] },
});
fs.meterRoutes("generate-words", generate, {
  reports: [wordUsage],
  maxOutputUnits: words.atMost(2_000),
});

fs.plan("free", {
  kind: fs.plan.kind.free,
  grants: [generate],
  limits: [requests.perMinute(30)],
});

fs.plan("pro", {
  kind: fs.plan.kind.hybrid,
  price: fs.money.usd(19).monthly(),
  usagePricing: wordPricing.current(),
  funding: { buckets: [fs.included(fs.money.usd(10))] },
  spendPolicy: {
    onExhaustion: fs.exhaustion.overage(wordPricing.current()),
  },
  grants: [generate, brandVoice],
  limits: [requests.perMinute(300)],
});

export default fs.business();

The origin handler for POST /v1/generate must report real usage:

ts
await ctx.report({
  meter: "words_generated",
  values: { words_generated: generatedWordCount },
});

Direct route grants control access. Free is bounded structurally (30 requests/minute); Pro includes $10 of rated words each month — 500,000 words at $0.02 per thousand — and rates anything past that as overage on the same catalog. Subscribers see the allowance and amount due through the bill preview, never a per-word price they must compute.

Validate and launch

bash
farthershore build --format json
farthershore validate --format json
git add business/ && git commit -m "add Free and Pro" && git push
farthershore backend create quillby \
  --name "Quillby API" \
  --slug api \
  --transport direct \
  --origin-url https://api.example.com \
  --default \
  --idempotency-key <persisted-backend-create-attempt-key> \
  --format json
farthershore business publish quillby --dry-run --format json
# After explicit approval of the first draft activation:
farthershore business publish quillby --format json --idempotency-key <persisted-business-publish-attempt-key>
farthershore business status quillby --format json

Poll until status: "ACTIVE" and live: true.

Verify

bash
farthershore backend create quillby \
  --env preview \
  --name "Quillby API (preview)" \
  --slug api \
  --transport direct \
  --origin-url https://preview-api.example.com \
  --default \
  --idempotency-key <persisted-backend-create-attempt-key> \
  --format json
farthershore persona bootstrap quillby --env preview --plan free --format json --idempotency-key <persisted-persona-bootstrap-attempt-key>
PREVIEW_GATEWAY="https://preview.example.com" # replace with preview hostname
FSK_TEST_KEY="fsk_test_..."                   # replace with bootstrap output
curl -i "$PREVIEW_GATEWAY/v1/generate" \
  -H "x-api-key: $FSK_TEST_KEY"
farthershore usage summary quillby --format json
  • The Free persona activates without Stripe checkout.
  • Repeated calls increase words_generated; a burst past 30/minute is denied rate_limited.
  • Brand Voice is hidden or upsold for Free.
  • Bootstrap a --plan pro persona and confirm Brand Voice is unlocked; the bill preview shows the included allowance draining and overage after it.
  • The managed usage card matches the usage summary.

Common failures and recovery

SymptomFix
Free plan fails validationA free plan takes no economic controls; bound it with limits.
Publish dry run is refusedFollow the stable prerequisite hint, resolve it, and preview again.
Paid route leaks to FreeGrant the backend route only to the paid plan; UI hiding is presentation.
Usage never increasesReport the exact declared meter key through an attested request-bound channel.

Fix the contract in business/, build, and publish forward. A new release reaches new subscriptions; existing subscribers keep their recurring-price pin and, under wordPricing.current(), follow catalog changes forward.

Next steps

  • Metered routes
  • Frontend route-aware UI
  • Plan changes — including the downgrade direction: a subscriber can move from Pro back to Free from the portal, and that move lands at the end of their current billing period.

Agent prompt

Add Free and Pro plans to Quillby. Free is kind free with an enforced rate
limit. Pro is kind hybrid at $19/month with a $10 included word allowance,
overage on the same catalog, and grants brand-voice. Add managed
usage, plans, and upsell UI; build and validate in preview; then verify Free
denial at limit and Pro access. Show the production publish dry run and ask
before publishing production.
PreviousSubscription + overageNextAdd a trial

On this page

OutcomePrerequisitesDefine the plans and gateValidate and launchVerifyCommon failures and recoveryNext stepsAgent prompt