# Mystra

> After every deploy, Mystra signs up in a real browser, reaches your Stripe Checkout without paying, and checks the paid area holds. Alerts only with proof.

Mystra is a revenue-path monitor for web apps with a signup, a payment and a paid area. After every deploy (and on a schedule) a real, scripted Chrome browser walks the path a paying customer takes on your app: sign up with a fresh throwaway email, receive and follow the welcome or magic-link email, reach Stripe Checkout, and confirm the paid area actually unlocked. It alerts only when it can prove a break, and every alert carries a screenshot, a video, a HAR network capture and the console log.

Site: https://mystra.run · Sign in: https://mystra.run/sign-in (Google or a magic link)

## How a run works

A **run** walks four **steps** in order on one **app** (a host you own and have verified):

1. **Signup** — opens the signup page, dismisses cookie banners, fills the email (and password when the app asks for one; passwordless and magic-link flows are handled), submits, and accepts a "check your email" confirmation as success.
2. **Email** — waits for the welcome or verification mail at the run's own address (`run-<id>@inbox.mystra.run`), then follows the first verify/confirm/login link on your host.
3. **Pay** — starts from the configured *upgrade page* (or looks for an Upgrade/Pricing/Billing link, then the usual paths such as /pricing and /dashboard/billing), presses the plan button, follows plan dialogs, and reaches Stripe Checkout. What happens next depends on the **payment proof** mode below.
4. **Access** — proves the paid area: either a CSS selector on a page, or a boolean field in a JSON endpoint called with the run's session.

Each step records **checks** (timestamped lines such as `POST /api/auth/signin/email → 200`), a screenshot, and, for the failing step, the request/response and the console error that decided it.

**Outcomes**: `passed`, `broken` (a proven break: a 4xx/5xx, a timeout, a missing email, a closed paid area), `uncertain` (something did not go to plan but nothing was proven, so nobody is paged), and `flaky` (passed only on a retry; signup, email and access are retried once).

**Alerting is proof-only.** A broken run with proof opens an alert on the app's channels (Slack incoming webhook, email, JSON webhook), reminds at a chosen interval while it stays broken, respects quiet hours, and recovers by itself the moment the same step passes again. Uncertain and flaky runs never alert; three uncertain runs in a row earn one "needs a look" note per day.

**Payment proof:** Mystra reaches Stripe Checkout and never pays. It reads the plan and amount, compares the price id you configured, stops, and checks the paid area is still gated for the fresh account. Safe on live Stripe keys.

## The dashboard (sign-in required; it lives at https://mystra.run/dashboard)

- **Runs** (`/dashboard`): every run with outcome, path segments, proof, duration and trigger; 24 h / 7 d / 30 d ranges; pass rate, broken count and median signup-to-access time. Pages refresh themselves while a run is in progress. A first-run checklist appears until the first run exists.
- **Run detail** (`/dashboard/runs/<id>`): the verdict, the step timeline with every check, the request and response that decided the run, screenshots (click to enlarge), video, HAR and console log, and a signed share link.
- **Alerts** (`/dashboard/alerts`): the open alert with the exact message as sent, history of broken → recovered pairs, "needs a look" notes, channels (add Slack, email or webhook and test them), and rules (remind-while-broken interval, quiet hours).
- **Apps** (`/dashboard/apps`): one card per product with status (passing / unclear / broken / setting up), a 7-day strip, and the wiring checklist (domain verified, deploy hook, schedule, alerts). **Add app** at `/dashboard/apps/new`.
- **Evidence** (`/dashboard/evidence`): the evidence library, storage use, retention rules and shared links.
- **App settings** (`/dashboard/apps/<id>/settings`): General, Path (signup page with a live check, sign-up method, welcome-email window, upgrade page, price id, access proof, cleanup webhook), Schedule, Deploy hook (URL, signing secret, Vercel webhook secret, snippets, "Copy instructions for your AI"), Domain, Danger zone.
- **Account settings** (`/dashboard/settings`): profile, a System status card (inbox MX, sending domain, one-click runner check), retention, delete account.

## Adding an app

1. Enter the host (e.g. `app.example.com`) and a name.
2. Prove ownership with one DNS TXT record at `_mystra.<host>` whose value Mystra shows (`mystra-verify=…`). Mystra checks every 10 seconds; on Vercel DNS one command does it: `vercel dns add <apex> _mystra TXT "<value>"`.
3. Describe the path: signup page and method, welcome-email window, upgrade page, price id and access proof.
4. Connect the deploy hook, and the first run starts.

