Clients & Identities
OAuth clients and mock identities are managed in the MinuteMail web dashboard, behind GitHub login. This page walks through registering a client and creating identities linked to your mailboxes. For the OAuth protocol itself, see OAuth Flow.
Accessing the page
Section titled “Accessing the page”- Log in to MinuteMail
- Open the Identity Providers page from the main navigation
The page lists all OAuth clients in your account. Each client card shows its client ID, secret, provider, and redirect URIs, and can be expanded to manage its identities.
Registering an OAuth client
Section titled “Registering an OAuth client”In the Create a new OAuth client form:
| Field | Required | Description |
|---|---|---|
| Name | Yes | Display name shown on the consent screen (e.g. “My App Dev”) |
| Provider type | Yes | google, github, apple, facebook, or custom |
| Provider label | Only for custom | Text shown above the client name on the consent screen. Predefined types default to “Google”, “GitHub”, etc. |
| Redirect URIs | Yes (at least one) | Exact-match URIs your app may be redirected back to (e.g. http://localhost:3000/callback) |
The provider type determines the logo rendered on the consent screen — a Google-styled client shows the Google logo, and so on. Use custom with your own label to impersonate any other provider.
The provider type also determines the client’s wire behavior — protocol, ID token issuance, token response fields, and profile endpoints — which the mock replicates faithfully per provider. See Provider Behavior.
On creation you receive:
- Client ID — public identifier (prefixed
mc_), used in authorize requests - Client secret — secret (prefixed
cs_) used at token exchange
Copy both — you’ll need them to configure your app. The secret remains visible on the client card in the dashboard and can be copied from there at any time.
Redirect URI rules
Section titled “Redirect URI rules”- At least one redirect URI is required
- Matching is exact —
http://localhost:3000/callbackandhttp://localhost:3000/callback/are different URIs, and query strings are part of the match - The
redirect_urisent to the authorize and token endpoints must exactly equal one of the registered URIs
Managing clients
Section titled “Managing clients”- Rotate secret — generates a new client secret. The old secret stops working immediately; update your app after rotating
- Delete — removes the client (confirmation required). Its identities remain, but flows for this client will fail until re-registered
Creating mock identities
Section titled “Creating mock identities”Expand a client card and use the identity form:
| Field | Required | Description |
|---|---|---|
| Mailbox address | Yes | One of your active MinuteMail mailboxes, selected from the dropdown or typed. The address must exist in your account |
| Username | No | Defaults to the local part of the mailbox address (before @) |
| Name | No | Display name; defaults to the username |
| Avatar URL | No | Picture URL returned by userinfo |
An identity is what your app “sees” as the logged-in user: its mailbox address becomes the email claim, the username becomes preferred_username, and the name becomes name in userinfo and ID tokens. Emails your app sends to that address arrive in the linked MinuteMail mailbox, where you can read them from the mailboxes page.
Identity fields
Section titled “Identity fields”Identities carry these additional fields, settable at create time or later via the management API, the MCP server, or the Python SDK:
| Field | Type | Default | Description |
|---|---|---|---|
isActive | bool | true | Whether the identity is eligible for the consent screen |
emailVerified | bool | true | Becomes the email_verified claim in ID tokens and userinfo |
claims | map of string to string | {} | Custom claims merged into ID tokens and userinfo responses — custom-provider clients only, see below |
Claim names reserved by the provider (iss, sub, aud, exp, iat, nbf, jti, email, email_verified, name, preferred_username, picture, nonce, at_hash) and empty claim keys are rejected with a 400 at create/update time — custom claims cannot override the standard ones.
Claims are a custom-provider feature. Setting claims on a google, github, apple, or facebook client is rejected with a 400 — you can’t inject claims into a Google- or Apple-issued token in reality, so the mock doesn’t allow it either. emailVerified, isActive, and the profile fields (username, name, avatarUrl) work on all provider types. See Custom.
New identities are active immediately. When an authorize request comes in for a client, the first active identity (oldest created) for that client is pre-selected on the consent screen.
Updating identities
Section titled “Updating identities”Update an identity with the management API instead of deleting and recreating it:
PATCH https://api.minutemail.co/v1/identities/ident_01JEXAMPLEAuthorization: Bearer mmak_YOUR_API_KEYContent-Type: application/json
{ "name": "Tricia McMillan", "emailVerified": false, "claims": { "roles": "admin" }}The request body accepts any subset of the following fields; omitted fields are left unchanged:
| Field | Type | Description |
|---|---|---|
username | string | New username (becomes preferred_username) |
name | string | New display name |
avatarUrl | string | New picture URL |
isActive | bool | false deactivates the identity — see below |
emailVerified | bool | New email-verification status |
claims | map of string to string | Replaces the existing claims wholesale when provided |
clientId and mailboxAddress are immutable. The endpoint requires an API key with the identities:write scope (see API Getting Started).
Managing identities
Section titled “Managing identities”- Update — change the profile fields, claims, or verification status via
PATCH /v1/identities/{identityId}(see Updating identities) - Deactivate — set
isActive: false. The identity is then skipped by the consent screen, which always uses the client’s first active identity; if no active identity remains, authorize shows a legible error instead of a code - Delete — removes the identity (confirmation required). Tokens already issued for it continue to work until they expire, but new flows will select the next active identity
Testing email verification and custom claims
Section titled “Testing email verification and custom claims”Two identity fields exist mainly for flow testing:
- Email verification — create or update an identity with
emailVerified: falseand the consent screen shows a ”⚠ email not verified” warning, while ID tokens and userinfo carryemail_verified: false(on GitHub-type clients, theverifiedflag in the emails array). Flip it back totrue— for example after your app sends a verification email that you read in the linked mailbox — to test both branches of your signup logic without real users. - Custom claims — set
claims(e.g.{ "roles": "admin", "tenant": "acme" }) to attach arbitrary string claims to the identity. They are merged into every ID token and userinfo response for that identity, so you can test role- or tenant-based authorization in your app. Custom-provider clients only — Custom explains why.
Quotas
Section titled “Quotas”Each plan caps the number of mocked IdPs (OAuth clients) you can register (mocked_idps). The dashboard shows your current usage, and creating a client fails with a limit error (HTTP 429) when the cap is reached — delete unused clients or upgrade your plan to continue.
Mock identities are not subject to any quota — you can create as many as you need, for any of your mailbox addresses.