
# Add an email address

`POST /fapi/v1/me/emails` · called from the environment's sign-in host

Adds an email address to the authenticated user as an unverified, non-primary address and sends a verification link to it. The address becomes usable once the user opens the link. Every accepted request answers `202` with no body, including when the address is already one of this user's; the answer never shows whether the address is in use on another account. A user holds at most 10 addresses, the primary one included. Requires the authenticated user's `__Host-idp_session` cookie; if the cookie is missing, expired, or revoked, returns `401 unauthenticated`. A first-party app on another origin can instead send its front API access token (`Authorization: DPoP <token>` with a DPoP proof; see [Front API access token](/docs/api/fapi/front-api-token)).

The session must have been verified in the last 5 minutes. If the user has a second factor, the session must also have been opened with a second factor (`urn:idp:acr:mfa`).

## Request

Headers:

| Header | Required | Description |
| --- | --- | --- |
| `Idp-Client` | yes | SDK identifier. |
| `Origin` | yes | Must be exactly `https://<sign-in host>`. |
| `Content-Type` | yes | `application/json`. |

Body:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | string | yes | The address to add (at most 320 characters). |

## Response

`202 Accepted`, no body.

## Errors

| Status | Code | When |
| --- | --- | --- |
| 400 | `malformed_request` | The body is not valid JSON. |
| 400 | `unknown_field` | The body has a field other than `email`. |
| 401 | `unauthenticated` | No valid session cookie. |
| 401 | `step_up_required` | Session was not verified in the last 5 minutes or a second factor is required; re-verify with `max_age=300` (and if applicable, `acr_values`) in the `WWW-Authenticate` header. |
| 403 | `origin_not_allowed` | `Origin` is missing or wrong. |
| 409 | `email_limit_reached` | The user already has 10 email addresses. |
| 413 | `payload_too_large` | The body is too large. |
| 415 | `unsupported_media_type` | `Content-Type` is not `application/json`. |
| 422 | `validation_failed` | `email` is missing. |
| 422 | `email_invalid` | `email` is not a valid email address. |
| 422 | `email_domain_not_allowed` | The environment does not allow addresses in this domain. |
| 429 | `verification_rate_limited` | Too many verification messages were sent recently; try again later. |

## Example

```bash
curl -X POST https://example.keenauth.app/fapi/v1/me/emails \
  -H "Idp-Client: my-app/1.0.0 (node/22.0.0)" \
  -H "Origin: https://example.keenauth.app" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"email": "ada@example.org"}'
```

## Personal data

This endpoint carries personal data: end-user profile. [Personal data in the KeenAuth APIs](/docs/policies/personal-data) describes what is stored, how long it is kept and how it is deleted. Do not send special categories of personal data (health, biometric data, religion, political opinions, sexual orientation) in any field.
