---
title: "Create email user"
method: POST
path: "/v1/email-users"
tags: ["Email Users"]
---

# Create email user

`POST /v1/email-users`

## Request

- Base URL: `https://api.winnr.app`
- URL: `https://api.winnr.app/v1/email-users`
- Auth: HTTP bearer

Create a new email user (mailbox) on a domain you already own.

**This is asynchronous.** The mailbox is created on the mail server by
a background worker, so a successful call returns `200` with a job
receipt (`data.job_id`, `data.status: "pending"`) — *not* the created
mailbox. Poll `GET /v1/jobs/{job_id}` until `status` is `completed`,
then fetch the mailbox with
`GET /v1/email-users?filter[domain]={domain}` (or
`GET /v1/email-users/{user_id}`) to read its password and SMTP/IMAP
connection details.

`domain` is the domain **name** (`talent.example.com`), not the domain
id. See `CreateEmailUserRequest`.

Validation (unknown domain, duplicate address, plan limits, per-domain
caps, password length) happens synchronously and returns `400` before
anything is enqueued — so a `200` means the request was accepted, and
the job can still fail later for mail-server reasons.

See **Asynchronous endpoints** in the introduction for how to reconcile
a timed-out request without creating duplicate mailboxes.

## Request body

- CreateEmailUserRequest
  - `username` string, required: Local part of the email address (before the `@`).
  - `domain` string, required: The domain **name**, exactly as it appears in `name` on the domain resource — e.g. `talent.example.com`. This is **not** the domain id. Passing a domain id here fails with `400 validation_error` / `Domain {value} not found in this account`, even when that id is a real domain on the account. Rule of thumb: domain **ids** are used only in the path of `/v1/domains/{domain_id}/...` routes. Request *bodies* that refer to a domain — including this one and `BulkCreateRequest` — take the domain name.
  - `name` string: Display name used in the `From` header. Derived from `username` if omitted.
  - `password` string: Optional mailbox password; a strong one is generated when omitted. Minimum 8 characters. Read the generated password back from `GET /v1/email-users/{user_id}` once the job completes.

## Response `200`

Mailbox creation accepted and queued. The body is a job receipt,
not the mailbox.

- EmailUserCreateAccepted: Job receipt for a queued mailbox creation. The mailbox does not exist yet when this is returned — poll `GET /v1/jobs/{job_id}`, then read the mailbox (and its password and SMTP/IMAP details) from `GET /v1/email-users/{user_id}`.
  - `data` object
    - `job_id` string: Poll `GET /v1/jobs/{job_id}` for completion.
    - `status` 'pending': Always `pending` — the mailbox has been enqueued, not created.
    - `email` string, email: Full address that will be created (`{username}@{domain}`).
    - `username` string
    - `domain` string: Domain name the mailbox is being created on.
    - `name` string: Display name that will be set on the mailbox.
    - `message` string
    - `prewarmed_billing` object, nullable: Present only when the domain is pre-warmed; describes the $3/addr seat charge.
  - `meta` Meta
    - `request_id` string
    - `timestamp` string, date-time

## Other responses

- `400`: Validation error
- `401`: Authentication required or token invalid
- `409`: Resource conflict

---

[API](https://skmtc.dev/winnr/apis/winnr-api.md) · [All operations](https://skmtc.dev/winnr/apis/winnr-api/llms.txt) · [OpenAPI document](https://skmtc.dev/winnr/apis/winnr-api/revisions/a4f960beb1eb?raw)
