minimoth

Identity

Every successful otp/verify call returns an identity_id — a stable id for the person, not just the session, scoped to your project. Verify the same phone number again next week, next month, next year, and you get the same identity_id back — as long as it’s the same project. The same phone number verified in a different one of your projects gets a completely unrelated identity_id; MiniMoth never links identities across projects. It’s a stable, opaque reference to that person for your own records — a cleaner foreign key than keying your schema directly off their phone number.

const res = await fetch('https://api.minimoth.dev/v1/otp/verify', {
  method: 'POST',
  headers: { 'X-Api-Key': 'mm_live_...', 'Content-Type': 'application/json' },
  body: JSON.stringify({ phone: '+919876543210', code: '123456' }),
})
const { access_token, refresh_token, expires_at, identity_id } = await res.json()
// identity_id is stable across every future login from this same phone number

session/validate reports the same identity_id too:

const res = await fetch('https://api.minimoth.dev/v1/session/validate', {
  method: 'POST',
  headers: { 'X-Api-Key': 'mm_live_...', 'Content-Type': 'application/json' },
  body: JSON.stringify({ access_token }),
})
const { valid, expires_at, identity_id } = await res.json()
// identity_id is omitted entirely when there is none to report

This is separate from session_id. session_id identifies one login; it changes every time a user verifies their phone again. identity_id stays the same across all of them — it’s what ties multiple logins, on multiple devices, over months or years, back to the same person.

Scope and lifetime

An identity is scoped to one project. The same phone number verified in two different MiniMoth projects gets two unrelated identity_id values — same as everything else in MiniMoth, projects never share user data with each other.

Identities are retained indefinitely — there’s no automatic expiry or cleanup. Recognising a returning person requires not deleting the link between their phone number and their identity_id. If you need to remove one, see Deleting an identity below.

Sandbox and Test Group

Identity resolution only runs on real, live verifications — a mm_test_ sandbox key, and MiniMoth’s dashboard Playground, never resolve or return an identity_id. Neither does the Test Group preview feature. All three are testing infrastructure, not real end users, so there’s nothing to recognise across logins.

Not available for Supabase or Auth0

If you’re using MiniMoth as a Supabase Send SMS Hook or an Auth0 custom phone provider, you will never get an identity_id — there is no MiniMoth session to attach one to.

In both integrations, Supabase or Auth0 generates the code, verifies it, and issues the session entirely on their own side. MiniMoth only delivers the SMS/WhatsApp message; it never sees the verification step and never mints a session of its own. The identity of that user already lives in Supabase’s or Auth0’s own user table — that’s their job, not MiniMoth’s, for these two integrations specifically.

If you need to recognise returning users across logins for a Supabase or Auth0 app, use their own user id — auth.users.id in Supabase, the Auth0 user_id — rather than anything from MiniMoth.

Deleting an identity

Deleting an identity is off by default for every project — a live API key can’t be used to erase identity data unless you’ve explicitly turned this on.

Turn it on first

In the dashboard, open your project’s Settings card and enable Identity deletion. Until you do, DELETE /v1/identity/:id returns 403 IDENTITY_DELETE_DISABLED for every request, valid id or not.

await fetch(`https://api.minimoth.dev/v1/identity/${identity_id}`, {
  method: 'DELETE',
  headers: { 'X-Api-Key': 'mm_live_...' },
})
// 403 IDENTITY_DELETE_DISABLED until you turn this on for the project (see below)
// 404 IDENTITY_NOT_FOUND if the id doesn't exist, or belongs to a different project

Once enabled, deleting an identity:

Hard-deletes the identity

The identity and its verified phone number are permanently removed. This cannot be undone.

Revokes every active session

Any session still tied to this identity is logged out immediately — the same revocation logout itself uses.

Session history is kept

Past sessions stay in MiniMoth's billing records; only their identity_id is cleared to null. Deleting a person's identity never rewrites your billing history.

This is a good fit for a “delete my account” flow in your own app — call it from your backend once you’ve confirmed the request is genuinely from that user.

Try the full OTP flow interactively in the sandbox — no SMS sent, no credits consumed. The same Playground also has a live test to send a real OTP to your phone (uses your credits).

Test in Playground →