verification
use it
# add to stunt.yaml
services:
revenuecat:
adapter: embedded:revenuecat-style
# then
$ stunt upThe embedded: source extracts this adapter from the binary — no git clone, fully offline.
how to mock the RevenueCat API locally
Install stunt, paste the service block above into stunt.yaml, run stunt up — then point your client at localhost instead of RevenueCat API. It works offline, keeps state across requests and restarts, and every response is synthetic: the route shapes, status codes, pagination, and webhook delivery follow the real RevenueCat API v1 surface — the data is fake, the behavior is real.
backing stores
subscribersentitlements
api surface (7)
generated from the adapter manifest — exactly what boots, nothing more · covers 26% of the real API's 15 routes (derived from spec RevenueCat API v1 reference @ 1.0)
7 routes
POST/v1/receipts
POST/v1/webhooks
GET/v1/webhooks
POST/v1/subscribers/{app_user_id}/subscriptions/{product_id}/revoke
GET/v1/subscribers/{app_user_id}
POST/v1/subscribers/{app_user_id}
DELETE/v1/subscribers/{app_user_id}
VM-verified behaviors (8)
- ✓a missing or unknown key is a 401 {code, message} envelope
- ✓the public pk_ SDK key passes subscriber reads and receipt posts but is 401 on restricted writes
- ✓GET subscriber is get-or-create and answers in the v1 CustomerInfo envelope
- ✓receipt validation mirrors the real 400 order: app_user_id, platform, fetch_token, bad token
- ✓an ios receipt grants the pro entitlement with real trial math, and renewals stack
- ✓a google-play dict receipt feeds the product and lands in non_subscriptions
- ✓revoke lapses a live subscription; delete and the 404 envelopes
- ✓expiry is derived on read: a lapsed trial drops its entitlement
Not implemented (5)
- No attribution endpoint (POST /v1/subscribers/{id}/attribution)
- No offers API (promotional offer creation)
- No v2 webhooks — only unsigned v1 events
- Only ios and android platforms — no amazon, stripe, or web billing
- No v2 REST surface (customers, subscriptions, entitlements)
Differs from the real API (5)
- fetch_token prefixed with invalid is the deterministic bad-receipt 400 path
- Subscription expiry is derive-on-read; first read past it fires EXPIRATION
- POST /v1/subscribers accepts _expires_at seeding to drive EXPIRATION in tests
- pk_ public keys are simulator convention; real RC public keys are appl_/goog_-prefixed
- REST webhook registration does not exist in real RC v1 (dashboard-configured)
want more of the RevenueCat API surface? adapters are YAML + Starlark — the authoring guide covers adding routes, fixtures, and state machines. Open an issue for anything big first, or just file a PR — merged routes ship in the next release.