Quickstart
Run the whole stack on your machine in a few minutes, sign in to the demo workspace, and read an account's access from the API.
Before you start
- Node 22 or newer. The Workflows service in
workflows/needs Node 24, but you don't need it to run the rest locally. - pnpm 9. Running
corepack enablepicks up the version pinned inpackage.json. - Docker, for Postgres and the API. You don't need Bun or Postgres installed.
Run it locally
Clone and install
git clone https://github.com/impactvelocity/offer-sdk cd offer-sdk pnpm installStart Postgres and the API
This runs Postgres 17 and the API in watch mode on
http://localhost:6767. Migrations run on boot. The API's interactive reference is athttp://localhost:6767/docs.pnpm dev:apiStart the dashboard
In a second terminal. Each service has its own script, listed in the table below. Use these rather than the root
pnpm dev, which doesn't start the API and also starts the Workflows service, which needs the Render CLI and Node 24.pnpm dev:appOpen
http://localhost:6768. In development the dashboard already points at the local API with its development admin key, so neither side needs a.envfile. On a fresh database it opens on/setup: the first account you create is the admin, and sign-up closes after that.Open the demo workspace
Press Explore the demo workspace on the setup or sign-in page. The first time, the dashboard builds two sample apps with six months of usage, which takes a few seconds. After that you can also sign in with
demo@offersdk.devanddemo-password. The demo login is read-only and the Agent is off for it, so sign in as your admin to make changes or use the Agent. Runpnpm seed:demo --resetto start the demo over.
| Service | URL | Started by |
|---|---|---|
| API | http://localhost:6767 | pnpm dev:api |
| Dashboard | http://localhost:6768 | pnpm dev:app |
Check an account's access
Create your own app in the dashboard, add an entitlement and a plan, then copy the app id and its secret key from Developers → API keys. Every account your app has is a record in the API, keyed by an id you choose (usually your user or team id).
curl -X POST http://localhost:6767/apps/$APP_ID/namespaces \
-H "Authorization: Bearer $OFFER_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{ "id": "user_42", "name": "Ada", "plan": "pro" }'Then ask what that account can do. full-plan returns the plan with every entitlement already resolved, including current usage and whether the account can use it right now.
curl http://localhost:6767/apps/$APP_ID/namespaces/user_42/full-plan \
-H "Authorization: Bearer $OFFER_SECRET_KEY"{
"plan": { "id": "pro", "name": "Pro", "description": null, "isFree": false, "meta": {}, "privateMetaKeys": [] },
"incentive": null,
"offer": null,
"addons": [],
"entitlements": [
{ "id": "posts", "feature": "posts", "name": "Posts", "type": "usage", "usage": 2, "max": 100, "left": 98, "can": true },
{ "id": "pin_posts", "feature": "pin_posts", "name": "Pin posts", "type": "boolean", "usage": 0, "max": null, "left": null, "can": true }
]
}When the account uses a metered feature, record it. The API answers with the new count, or with 402 and an upgrade offer if the entitlement blocks usage past its limit.
curl -X POST http://localhost:6767/apps/$APP_ID/namespaces/user_42/usage/posts/add \
-H "Authorization: Bearer $OFFER_SECRET_KEY"pub_…), which can only read plans and pricing, add usage and run checkouts. Authentication lists what each key can do.Optional settings
Everything above works with no configuration. Add these when you want the AI features, or to work without Docker.
| Variable | Where | What it turns on |
|---|---|---|
| ANTHROPIC_API_KEY | offer-app/.env.local | The Agent page in the dashboard. |
| ANTHROPIC_API_KEY | api/.env | Dynamic save offers in cancel flows. Without it, the flow shows its static offer. |
| OFFER_API_URL=mock | offer-app/.env.local | Runs the dashboard on an in-memory mock API with a demo workspace, no Docker needed. Offers and cancel flows are hidden in this mode. |
Next steps
- Learn the records you just touched in Core concepts.
- Gate features in React with the React SDK.
- Put it online with Deploy on Render.