Topolo Docs Topolo Platform
Open workspace

Get my recovery email

Read the caller's personal recovery email status.

Outcome

Read the caller's personal recovery email status.

These examples prove local handler behavior with real isolated SQL and explicitly simulated identity/permission dependencies.

Before you start

  • Verify the intended authenticated identity and the current credential-scoped action before preparing input. Self and managed-user security operations have different authority; a session id does not authorize a different user.

  • Use authorized identity and user/session discovery. Recovery security data and session/device identifiers must remain inside the caller-approved workflow.

Discover the target

topolo whoami --json
topolo apps --json
topolo actions get app_topolo_auth.me.recovery_email.get --detail --json

For user/session actions use the caller subject or a user returned by authorized users discovery, then sessions.list for that exact user. For recovery read me.recovery_email.get before reviewing an approved address. Tenant identity takes no override input.

Input fields

FieldRequiredMeaning

This action accepts exactly {}. Identity and target context come from approved authentication, not additional input fields.

Effects

  • Reads the selected personal recovery record and distinct-email requirement; it does not list all pending addresses.

Interpret the response

Success is HTTP 200 with raw target success/message/data/timestamp. CLI/MCP can wrap or project that response. Record timestamps are epoch seconds; the envelope timestamp is ISO text. These local fixtures simulate token identities, so no response proves live sign-in or browser OAuth recovery.

Recovery read selects the verified personal_recovery row first, then verified/updated time; it is not a list of every pending address. recoveryEmailRequired is based on that selected row verifiedAt. requiresDistinctRecoveryEmail is based on the presence of identity organization memberships, not the currently selected context alone.

A Notify 500/502 can follow a successful pending-email SQL write. Read current recovery status before reviewing a retry, but that read can hide pending rows behind an older verified address. Confirm the requested mailbox through the actual verification journey and preserve the failure evidence; this action family has no pending-address list or cancellation action. An email globally attached to another identity is not reassigned and currently returns SERVER_ERROR.

Missing access tokens return AUTH_ERROR. A thrown invalid-token error currently becomes SERVER_ERROR in these handlers. Session/recovery/logout prefer an access cookie when present; tenant lookup prefers the Bearer header. Do not combine identities across cookie and Bearer transports or infer an OAuth expiry from every 401/500.

Worked examples

These are complete raw target-handler responses, not CLI/gateway envelopes or live authorization proof. Replace synthetic identifiers using authorized discovery. Save only the reviewed input as payload.json; inspect validation and plan before executing. --confirm assumes the intended operation is approved. Storage and response read-back require separate live token rejection, delivery and recipient verification proof where relevant. Cookies and Bearer tokens must identify the intended principal consistently.

No recovery record means verification is required

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions plan app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions call app_topolo_auth.me.recovery_email.get --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.me.recovery_email.get",
    "input": {}
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Recovery email status retrieved successfully",
  "data": {
    "personalRecoveryEmail": null,
    "recoveryEmailRequired": true,
    "primaryEmail": "work@example.test",
    "requiresDistinctRecoveryEmail": true
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Personal identity does not require a distinct work email

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions plan app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions call app_topolo_auth.me.recovery_email.get --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.me.recovery_email.get",
    "input": {}
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Recovery email status retrieved successfully",
  "data": {
    "personalRecoveryEmail": null,
    "recoveryEmailRequired": true,
    "primaryEmail": "personal@example.test",
    "requiresDistinctRecoveryEmail": false
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Pending email remains unverified despite notification acceptance

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions plan app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions call app_topolo_auth.me.recovery_email.get --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.me.recovery_email.get",
    "input": {}
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Recovery email status retrieved successfully",
  "data": {
    "personalRecoveryEmail": {
      "id": "uem_hZa-yhthJUYb",
      "userId": "usr_self",
      "email": "recovery@example.test",
      "kind": "personal_recovery",
      "organizationId": null,
      "verifiedAt": null,
      "verificationExpiresAt": 1790985600,
      "loginEnabled": false,
      "recoveryEnabled": false,
      "createdAt": 1790899200,
      "updatedAt": 1790899200
    },
    "recoveryEmailRequired": true,
    "primaryEmail": "work@example.test",
    "requiresDistinctRecoveryEmail": true
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Read selected verified recovery record; verification state was seeded in the fixture

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions plan app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions call app_topolo_auth.me.recovery_email.get --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.me.recovery_email.get",
    "input": {}
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Recovery email status retrieved successfully",
  "data": {
    "personalRecoveryEmail": {
      "id": "uem_hZa-yhthJUYb",
      "userId": "usr_self",
      "email": "recovery@example.test",
      "kind": "personal_recovery",
      "organizationId": null,
      "verifiedAt": 1790899199,
      "verificationExpiresAt": 1790985600,
      "loginEnabled": true,
      "recoveryEnabled": true,
      "createdAt": 1790899200,
      "updatedAt": 1790899200
    },
    "recoveryEmailRequired": false,
    "primaryEmail": "work@example.test",
    "requiresDistinctRecoveryEmail": true
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Read after Notify failure still selects the prior verified address

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions plan app_topolo_auth.me.recovery_email.get --data @payload.json --json
topolo actions call app_topolo_auth.me.recovery_email.get --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.me.recovery_email.get",
    "input": {}
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Recovery email status retrieved successfully",
  "data": {
    "personalRecoveryEmail": {
      "id": "uem_hZa-yhthJUYb",
      "userId": "usr_self",
      "email": "recovery@example.test",
      "kind": "personal_recovery",
      "organizationId": null,
      "verifiedAt": 1790899199,
      "verificationExpiresAt": 1790985600,
      "loginEnabled": true,
      "recoveryEnabled": true,
      "createdAt": 1790899200,
      "updatedAt": 1790899200
    },
    "recoveryEmailRequired": false,
    "primaryEmail": "work@example.test",
    "requiresDistinctRecoveryEmail": true
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Verify the result

  • Check primaryEmail, requiresDistinctRecoveryEmail, selected email and verifiedAt. A missing or unverified row requires verification; an older verified row does not prove a newly requested pending address is verified.

Errors and recovery

Missing identity is not a recovery record

Captured local refusal · HTTP 404:

{
  "input": {},
  "response": {
    "success": false,
    "error": {
      "message": "User not found",
      "code": "NOT_FOUND",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Anonymous recovery read is refused

Captured local refusal · HTTP 401:

{
  "input": {},
  "response": {
    "success": false,
    "error": {
      "message": "Access token required",
      "code": "AUTH_ERROR",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Published recovery guidance

  • AUTH_ERROR (HTTP 401): Verify the intended identity and access-token transport. Refresh only an expired credential for that same approved context; do not switch organizations automatically.

  • NOT_FOUND (HTTP 404): Refresh authorized user/session discovery or recovery status. Session deletion can also map a storage error to NOT_FOUND; do not claim successful revocation from this response.

  • SERVER_ERROR (HTTP 500): Inspect the original error and current state. Invalid-token exceptions can return 500. A recovery write or token-version bump may already have happened; do not blindly repeat a mutation or claim a delivery/revocation outcome.

Recovery boundaries

Read-only. Keep recovery security data within the intended caller workflow. Discover the verification request separately and obtain approval for its email effect.

Discovery and evidence

This record belongs to app_topolo_auth. Local tests prove real canonical session/recovery email SQL, target-user authorization and handler responses with simulated tokens, identity lookup and Notify results. Verification state is seeded; tokens are unusable. They do not prove live JWT rejection, browser OAuth recovery, email delivery, recipient verification, deployment or production completion.