## Integrations and APIs

- **Deploy hook** — `POST https://mystra.run/api/hooks/deploy/<appId>` with header `X-Mystra-Signature: <signing secret>` and JSON `{ "commit": "<sha>", "env": "production" }` starts a run tagged with the commit. Easiest: a GitHub Action on `deployment_status` (any host that reports GitHub Deployments, including Vercel's Git integration). Vercel Pro/Enterprise teams can instead point a Vercel account webhook (event *Deployment Succeeded*) at the same URL and paste its secret into the app's Deploy hook settings; Mystra verifies `x-vercel-signature` and only acts on production deploys.
- **Cleanup webhook** — after every run Mystra POSTs `{ "event": "run.finished", "runId", "email", "outcome" }` to a URL you set, signed with `X-Mystra-Signature: sha256=<HMAC-SHA256 of the raw body>` using the app's outgoing secret, so your app can delete the throwaway `run-…@inbox.mystra.run` user.
- **Marking the path** — add `data-mystra="upgrade"` to the button that starts checkout, `data-mystra="checkout"` to a plan dialog's confirm button, and a stable selector such as `data-plan="pro"` on the paid area. The runner presses these first and never has to guess.
- **AI brief** — every app's Deploy hook settings offer "Copy instructions for your AI": a markdown brief for Claude Code, Cursor or ChatGPT that explains what the codebase must expose (throwaway accounts, signup form, welcome email, payment proof, access proof, deploy hook, cleanup webhook). No secrets are embedded.
- **Shared runs** — `https://mystra.run/s/<token>`: a signed, revocable public page for one run with its evidence.

## Evidence and retention

Every run stores per-step screenshots, a video, a HAR archive and the console log. Evidence of broken runs is kept 30 days, of passed runs 7 days, pinned runs until unpinned; the run list goes back 7 days (Free, Starter) or 90 days (Pro). Evidence links are private to the owner or to holders of a share link.

## Plans

- **Free** · $0 · 1 app · 25 runs / month · deploys and Run now (no schedule) · 7-day history · 1 GB of evidence
- **Starter** · $29/month · 3 apps · 500 runs / month · Up to three apps, checked after every deploy and on a schedule.
  Signup, email, payment and access checks · Screenshots, video, HAR and console log on every run · Slack, email and webhook alerts, only with proof · Runs on deploy, on a schedule and on demand · 7-day run history · 2 GB of evidence
- **Pro** · $79/month · 10 apps · 3,000 runs / month · Several apps, checked as often as every 15 minutes.
  Everything in Starter · Up to 10 apps · 3,000 runs a month · 90-day run history · 10 GB of evidence

## Links

- [Home](https://mystra.run/): what Mystra does, how it works, pricing
- [Pricing](https://mystra.run/pricing): the Free, Starter and Pro plans side by side, what counts as a run, what happens at the limit
- [Blog](https://mystra.run/blog): explainers and guides, newest first; RSS at https://mystra.run/blog/feed.xml. Posts so far: "Synthetic monitoring vs uptime checks: what each one actually proves" (https://mystra.run/blog/synthetic-monitoring-vs-uptime-checks) and "How to test a magic-link signup flow end to end" (https://mystra.run/blog/how-to-test-a-magic-link-signup-flow)
- [Guide: how to test a Stripe Checkout flow without paying](https://mystra.run/guides/test-stripe-checkout-without-paying): test mode and test cards, reaching live Checkout and stopping, 100%-off promotion codes, real card and refund, and re-checking the paywall
- [Docs](https://mystra.run/docs): quickstart, how a run works, outcomes and alerts, payment proof, evidence and retention, path settings, deploy hook, cleanup webhook, marking the path, AI brief, sharing a run, plans and limits (each at https://mystra.run/docs/<slug>)
- [Changelog](https://mystra.run/changelog)
- [Status](https://mystra.run/status): live checks of Mystra's own plumbing
- [Security](https://mystra.run/security): what Mystra touches on your app and what it stores
- [About](https://mystra.run/about) · [Contact](https://mystra.run/contact)
- [Sign in](https://mystra.run/sign-in)
- [Privacy policy](https://mystra.run/privacy-policy) · [Terms of service](https://mystra.run/tos)

Mystra is an independent, self-funded product built in Europe, with a public changelog and status page.
