Start changing your email address
The users.email_change.start operation: POST /api/v1/users/me/email_change/start in the REST API and the users_email_change_start tool in the MCP server.
/api/v1/users/me/email_change/startStarts moving your Ownrecord account to a new email address: a six-digit code goes to the new address, and
users.email_change.confirm with that code makes the change. The code works for 10 minutes and allows 5
guesses. Starting again replaces the open change and its code.
The answer is the same whether or not the new address already has an Ownrecord account, so nobody can use this
to find out which addresses have one. An address that already has an account gets a notice instead of a code,
and users.email_change.confirm answers email_taken only after a code proved the address is yours.
Limits: 3 starts an hour per account and 5 a day per new address (rate_limited). Refused for platform staff,
whose addresses follow the staff domains and their identity provider (email_change_not_allowed), and for
disposable addresses. If you sign in with Google or Microsoft, that keeps working after the change.
Who can call it: the signed-in user, for their own account, in the console, with a sign-in in the last 15 minutes.
At a glance
- REST:
POST /api/v1/users/me/email_change/start - MCP tool:
users_email_change_start - Operation ID:
users.email_change.start - Scope: Platform
- Permission:
account:write - Risk tier:
security - Dry run: Not supported
- Idempotency:
Idempotency-Keyrequired - Modes: Test and live
- Authentication: API key with the
account:writescope - Fresh sign-in: In the console, a sign-in within the last 15 minutes
- Since: M13
Request
Body
A JSON object (Content-Type: application/json):
| Field | Type | Required | Description |
|---|---|---|---|
newEmail | string | Yes | The address to move your account to. A code goes there. |
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
object | "email_change_request" | |
id | emc_… ID | |
email | string | The new address, normalised (lower case). |
expiresAt | date-time | When the code stops working (10 minutes after the start). |
message | string | What to do next. The same whether or not the address has an account. |
Examples
Move my account to a new address
POST /api/v1/users/me/email_change/start
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json
{
"newEmail": "ana.novak@example.com"
}
Response (200):
{
"object": "email_change_request",
"id": "emc_01m4tx5nj8emwbyf7y9vcf47xg",
"email": "ana.novak@example.com",
"expiresAt": "2026-11-04T09:10:00.000Z",
"message": "We've sent an email to ana.novak@example.com. Enter the code from it within 10 minutes to confirm the address."
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
email_invalid | 400 | newEmail isn't an address that can receive a code. | Check the address and try again. |
email_change_same_address | 400 | newEmail is already your address. | Enter the new address you want to use. |
email_domain_blocked | 400 | newEmail is a disposable address. | Sign up with a permanent address, for example your work email. |
email_change_not_allowed | 403 | You're platform staff. | Staff addresses follow the staff domains and your Google or Microsoft account. Ask a platform admin to change it. |
rate_limited | 429 | 3 starts in the last hour for your account, or 5 today for this address. | Wait for retry_after_ms and retry with backoff. |
email_change_unavailable | 500 | The platform isn't set up yet. | Try again later. If it persists, contact support with the request ID. |
fresh_auth_required | 403 | Your last sign-in is older than 15 minutes: sign in again first. | Sign in again, then repeat the action within 15 minutes. |
permission_denied | 403 | The caller isn't a person signed in to the console. | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: validation_failed, api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, resource_not_found, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, dry_run_not_supported, internal_error.