Skip to content

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.

  1. Log in to MinuteMail
  2. 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.

In the Create a new OAuth client form:

FieldRequiredDescription
NameYesDisplay name shown on the consent screen (e.g. “My App Dev”)
Provider typeYesgoogle, github, apple, facebook, or custom
Provider labelOnly for customText shown above the client name on the consent screen. Predefined types default to “Google”, “GitHub”, etc.
Redirect URIsYes (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.

  • At least one redirect URI is required
  • Matching is exacthttp://localhost:3000/callback and http://localhost:3000/callback/ are different URIs, and query strings are part of the match
  • The redirect_uri sent to the authorize and token endpoints must exactly equal one of the registered URIs
  • 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

Expand a client card and use the identity form:

FieldRequiredDescription
Mailbox addressYesOne of your active MinuteMail mailboxes, selected from the dropdown or typed. The address must exist in your account
UsernameNoDefaults to the local part of the mailbox address (before @)
NameNoDisplay name; defaults to the username
Avatar URLNoPicture 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.

Identities carry these additional fields, settable at create time or later via the management API, the MCP server, or the Python SDK:

FieldTypeDefaultDescription
isActivebooltrueWhether the identity is eligible for the consent screen
emailVerifiedbooltrueBecomes the email_verified claim in ID tokens and userinfo
claimsmap 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.

Update an identity with the management API instead of deleting and recreating it:

PATCH https://api.minutemail.co/v1/identities/ident_01JEXAMPLE
Authorization: Bearer mmak_YOUR_API_KEY
Content-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:

FieldTypeDescription
usernamestringNew username (becomes preferred_username)
namestringNew display name
avatarUrlstringNew picture URL
isActiveboolfalse deactivates the identity — see below
emailVerifiedboolNew email-verification status
claimsmap of string to stringReplaces 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).

  • 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: false and the consent screen shows a ”⚠ email not verified” warning, while ID tokens and userinfo carry email_verified: false (on GitHub-type clients, the verified flag in the emails array). Flip it back to true — 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 onlyCustom explains why.

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.