UptimeHunt Docs
Account

Email Management

Manage multiple email addresses on your account, verify emails, set primary email, and configure per-organization contact emails.

Email Management

Overview

Your account can hold multiple verified email addresses — your primary address plus any additional ones you add. This is useful when you want different organizations to receive notifications at different addresses, or when you are preparing to migrate your primary email.

Emails are managed from Settings → Login & Email.

The Email Set

Every account has at least one email address. Addresses on your account fall into three states:

StateMeaning
Primary + verifiedYour main contact and sign-in address. Shown in every org context by default.
Secondary + verifiedAdditional addresses you own. Can be promoted to primary or assigned as a per-org contact email.
PendingAdded but not yet verified. Cannot be used as a contact email or promoted to primary.

The API exposes the email set on GET /api/v1/auth/me in the emails[] array:

{
  "data": {
    "emails": [
      { "email": "alice@example.com", "verified": true,  "is_primary": true  },
      { "email": "alice@work.com",    "verified": true,  "is_primary": false },
      { "email": "alice@new.com",     "verified": false, "is_primary": false }
    ]
  }
}

Adding an Email Address

Adding an address puts it in pending state and sends a verification link to that address. The address cannot be used for anything until it is verified.

curl -X POST https://app.uptimehunt.io/api/v1/auth/account/emails \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"email": "alice@work.com"}'

Response (201 Created):

{ "data": { "emails": [ /* updated email set */ ] } }

Idempotent for pending addresses. Posting an address that is already pending (not yet verified) returns 200 OK and resends the verification email — use this if the first link expired.

Error cases:

CodeHTTPMeaning
already_owned409This address is already verified on your account.
email_already_exists409Another account already uses this address as its password-login email.
invalid_email422The address is syntactically invalid or missing.

Verifying an Added Email

The verification link in the email calls GET /api/v1/auth/account/emails/verify?token=…. This is a browser redirect target: you do not call it via the API — click the link, and the server marks the address verified then redirects you to account settings:

  • Success: /settings/account?email_verified=1
  • Failure: /settings/account?email_verify_error=invalid (bad/expired token)
  • Conflict: /settings/account?email_verify_error=conflict (another account claimed the address between the time you added it and the time you clicked the link)

Verification links are single-use. If the link has expired, re-post the address to receive a fresh one.

Re-checking a conflict

If your verification lands at email_verify_error=conflict, the race was lost — another password-realm account registered that address as its primary between your add and your click. Remove the pending address and contact the other account, or choose a different address.

Setting a Primary Email

Promote a verified secondary address to primary. The new primary must satisfy every organization's member-email-domain policy (see Per-Org Domain Policy below). If any organization you belong to would reject the new primary, the change is refused and the offending organization is named.

curl -X PATCH \
  "https://app.uptimehunt.io/api/v1/auth/account/emails/alice%40work.com" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"primary": true}'

Passing {"primary": false} is a documented no-op — the response is the current email set unchanged.

Error cases:

CodeHTTPMeaning
email_not_verified409The address is still pending — verify it first.
member_email_policy_violation422An org you belong to does not allow this domain as a member email. The org field names the offending org.
NOT_FOUND404The address is not on your account.

After a successful primary change, auth.User.email is updated, and if you have a password login method, its email claim is updated to match so the password sign-in lookup stays consistent.

Removing an Email Address

curl -X DELETE \
  "https://app.uptimehunt.io/api/v1/auth/account/emails/alice%40old.com" \
  -H "Authorization: Bearer {access_token}"

Three guards prevent the removal:

CodeHTTPMeaning
primary_email409This is your primary address. Promote another verified address to primary first, then remove this one.
last_email409This is your only address. Add and verify another one first.
identity_email409This address backs a password login method. Change that method's email first (i.e. make another address primary so the password method re-keys to it), then remove.

When a secondary address is removed, any per-org contact email (member_email) that pointed to it is cleared automatically — the affected memberships fall back to your account primary.

