Give up to 5 testers a link where they can see the OTP your [Supabase](/docs/integrations/supabase) or [Auth0](/docs/integrations/auth0) Test Hook generates — without a real SMS or WhatsApp message ever going out, and without anyone digging through your provider's own logs to find the code.

## How it fits together

This only works together with the Supabase or Auth0 integration's `Test` Hook — it isn't a general-purpose way to test the OTP API. When your staging app triggers a phone OTP against a number wired to your Test Hook, Supabase or Auth0 sends the code to MiniMoth as usual, but test mode never actually delivers it. Test Group gives a human a place to see that code anyway: a tester who's part of the group and has logged in sees the code appear on their screen (or as a push notification) within seconds, and relays it to whoever needs to finish verification.

<div className="bg-white/5 border border-white/10 rounded-lg px-4 py-3 text-xs text-ink/50 leading-relaxed mt-3">
  Test Group only ever captures OTPs sent through your project's Test Hook. Live/production OTPs — from the Live Hook, the direct API, or anywhere else — are never captured or exposed here.
</div>

## Setup

1. **Wire up your Supabase or Auth0 Test Hook first** — Test Group has nothing to show until your app is actually triggering OTPs through it. See the [Supabase](/docs/integrations/supabase) or [Auth0](/docs/integrations/auth0) integration guide.

2. **MiniMoth dashboard** — switch the project to `Test Mode`, open the `Test Group` card, and click `Set up a test group`.

3. **Add testers** — up to 5 real, reachable phone numbers. Each one has to log in with an actual OTP before they can see anything, so a number you don't control won't get you access.

4. **Share the invite link** — copy it from the same card and send it to your testers. You can rotate it any time to revoke the old link immediately; testers already logged in aren't affected.

5. **Tester logs in** — they open the link, enter their phone number, and verify a one-time code (this part is a real OTP, sent over MiniMoth's normal infrastructure). That signs them into a 10-day session, independent of your project's own session settings — logging out is the only thing that ends it early.

6. **Trigger a Test Hook OTP** — from your staging app, for one of the allowlisted numbers:

   ```typescript
// Trigger this against a phone number in your test group,
// with your Test Hook wired up in Supabase Auth
const { error } = await supabase.auth.signInWithOtp({ phone })
```

   The code shows up on the tester's screen within about 10 seconds. They can also install the page as an app and enable notifications, so it arrives as a push instead of requiring the tab to stay open.

<div className="mt-6">
  <Callout variant="accent">
    <p className="font-medium mb-1">Billing</p>
    <p className="text-ink/60">
      A tester's one-time login OTP is billed to your wallet like any other OTP, that's real delivery, so it's real cost. The OTPs they preview afterwards cost nothing: those come from your Test Hook, which never sends a real message in the first place.
    </p>
  </Callout>
</div>

<div className="mt-6">
  <Callout>
    <p className="font-medium text-ink/80 mb-1">Good to know</p>
    <ul className="list-disc list-inside space-y-1">
      <li>Up to 5 numbers per project.</li>
      <li>A captured OTP is only held for 5 minutes — if nobody's watching the screen when it comes through, it's gone by the time they check.</li>
      <li>Removing a tester's number immediately logs out their session, if they had one.</li>
    </ul>
  </Callout>
</div>

---

Full documentation index: https://minimoth.dev/llms.txt
