export const verifyIdentityCode = `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`

export const validateIdentityCode = `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`

export const deleteIdentityCode = `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`

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.

<CodeBlock code={verifyIdentityCode} lang="javascript" />

`session/validate` reports the same `identity_id` too:

<CodeBlock code={validateIdentityCode} lang="javascript" />

<div className="mt-6">
  <Callout>
    <p><span className="text-ink font-medium">This is separate from session_id.</span> <code className="font-mono">session_id</code> identifies one login; it changes every time a user verifies their phone again. <code className="font-mono">identity_id</code> 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.</p>
  </Callout>
</div>

<div className="mt-8">
<Section label="Scope and lifetime">
  <p>An identity is scoped to one project. The same phone number verified in two different MiniMoth projects gets two unrelated <code className="font-mono">identity_id</code> values — same as everything else in MiniMoth, projects never share user data with each other.</p>
  <p>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 <code className="font-mono">identity_id</code>. If you need to remove one, see <a href="#deleting-an-identity" className="text-saffron hover:underline">Deleting an identity</a> below.</p>
</Section>
</div>

<div className="mt-8">
<Section label="Sandbox and Test Group">
  <p>Identity resolution only runs on real, live verifications — a <code className="font-mono">mm_test_</code> sandbox key, and MiniMoth's dashboard Playground, never resolve or return an <code className="font-mono">identity_id</code>. Neither does the <a href="/docs/integrations/test-group" className="text-saffron hover:underline">Test Group</a> preview feature. All three are testing infrastructure, not real end users, so there's nothing to recognise across logins.</p>
</Section>
</div>

<div className="mt-8 scroll-mt-8" id="not-available-supabase-auth0">
<Section label="Not available for Supabase or Auth0">
  <p>If you're using MiniMoth as a <a href="/docs/integrations/supabase" className="text-saffron hover:underline">Supabase Send SMS Hook</a> or an <a href="/docs/integrations/auth0" className="text-saffron hover:underline">Auth0 custom phone provider</a>, you will never get an <code className="font-mono">identity_id</code> — there is no MiniMoth session to attach one to.</p>
  <p>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.</p>
  <p className="text-ink/50">If you need to recognise returning users across logins for a Supabase or Auth0 app, use their own user id — <code className="font-mono">auth.users.id</code> in Supabase, the Auth0 <code className="font-mono">user_id</code> — rather than anything from MiniMoth.</p>
</Section>
</div>

<h2 id="deleting-an-identity" className="font-medium text-xl mt-10 mb-3 scroll-mt-8">Deleting an identity</h2>

<p>Deleting an identity is <b className="text-ink">off by default</b> for every project — a live API key can't be used to erase identity data unless you've explicitly turned this on.</p>

<div className="mt-4">
  <Callout variant="accent">
    <p className="font-medium mb-1">Turn it on first</p>
    <p className="text-ink/60">In the dashboard, open your project's Settings card and enable <b className="text-ink">Identity deletion</b>. Until you do, <code className="font-mono text-xs">DELETE /v1/identity/:id</code> returns <code className="font-mono text-xs">403 IDENTITY_DELETE_DISABLED</code> for every request, valid id or not.</p>
  </Callout>
</div>

<div className="mt-4">
<CodeBlock code={deleteIdentityCode} lang="javascript" />
</div>

<p className="mt-4">Once enabled, deleting an identity:</p>

<div className="mt-2">
  <CompareGrid items={[
    { title: 'Hard-deletes the identity', description: 'The identity and its verified phone number are permanently removed. This cannot be undone.' },
    { title: 'Revokes every active session', description: 'Any session still tied to this identity is logged out immediately — the same revocation logout itself uses.', accent: true },
    { title: 'Session history is kept', description: '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.' },
  ]} />
</div>

<p className="text-xs text-ink/40 mt-4">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.</p>

---

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