Skip to main content
By the end of this guide your backend will be able to:
  1. Authenticate as a machine client (server-to-server)
  2. Provision an end-user in your app’s tenant
  3. Issue a signed, scoped JWT for that user
  4. Gate a request on the user’s entitlement balance
  5. Query usage to confirm metering is working
Time: ~10 minutes
What you need: curl, jq, and credentials from your PymtHouse app registration

Prerequisites

You need three values from your registered developer app. If you don’t have these yet, ask your platform admin or check your app’s settings page.
For local development, BASE_URL is http://localhost:3001. Your M2M and public client IDs are created automatically during app setup.

Step 1 — Authenticate your backend

Exchange your M2M credentials for a short-lived machine token. This token authorizes Builder API calls on behalf of your app.
You’ll use this token for the next two steps. Machine tokens are short-lived — acquire a fresh one per request batch rather than persisting them.
scope=users:write users:token is the minimum needed for this guide. users:write lets you provision users; users:token lets you mint JWTs for them.

Step 2 — Provision a user

Register a user in your app’s tenant. Use your own identifier — PymtHouse calls this externalUserId. This call is idempotent: running it again updates the existing record instead of creating a duplicate.
A 200 response confirms the user exists. PymtHouse automatically subscribes new users to the app’s Starter plan — they start with a default $5.00 USD allowance for AI job requests.

Step 3 — Issue a signed user JWT

Mint a short-lived access token scoped to this user. This is what you’ll pass to AI services as proof that this user is authorized to make a request.
This JWT has:
  • sub — the PymtHouse user record id
  • azp / client_id — your public app_… client id
  • scopesign:job (gates this user to AI signing requests)
Pass it as Authorization: Bearer ${USER_JWT} to any PymtHouse-integrated service.

Step 4 — Check the user’s entitlement balance

Before dispatching an AI request, verify the user has remaining balance. This is the access gate.
Response:
hasAccess: true means the user can proceed. Gate your request on this field. When the balance is exhausted, hasAccess becomes false and the signer will reject requests with trial_credits_exhausted.

Step 5 — Query usage

After your first AI request goes through, verify it was metered:
Usage appears here after the OpenMeter collector ingests the signed-ticket event from the AI backend. There is a short async delay (typically under 30 seconds in production).

What’s next

You have the core flow working. Now wire it into your product:

Integration patterns

Full working examples: SaaS app, CLI device flow, and metered billing. Pick the one that matches your architecture.

Builder SDK

Replace the curl calls with one TypeScript client. mintSignerSessionForExternalUser handles upsert + mint + exchange in one call.

Device flow

Add browser-based login for users authenticating from a CLI or terminal.

Billing setup

Connect Stripe, configure plans, and let users pay for usage beyond the Starter allowance.

SDK equivalent

The entire quickstart in TypeScript using the Builder SDK. See Builder SDK for install instructions and the full method reference.