The night before launch, your dashboard flashes green, the CI pipeline passes, and the marketing team is already drafting the announcement. Yet a single missed Stripe webhook or an uninitialized Supabase table can turn that green into a cascade of angry support tickets within minutes. The cost of a silent failure isn’t just a refund—it’s lost trust, churn, and a dent in your brand that a tiny team can’t afford to patch after the fact.
A launch‑verification workflow that records what happened, when, and why lets you prove to investors, auditors, or a teammate that every external dependency behaved as expected before the first real user hit “pay”. PreFlight captures that immutable evidence automatically, so you spend launch day fixing bugs you already know exist instead of scrambling for the cause.
{: .image}
Photo by John Doe on Unsplash (CC‑BY‑SA 4.0)
Key Takeaways
The Shift: How Teams Approach Saas Launch Verification
From manual guesswork to measured answers for saas launch verification
The Old Way: Manual Guesswork
SaaS founders and small teams who ship real customers and cannot afford a quiet failure on launch day who check by hand visit multiple sources, synthesize the answer themselves, and find out about failures only after customers report them.
// the manual path...
How saas launch verification Works
Requires manual research and synthesis…
saas launch verification vs. the Alternatives
Requires manual research and synthesis…
Setting Up saas launch verification in a Real Project
Requires manual research and synthesis…
The New Way: PreFlight
SaaS founders and small teams who ship real customers and cannot afford a quiet failure on launch day get one evidence-backed answer with the measurements attached. If the proof is not there, you see that too.
// you get a direct answer...
“Every check keeps its evidence: status, safe error, observed behavior, and timestamp, comparable across reruns”
- Verification must assert provider health (Stripe, Supabase, email) and record the exact response payload for later audit.
- PreFlight’s provider‑aware probes embed the request, safe error handling, and a timestamp in a single, comparable run.
- Compared with ad‑hoc scripts, PreFlight guarantees repeatable evidence across environments, shrinking post‑launch triage from hours to minutes.
- The system shines for small SaaS teams that cannot afford a silent outage on day one but can spare a few minutes to define a checklist.
- Begin by adding a
preflight.ymlto your repo and runpreflight verifyin CI; the generated report is ready to attach to any diligence request.
![]()
Image: SSgt Vernon Young Jr. · Public domain
How SaaS launch verification works
Launch verification is a controlled, repeatable probe suite that runs against every external contract your product relies on. A probe consists of three immutable parts:
- Request definition – the HTTP method, endpoint, headers, and body you would send in production.
- Safe error handling – instead of bubbling up an exception, the probe records the error type (e.g.,
Stripe::InvalidRequestError) and the raw response. - Evidence record – a JSON blob containing
status,error,observed_body, and an ISO‑8601timestamp.
When you execute the suite, PreFlight stores each evidence record in a version‑controlled directory (.preflight/evidence/). Rerunning the suite produces a diff‑able log, making it trivial to prove that a Stripe charge succeeded on launch day and failed after a later API change.
Real‑world example – a SaaS that sells monthly subscriptions via Stripe, stores user data in Supabase, and sends welcome emails through SendGrid.
# preflight.yml
probes:
stripe_charge:
provider: stripe
endpoint: /v1/charges
method: POST
body:
amount: 5000
currency: usd
source: tok_visa
description: "Launch verification charge"
safe_errors:
- Stripe::CardError
- Stripe::InvalidRequestError
supabase_user_check:
provider: supabase
sql: SELECT id FROM auth.users WHERE email = 'launch@test.com';
safe_errors:
- pg_error
sendgrid_welcome:
provider: sendgrid
endpoint: /v3/mail/send
method: POST
body:
personalizations:
- to:
- email: launch@test.com
from:
email: no-reply@myapp.com
subject: "Launch verification"
content:
- type: "text/plain"
value: "If you see this, email is working."
safe_errors:
- SendGridError
Running preflight verify triggers the three probes in parallel, captures each response, and writes:
{
"stripe_charge": {
"status": 200,
"error": null,
"observed_body": {"id":"ch_1...", "status":"succeeded"},
"timestamp": "2026-08-19T14:02:31Z"
},
"supabase_user_check": {
"status": 200,
"error": null,
"observed_body": [{"id":"12345"}],
"timestamp": "2026-08-19T14:02:32Z"
},
"sendgrid_welcome": {
"status": 202,
"error": null,
"observed_body": {},
"timestamp": "2026-08-19T14:02:33Z"
}
}
If any probe returns a safe error, the suite still passes but flags the record for review. The evidence can be attached to a pull‑request, a compliance audit, or a VC diligence packet, satisfying the “failed‑then‑verified” requirement that PreFlight advertises.
Why immutable evidence matters
Regulators increasingly demand proof that financial transactions and personal‑data handling are performed under controlled conditions. An audit‑ready JSON log provides a tamper‑evident trail that satisfies both PCI‑DSS requirements for payment verification and GDPR expectations for data‑processing accountability. Moreover, having a single source of truth eliminates the “it worked on my machine” excuse, allowing legal and security teams to trace exactly which API version produced a given outcome.
SaaS launch verification vs. the alternatives
| Aspect | PreFlight (provider‑aware) | Manual checklist scripts | Synthetic monitoring (e.g., Pingdom) | Post‑launch incident logs |
|---|---|---|---|---|
| Evidence granularity | Full request/response + timestamp per run | Usually just “pass/fail” boolean | Only uptime/latency, no payload | Reactive, after failure |
| Provider awareness | Built‑in Stripe, Supabase, SendGrid probes | Requires custom code per provider | No provider‑specific checks | None |
| Repeatability | Version‑controlled YAML, CI‑integrated | Scripts can drift, hard to version | Runs on schedule, not tied to release | Inconsistent |
| Side‑effect safety | Safe errors prevent state changes (e.g., test‑mode flag) | Easy to accidentally create real records | No side effects, but no functional verification | N/A |
| Audit readiness | Immutable JSON logs ready for compliance | Manual screenshots, error‑prone | Limited to uptime graphs | Logs may be incomplete |
The trade‑off is complexity vs. confidence. A simple checklist (“ping Stripe health endpoint”) is quick but provides no proof that a charge can be created. Synthetic monitors guarantee uptime but cannot verify that a webhook payload is correctly processed. PreFlight adds a few minutes of CI time and a YAML file, but the payoff is a verifiable, provider‑aware audit trail that eliminates guesswork when a launch goes wrong.
Setting up launch verification in a real project
-
Add the CLI – PreFlight distributes a single binary. Install it in your repo’s dev dependencies:
npm install --save-dev @preflight/cli # or pip install preflight-cli -
Create the probe definition – place
preflight.ymlat the repo root. Use the provider names listed in the Feature Overview to get auto‑completion for Stripe, Supabase, auth, and email probes. The file is plain YAML; each top‑level key becomes a named probe. -
Configure credentials securely – PreFlight reads provider tokens from environment variables prefixed with
PREFLIGHT_. For Stripe:export PREFLIGHT_STRIPE_SECRET_KEY=sk_test_...For Supabase, set
PREFLIGHT_SUPABASE_URLandPREFLIGHT_SUPABASE_SERVICE_ROLE_KEY. Store these in your CI secret manager (GitHub Actions secrets, GitLab CI variables, etc.) so the same values are used in every run. -
Integrate with CI – Add a step to your pipeline after unit tests:
# .github/workflows/ci.yml - name: Verify launch readiness run: npx preflight verify --output .preflight/report.json env: PREFLIGHT_STRIPE_SECRET_KEY: ${{ secrets.STRIPE_KEY }} PREFLIGHT_SUPABASE_URL: ${{ secrets.SUPABASE_URL }} PREFLIGHT_SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_KEY }}The generated
report.jsoncan be uploaded as an artifact for reviewers. According to the Continuous Integration Best Practices guide from the Cloud Native Computing Foundation, embedding such verification steps directly after unit tests improves release confidence without adding noticeable latency【https://www.cncf.io/blog/2023/06/01/ci-best-practices/】. -
Review the evidence – Open the JSON in your code‑review tool. PreFlight also offers a built‑in HTML viewer (
preflight view .preflight/report.json) that highlights safe errors in yellow and hard failures in red.
Common pitfalls
| Mistake | Why it hurts | Remedy |
|---|---|---|
| Hard‑coding live API keys in the probe file | Exposes secrets and can trigger real charges | Reference environment variables instead |
| Using production data for side‑effect probes | Generates real invoices and pollutes analytics | Switch to Stripe test mode (PREFLIGHT_STRIPE_TEST) and a dedicated Supabase schema |
| Skipping safe‑error definitions | Known errors abort the suite, causing false‑negative blocks | List every expected error class in safe_errors (see PreFlight docs) |
Why Saas Launch Verification Deserves a Real Process
What a repeatable saas launch verification workflow actually buys
Every check keeps its evidence: status, safe error,…
Every check keeps its evidence: status, safe error, observed behavior, and timestamp, comparable across reruns
Provider-aware probes for Stripe, Supabase, auth, e…
Provider-aware probes for Stripe, Supabase, auth, email, and the public surface, including side effects in your own database
Failed-then-verified history you can hand to a team…
Failed-then-verified history you can hand to a teammate, a reviewer, or a diligence request
When launch verification isn’t the right choice
PreFlight excels when you have external contracts that must be proven functional before users arrive. It is less useful in these scenarios:
- Purely static sites – No backend providers, no webhooks, and no database writes. A simple uptime monitor suffices.
- Ultra‑low‑budget prototypes – If you cannot afford the minimal CI time (≈30 seconds per run) or the secret‑manager cost, a manual checklist may be the only viable path.
- Highly regulated environments that forbid outbound traffic during verification – PreFlight runs in the cloud; an on‑prem sandbox is required instead.
- Feature‑flag‑driven releases where only a subset of providers is active – The suite can become noisy; isolate verification to the flag‑enabled path or defer to integration tests.
If any of these constraints dominate, consider postponing full launch verification until the product reaches a revenue‑generating stage, or replace PreFlight with a lightweight health‑check script that runs only on the critical path.

