Postman

The Offer API ships a Postman collection with a request for every route. Import it, run the Quickstart folder, and every other request has an app, keys and ids to work with.

Download

  • Collection (offer-api.postman_collection.json): every route in folders by resource, with example bodies, the right key per request, and scripts that save ids and keys as you go. It points at the local API by default.
  • Environment (offer-api.postman_environment.json): only needed for a deployed API. It overrides baseUrl and adminKey.

Both files live in api/postman/ in the repo. Postman's Import also accepts the download links as a URL.

Get started

  1. Import the collection

    In Postman, choose Import and drop in offer-api.postman_collection.json. It shows up as Offer API.

  2. Point it at your API

    For a local API (pnpm dev:api) there is nothing to set: baseUrl starts as http://localhost:6767 and adminKey as the local dev-admin-key.

    For a deployed API, import offer-api.postman_environment.json, select Offer API (deployed) in the environment menu, and set baseUrl to your API's URL and adminKey to its ADMIN_API_KEY. Quickstart creates its app with the admin key, so it needs both.

  3. Run Quickstart

    Open the Quickstart folder and send its requests in order, or press Run on the folder to send them all. Create an app uses the admin key and saves the new app's id, secret key and publishable key into the collection variables. The rest creates a posts entitlement, a Free plan with 3 posts and a Pro plan with 100, an account called user_42, one recorded post, and an upgrade to Pro.

  4. Use the other folders

    Every other request now has an app and data to act on. Requests that create something save its id, so the next request in the folder uses it.

Already have an app? Skip Quickstart and set appId, secretKey and publicKey in the collection's Variables tab. The keys are under Developers → API keys in the dashboard.

Folders

Quickstart
Creates an app and a small catalog, then reads and changes an account. Run it first.
Service
Health check, the OpenAPI document, the reference page and the webhook event catalog. No key.
Apps
Read and update the app, and rotate its keys. Rotating saves the new key.
Entitlements, Add-ons, Incentives, Plans
The catalog: create, read and update records, and attach entitlements and add-ons to plans and incentives.
Accounts, Usage
Search and change accounts, mint account tokens, read access, and move usage counters.
Offers, Checkouts, Subscriptions, PayPal
Selling through PayPal. These need a PayPal sandbox connection: set paypalClientId and paypalClientSecret, then send PayPal → Connect PayPal.
Cancel flows, Cancel sessions
Create a flow from the template, preview its save offer, and walk a session through it with an account token.
Analytics, Webhooks and events
Usage reports, webhook endpoints, test sends, delivery logs and the event log.
MCP server
Calls the app's MCP server with the secret key: initialize, list and call tools, read a resource, get a prompt. Also the dashboard's settings, connections and call log routes, with the admin key.
MCP OAuth
The sign-in an MCP client goes through: discovery, client registration, authorize, approval, the PKCE code exchange, a tool list with the access token, refresh and deny. The admin-key approval stands in for the dashboard's consent page.
Admin
Workspaces, history import, pauses and agent threads. These use the admin key.
Clean up
Deletes what the other folders created, ending with the app. Run it last, or skip it to keep the data.

Keys

The collection sends the app's secret key by default. Requests that a browser or another service would make send a different key, set on their Authorization tab:

VariableKeyUsed by
secretKeykey_…Every request that doesn't say otherwise.
publicKeypub_…Browser routes: plan reads, usage, pricing, public offers and checkouts.
accountTokenact_…Cancel sessions. Send Accounts → Mint an account token first; tokens last an hour.
adminKeyADMIN_API_KEYThe Admin folder, the MCP dashboard and approval routes, and some of Clean up.
mcpAccessTokenmcp_at_…The MCP server, as an OAuth client. Saved by MCP OAuth → Exchange the code; lasts an hour.

Each request's description says which other keys it accepts. Authentication explains what each key can do.

The variables hold real keys after a run. Clear secretKey, publicKey, accountToken, mcpAccessToken, mcpRefreshToken and adminKey before you export or share the collection.

Variables

VariableStarts asSet by
baseUrlhttp://localhost:6767You, or the environment.
adminKeydev-admin-keyYou, or the environment.
appId, secretKey, publicKeyEmptyQuickstart → Create an app.
accountIduser_42You. The account most requests act on.
freePlanId, planIdfree, proYou.
entitlementId, addonId, incentiveIdposts, priority_support, launch_boostYou.
offerId, flowIdlaunch, defaultYou. Creating the cancel flow saves its id.
checkoutId, sessionId, reportId, webhookId, deliveryIdEmptyThe request that creates each one.
accountTokenEmptyAccounts → Mint an account token.
webhookUrlhttps://example.com/offer-webhooksYou. Point it at a receiver you can watch, such as webhook.site.
paypalClientId, paypalClientSecretEmptyYou, from a PayPal sandbox REST app.
orgId, userId, threadIdpostman_workspace, postman_user, postman_threadYou. Used by the Admin and MCP OAuth folders.
mcpSessionId, mcpConnectionIdEmptyThe MCP server folder.
oauthRedirectUri, oauthCodeVerifier, oauthCodeChallengeA local callback and a fixed PKCE pairYou. The MCP OAuth folder uses them as is.
oauthClientId, oauthRequestId, oauthCodeEmptyThe MCP OAuth folder, one step at a time.
mcpAccessToken, mcpRefreshTokenEmptyThe MCP OAuth folder's token requests.

Run the whole collection

The folders are ordered so the collection runs top to bottom: Quickstart sets up, the resource folders build on it, and Clean up removes everything. Use Run on the collection in Postman, or Newman, Postman's command-line runner:

npx newman run api/postman/offer-api.postman_collection.json

Every request carries one test: no 5xx. Some requests answer 404 or 409 on purpose in a full run. Requests that create a record Quickstart already made return 409, and without PayPal connected, publishing, checkouts, subscriptions and save offers return 409 too.

Keep it in step with the API

The collection is generated. Requests are defined in api/postman/requests.ts, and the generator reads the API's own route table, so it refuses to build if a route has no request or a request has no route.

cd api
bun run postman
# or, with the API running in Docker
docker compose exec api bun run postman

api/test/postman.test.ts runs the same check in the API's test suite, and also fails when the committed JSON is out of date. Adding a route without a Postman request fails the tests.