Quickstart

What ParityRail does, the eight-step setup, demo mode, and what read-only means.

What ParityRail does

Every payment makes a promise about what a customer can access. ParityRail checks that your app keeps that promise. When it doesn’t, it flags the gap as an access incident — a specific mismatch it found and can help you fix.

It runs one loop, called a fulfillment check — a read-only comparison of what billing promised against what your app grants. Here’s every stage:

StageWhat happens
PromiseEvery billing event defines exactly what access the customer is owed.
CheckA fulfillment check compares that promise against your live app state.
IncidentEach unfulfilled promise is filed as an access incident, with evidence.
RepairA single-row, approval-gated fix with a before/after diff.
VerifyAfter the repair, the customer is re-checked until the promise holds.
LedgerEvery promise, check, incident, and repair lands in the Access Ledger.

Before you start

  • A ParityRail account with a project created — this walkthrough lands you on that project’s onboarding wizard.
  • Admin role on the project. Every connect action (Stripe, database, Clerk) requires admin; a member can view and run the dry run but can’t connect integrations.
  • One billing source (a Stripe account, or nothing — demo mode works) and one access-state source (a Postgres/Supabase database, or a Clerk instance whose metadata holds plan, premium, or trial).
  • Nothing to install in your app to read your data. Only two steps touch your own systems: creating a read-only database role, and, optionally, registering a Stripe webhook.

Set up in eight steps

Onboarding lives at Project → Onboarding and walks you through every connection. Every step only reads — nothing changes until you turn on repairs.

  1. In the dashboard, open Project → Onboarding (URL /projects/{projectId}/onboarding). The wizard is 8 numbered steps on a left rail: Stack → Stripe → Database → Identity mapping → Plan mapping → Access mapping → Dry run → Repair mode. It resumes where you left off, so you can leave and come back.
  2. Step 1 (Stack): pick Billing (Stripe, pre-selected), Auth (Clerk / Supabase Auth / Other), and Database (Supabase / Postgres), then click Save and continue. Note: choosing Auth = Clerk here only tunes hints — it does not make Clerk your access source. You choose that with the tab on step 3.
  3. Step 2 (Stripe): either paste a restricted key and click Test & connect, or click Connect demo datasetin the dashed “Use demo mode” card to load 250 fixture customers with no external calls. See Connect Stripe.
  4. Step 3 (Database): connect Postgres with a read-only role, or switch to the Clerk tab. See Connect your database or Connect Clerk.
  5. Steps 4–6 (mappings):review ParityRail’s auto-suggested identity, plan, and access mappings and save each. See Mappings.
  6. Step 7 (Dry run): click Run read-only scan. Nothing is written.
  7. Step 8 (Repair mode): choose Detect only, Approval required, or Auto-repair safe to finish setup.
Want a fast tour without touching Stripe? Use demo mode on step 2 — see demo mode below.
Inside the dashboard, press ⌘K (Ctrl K on Windows and Linux) to open the command palette. Jump between projects, access incidents, and settings without leaving the keyboard.

Copy-paste reference

The onboarding URL for any project follows this pattern:

/projects/<your-project-id>/onboarding

If you chose Stripe demo mode on step 2, the seeded demo app database — useful for step 3 — connects with:

postgres://demoapp:demoapp_dev@localhost:54322/demoapp

Verify it worked

Two signals tell you setup actually worked, and neither requires trusting that a step “looked” connected:

  • Step 7 (Dry run): clicking Run read-only scanproduces a toast reading “Read-only scan complete — no changes were made” and four stat cards — Customers checked, Access incidents, Revenue at risk, and Changes made (always 0, hinted “Dry runs never write”). If it found incidents, a “By severity” breakdown and a “Review them in the incident inbox” link appear. The left rail shows a green check mark on every completed step.
  • Finishing step 8flips the onboarding page to a “Setup complete / Active” summary card, with a green status row for each of Stripe, App database, Identity mapping, Plan mappings, and Access mapping.

Troubleshooting

SymptomFix
The wizard opens on a later step than you expected.It resumes at your saved progress. Use the numbered left-rail buttons to jump back to any completed step — only steps you've already reached are clickable.
Continueis disabled, with a grey hint under it (for example, “Connect Stripe to continue”).The step's requirement isn't met yet — finish the connect or mapping the hint names, then Continue enables itself.
Other connect buttons work for teammates, but not for you.You likely have the member role. Connecting Stripe, a database, or Clerk requires admin — ask an owner or admin to elevate you.
You already finished setup and want to redo it.Open the completed onboarding page and click Restart setup — it reopens the wizard from step 1.

Demo mode

No Stripe account handy? On the Stripe step, choose Connect demo dataset. Demo mode loads a fixed dataset of 250 customers with realistic billing states and seeded access incidents, so you can see the full loop end to end. No external calls are made, and the demo Stripe integration never receives real webhook traffic.

The bundled demo project pairs demo Stripe fixtures with a seeded app database. Run a check and ParityRail finds a spread of access incidents across the demo customers, each with evidence and a repair preview.

What read-only means

ParityRail only ever reads. It can’t touch your billing or your live app data unless you explicitly turn on repairs.

  • Stripe — a restricted, read-only API key. ParityRail never writes to Stripe.
  • Postgres — a read-only role. Each connection also sets default_transaction_read_only = on as a second safeguard, so it physically cannot write.
  • Clerk — read-only too, if you use it instead of a database. There, repairs are guided rather than automated.

Repairs are opt-in and isolated. They need a separate database role with narrow, column-scoped UPDATE grants.

  • Every repair waits for your approval by default.
  • You see a before/after diff before it runs.
  • ParityRail re-verifies the customer afterward.

Leave the repair role unset to stay detect-only.

The incidents it catches

ParityRail detects eight classes of access incident between your billing and your app. Grace statuses like past_due and incomplete never trigger a revocation.

ClassIncidentWhat it means
M1Paid but no accessThe customer pays for a plan but your app still shows them as free or locked out.
M2Access but not paidThe subscription ended or never paid, but your app still grants premium access.
M3Plan mismatchBilling and your app disagree on which plan the customer is on.
M4Trial mismatchThe trial end date in your app does not match the subscription's trial.
M5Seat mismatchBilled seat quantity differs from the count of active members.
M6Mapping missingA billing customer or app row could not be matched by the identity mapping.
M7Webhook lagA recent billing change has not been reflected within the tolerated window.
M8Entitlement mismatchA feature entitlement is missing or lingering relative to the billing promise.