A pay-as-you-go API
Put a metered, limited, billed gateway in front of an origin API.
Outcome
Sell CronCloud, an API billed per request. Farther Shore authenticates API keys, applies plan limits, meters admitted traffic, and forwards it to your origin.
Use this recipe when customers call your service from their own code. For a hosted web app, use Subscription SaaS.
Prerequisites
- A reachable HTTPS origin
- Authenticated CLI and a managed business repository
- An API-surface business
Define the API
import * as fs from "@farthershore/business";
const requests = fs.requests();
const calls = fs.measure("calls");
const apiUsage = fs.meter("api_usage", { measures: [calls] });
const apiPricing = fs.pricing("api_usage", {
meter: apiUsage,
catalog: [fs.rate.per(1000, fs.money.usd(5))],
});
const api = fs.backend("api", {
transport: { mode: "direct" },
default: true,
});
const listJobs = fs.route("/v1/cron-jobs", {
get: { backend: api, costs: [requests.fixed(1)], reports: [apiUsage] },
});
fs.meterRoutes("cron-jobs-usage", listJobs, { reports: [apiUsage] });
fs.plan("payg", {
kind: fs.plan.kind.usage,
usagePricing: apiPricing.current(),
grants: [listJobs],
limits: [requests.perMinute(600)],
});
export default fs.business();
payg is a usage plan: postpaid, every reported call rated at $5 per
thousand ($0.005 each, exactly) and settled on the invoice. The origin reports
one unit per served call:
await req.fartherShore.report({ meter: "api_usage", values: { calls: 1 } });
Discovery is folder-based. Keep exactly one default-exported fs.business()
result across business/.
Validate and launch
farthershore build --format json
farthershore validate --format json
git add business/ && git commit -m "define CronCloud API" && git push
farthershore backend create croncloud \
--name "CronCloud API" \
--slug api \
--transport direct \
--origin-url https://api.example.com \
--default \
--idempotency-key <persisted-backend-create-attempt-key> \
--format json
farthershore business publish croncloud --dry-run --format json
# After explicit approval of the first draft activation:
farthershore business publish croncloud --format json --idempotency-key <persisted-business-publish-attempt-key>
farthershore business status croncloud --format json
Poll until ACTIVE and live: true. In a preview environment, mint a one-time
test credential and copy the returned fsk_test_* value:
farthershore backend create croncloud \
--env preview \
--name "CronCloud 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 croncloud --env preview --plan payg --format json --idempotency-key <persisted-persona-bootstrap-attempt-key>
Personas are limited to test-strategy environments. See API keys and test personas for preview setup.
Verify
GATEWAY_HOST="https://preview.example.com" # replace with environment hostname
FSK_TEST_KEY="fsk_test_..." # replace with bootstrap output
curl -i "$GATEWAY_HOST/v1/cron-jobs" \
-H "x-api-key: $FSK_TEST_KEY"
farthershore usage summary croncloud --format json
Confirm the request reaches the origin, api_usage increases, the bill
preview's rated total grows by exactly $0.005 per call, and an invalid key is
rejected before origin forwarding.
Common failures and recovery
| Symptom | Fix |
|---|---|
| Gateway returns an origin error | Verify HTTPS reachability, route path, and backend status. |
| Usage stays at zero | Confirm the route matched the declared operation and the origin reports api_usage. |
MANAGED_BY_CODE | Edit business/, build, and push instead of mutating the contract through the API. |
| Valid caller gets 429 | Inspect response limit metadata and the plan's rate ceiling. |
Correct routes, pricing, and limits in business/, then publish forward. A
catalog reprice reaches every current()-bound subscriber from the release's
activation forward; usage already admitted is rated at the old rate.
Next steps
Agent prompt
Define CronCloud as an API business at the supplied HTTPS origin. Add a
`calls` measure on an `api_usage` meter, a pricing catalog at $5 per thousand,
three cron-job routes bound with meterRoutes, a kind-usage plan, and an
enforced rate limit.
Build, validate, push, and verify in preview. Show the production publish dry
run and ask for approval before publishing. Create a safe test identity, call
the gateway, and verify forwarding, rejection of an invalid key, and usage.