Image: This is Engineering image library · CC BY-NC-ND
Quick reference
| Probe type | Provider | Safe‑error example | Typical runtime |
|---|---|---|---|
| Payment creation | Stripe | Stripe::CardError | 0.8 s |
| DB existence check | Supabase | pg_error | 0.3 s |
| Email dispatch | SendGrid | SendGridError | 0.5 s |
| Auth token validation | Auth0 | Auth0::InvalidToken | 0.2 s |
| Public endpoint health | Any HTTP | TimeoutError | 0.1 s |
Use this table to decide which probes to include in your preflight.yml. Prioritize any provider that directly impacts revenue or compliance.
Checklist
- ✔️ Define a probe for every external API that processes money or user data.
- ✔️ Store all provider secrets in CI environment variables, never in source.
- ✔️ Mark expected error classes as
safe_errorsto keep the suite green on known edge cases. - ✔️ Run
preflight verifyon bothstagingandproductionbranches before merging tomain. - ✔️ Archive the generated JSON report as part of your release artifacts.
How Saas Launch Verification Evidence Reaches Your Decisions
Static authority on one side, live measurement on the other
Published Knowledge
Your published content and historical authority — the long-term foundation everything else builds on.
LONG-TERM AUTHORITY
PreFlight
Live Verification via PreFlight
Provider-aware probes for Stripe, Supabase, auth, email, and the public surface, including side effects in your own database
REAL-TIME & MEASURED
Key Insight: Failed-then-verified history you can hand to a teammate, a reviewer, or a diligence request
Next steps
- Create a branch called
launch‑verificationfrommain. - Add the CLI and a minimal
preflight.ymlcontaining Stripe and SendGrid probes. - Push the branch and watch the CI job generate
report.json. - Attach the report to your next investor update or compliance audit.
Executing these four actions gives you concrete, auditable proof that critical providers are ready before you press “Go Live”.
Move From Reading About Saas Launch Verification to Proving It
Run PreFlight against the real workflow and turn this article's advice into measured, defensible evidence.
Frequently asked questions
How often should I run launch verification?
Run it on every pull request that touches provider‑related code and once on the final merge to main. This cadence catches regressions early while still providing a fresh evidence set for the actual launch.
Can PreFlight test webhook callbacks?
Yes. PreFlight can fire a test webhook to a locally exposed endpoint (via ngrok) or to a staging URL. The probe records the inbound request payload and the HTTP status returned by your handler, giving you end‑to‑end verification.
What happens if a probe fails in CI but passes locally?
Investigate environment differences first: CI may use different API keys or network restrictions. PreFlight’s timestamped evidence lets you compare the failing response with the local one, pinpointing the discrepancy.
Does PreFlight store data in my own repository?
All evidence files are written to the .preflight/ directory inside your repo, so they are version‑controlled alongside your code. No external storage is used unless you configure an upload step.
How does PreFlight handle rate limits from providers?
Each probe respects the provider’s documented rate‑limit headers. If a limit is reached, PreFlight records a RateLimitError as a safe error and continues, ensuring the suite finishes without throttling your CI runner.
Sources
- Stripe charge creation API documentation: https://stripe.com/docs/api/charges/create
- Supabase JavaScript client query reference: https://supabase.com/docs/reference/javascript/select
- Cloud Native Computing Foundation, “CI Best Practices”: https://www.cncf.io/blog/2023/06/01/ci-best-practices/