Per-Org Contact Email

Each of your organization memberships has an effective email — the address that organization sees for contact, notifications, and audit display. By default this is your account primary, but you can override it per organization using a different verified address you own.

Viewing the Contact Email

curl https://app.uptimehunt.io/api/v1/orgs/acme/members/{user_id}/email \
  -H "Authorization: Bearer {access_token}"

Returns member_email (the explicit override, or null) and effective_email (the resolved address — the override when set, else your account primary):

{
  "data": {
    "user_id": 42,
    "member_email": "alice@work.com",
    "effective_email": "alice@work.com"
  }
}

member_email: null means no override is set and effective_email equals your account primary.

Who can read this

The member themselves, plus any org member with the member.view capability (Admin, Owner), can read the contact email. Write is self-service only — only the member can change their own contact email; org admins cannot override it on your behalf.

Setting a Per-Org Contact Email

You can override your contact email to any verified address on your account, subject to the org's domain policy:

curl -X PUT https://app.uptimehunt.io/api/v1/orgs/acme/members/{user_id}/email \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"email": "alice@work.com"}'

To clear the override (revert to your account primary):

curl -X PUT https://app.uptimehunt.io/api/v1/orgs/acme/members/{user_id}/email \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"email": null}'

Constraints:

  • The address must be in your account's verified email set. Pending (unverified) addresses are rejected.
  • The domain must be allowed by the org's member-email-domain policy (if the org has one).

Error cases:

CodeHTTPMeaning
email_not_in_account422The address is not on your account. Add and verify it first.
email_not_verified422The address exists on your account but has not been verified yet.
member_email_policy_violation422The domain is not on the org's allowed-domains list.
member_email_self_only403Only the member can set their own contact email.

Per-Org Domain Policy

An organization can restrict which email domains its members may use as their org-facing contact email. This is the allowed_member_email_domains policy on the organization.

  • What it gates: only the org-facing contact email (the member_email override and the account primary when it acts as the fallback). It does not affect sign-in or which addresses you can add to your account.
  • Empty list means no restriction (the default). Any verified address may be used.
  • Applied at write time. Existing members are not retroactively affected when an org first sets the policy.
  • Applies to primary promotion. When you promote a secondary address to primary, the new primary is checked against all orgs' policies you belong to. If any org rejects the domain, the promotion is blocked and the offending org is named in the error.
  • Separate from DNS-verified routing domains. This list is declared by the org admin (no DNS verification required) and is entirely distinct from the DNS-verified email routing domains used for SSO routing and from the per-IdP allowed_email_domains JIT filter.

To set the org policy (Owner only, via PATCH /api/v1/orgs/{slug}):

curl -X PATCH https://app.uptimehunt.io/api/v1/orgs/acme \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"allowed_member_email_domains": ["acme.com", "acme.io"]}'

Pass [] to remove all restrictions.

Invitation Signup and the Contact Email

When a new account is created through an invitation link, the invited email becomes the account primary. The per-org contact email override (member_email) is not explicitly set — it remains null, so effective_email resolves to the account primary via the null-fallback path. The net result is the same address, but a call to GET /orgs/{slug}/members/{user_id}/email will return member_email: null, effective_email: "invited@example.com", not a stored override. No manual action is needed.

Required Override (Domain Policy Enforcement)

If an organization introduces an allowed_member_email_domains policy after you are already a member, your existing contact email is not automatically changed. However, the next time you set or promote an email in this organization's context, the new policy will be applied. Org owners can request that existing members update their contact email via out-of-band communication — there is no forced-update mechanism.

Audit Events

EventTrigger
auth.email.addedA pending address is successfully verified.
auth.email.primary_changedYour primary email is changed.
auth.email.removedA secondary address is removed from your account.
member.org_email_setYour per-org contact email is changed (including SET_NULL clears).

These appear in both your personal audit log (GET /api/v1/audit-log) and in the relevant organization's audit log (GET /api/v1/orgs/{slug}/audit-log).

On this page