~/simple-stack $ ./launch

Sell your API, metered by credits.

bash — 80×12
# Bearer-token keys, rate limits, and a per-call credit cost, managed from a left-sidebar member app — billing, auth and a dedicated admin app already wired, on plain PHP and SQLite.
$ composer install && php scripts/install.php
✓ database created · migrations applied
$ php -S 127.0.0.1:8000 -t public router.php
✓ live — start charging
Developer API

One bearer token. A clean 200.

Bearer-key auth, per-call credits and rate limits that just work. Watch a request go out and a response come back — no SDK required.

  • Scoped keys, instant revoke
  • Per-call credit metering
  • Rate-limit headers on every response
SHIP THE API, NOT THE PLUMBING

Bearer keys, metered and rate-limited on day one.

Users mint API keys, hit your endpoints with a token, and you meter every call. A working notes JSON API ships as the example you clone into your own routes.

Peppered key hashes, shown once

Keys are ss_ plus 48 hex chars. Only an HMAC-SHA256 hash and a 12-char prefix touch the database; the raw token is shown once at creation and never again. A leaked DB hands an attacker nothing usable.

Bearer auth on every route

Send Authorization: Bearer ss_... or an X-API-Key header. require_api_user() resolves the key to its owner and plan; a bad token gets a clean 401. The same handler serves browser sessions and API keys, so you write each endpoint once.

Per-key rate limits, 429 + Retry-After

A fixed-window limiter in SQLite caps each key at 300 requests per 60s out of the box (one env var to change). Over the line returns 429 with a Retry-After header and a retry_after field in the body.

Credits priced per call

Plans grant credits per billing period (25 free, up to 2,000 on Scale) and each action spends from the same ledger. Set a different cost per endpoint in app/subscriptions.php.

Self-serve key management

Users create, name, list and revoke their own keys from the member sidebar app, up to ten active each. last_used_at is stamped on every call, and a superadmin can revoke any key from the separate admin app at /admin.

A real /v1 REST API to clone

A versioned REST API mounted at /v1: GET /v1/me and GET /v1/usage return the key's account, plan and live credit balance, and GET/POST/PATCH/DELETE /v1/notes is a complete, scoped-per-user CRUD resource. Data comes back as { "data": ... } with real status codes (200/201/204/401/404/422/429) and paginated lists. Delete the notes logic, keep the shape, and drop in your own resource.

One request, fully metered

A real call: authed, throttled, billed, answered.

Send a Bearer key to a notes endpoint and the same short path runs every time — resolve the key, count the window, charge a credit, return your JSON.

api.yoursite.com/api.php
# POST a note as one of your API users.
# The ss_ key is shown once at creation.
curl -X POST https://api.yoursite.com/api.php \
  -H "Authorization: Bearer ss_a1f3...8e2d" \
  -d action=create_note \
  -d title="Shipped v1" -d status=open
# 200 OK  ·  X-RateLimit: 41/300 in this 60s window
{ "ok": true, "cost": 1, "balance_after": 1974,
  "note": { "id": 5012, "status": "open" } }
Auth, throttle, bill

Wired before you write a line — by the numbers

Every figure here is how the metering actually works, not a sales chart.

300 requests per 60s window per key, out of the box — one env var to change
1 credit charged per metered /v1/notes write, with a different cost settable per endpoint
10 active keys a user can mint, name, and revoke themselves from the sidebar member app — and an admin can revoke from the admin app
0 raw keys stored — only an HMAC-SHA256 hash and a 12-char prefix
Keep the infrastructure small. Make the product yours.
This store and its demos use the same PHP and SQLite foundation included in your download.
1 SQLite database
web_build_stepnone
source_codeincluded
hostingyour own server
database_modeSQLite WAL
Superadmin, not a spreadsheet

A real admin console — have a poke around.

Every install ships with this. Search users, replay webhooks, inspect billing and revoke keys — server-rendered, access-gated, no second app.

app.yoursaas.com/admin superadmin
MRR£4,820▲ 12%
Active subs138▲ 6
Credits today29,400spent
Signups · 7d52▲ 18%
UserPlanStatusJoined
ada@example.comProactive2d ago
grace@example.comScaleactive5d ago
linus@example.comStarterpast due3w ago
margaret@example.comProactive1mo ago
blocked@example.comFreeblocked1mo ago
processedinvoice.paidevt_1Q8x…a3
processedcustomer.subscription.updatedevt_1Q8w…f1
processedcheckout.session.completedevt_1Q8w…7c
retryinginvoice.payment_failedevt_1Q8v…02
refundedcharge.refundedevt_1Q8u…9d
curl -H "Authorization: Bearer ss_live_••••" \
     https://app.yoursaas.com/api.php?resource=notes

{
  "ok": true,
  "data": [ "note_18f2", "note_18f9" ],
  "rate_limit": "58/60",
  "credits_left": 1840
}
From download to charging cards

Preview locally. Connect services. Launch.

01

Unzip & copy

copy a template folder

02

Install & connect

composer install · Stripe + SES

03

Ask your agent

rebrand · plans · run doctor

04

Deploy & charge

NGINX + PHP-FPM · take cards

Try the local app before configuring billing or email. Provider approval and deployment take additional time.

Pricing you control

Tiers, access levels and credits from one config file.

Define plans in app/subscriptions.php, attach Stripe price IDs, and the checkout flow stays generic across every project.

Included

Free

£0

Default access for new users and trial accounts.

Access 025 starter credits
Subscription

Starter

$19/mo

For a small paid SaaS tier.

Access 10100 credits/mo
Subscription

Pro

$49/mo

For heavier usage and premium features.

Access 20500 credits/mo
Subscription

Scale

$149/mo

For power users and high-credit products.

Access 302,000 credits/mo
Questions

The honest FAQ.

Get started

You’re already inside.

This is a live, fully interactive demo — explore every screen. Nothing you do is saved and no payments are real.

Get Simple Stack Launch offer · £49