# Email Account

An *Email Account* is an SMTP sender you register in a *Space*. It is a resource that bundles together the server address to send mail through, the login credentials, and the sending address. When a *Script*'s `EmailSend` statement runs, the actual mail goes out through this *Email Account*. For example, if a clothing-shop online store wants to send a confirmation email whenever an order comes in, you first register an *Email Account* to use for sending and have the *Script* reference it.

An *Email Account* is a *Space*-level resource managed in CMA, based on the path `/spaces/{spaceId}/email-accounts`. It has no publish concept. With no status value or publish step, once you create it you can use it for sending right away. Instead, note that creating one is not a harmless read-only action but an action that **actually sends one email to validate the settings**, and that the connection information (`endpoint`, `username`, `password`) cannot be changed once created; both points are covered below.

## Resource structure {#resource-structure}

The following is the response when you create an *Email Account*. `sys` (system properties) holds the identifier and version, and the body holds the sender settings (`name`, `endpoint`, `username`, `fromAddress`, `fromName`). The password (`password`) does not appear anywhere in the response.

```json
{
  "sys": {
    "id": "3trmXRMdKpLc7GfNbyVQeR2WsT9LnU",
    "type": "EmailAccount",
    "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
    "createdBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-08-04T05:12:44.108Z",
    "updatedBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-08-04T05:12:44.108Z",
    "version": 1
  },
  "name": "Order Notifications",
  "endpoint": {
    "host": "smtp.gmail.com",
    "port": 587,
    "security": "StartTls"
  },
  "username": "orders@example-shop.com",
  "fromAddress": "orders@example-shop.com",
  "fromName": "Clothing Shop Orders"
}
```

Main keys:

- `sys.id`: The unique identifier of the *Email Account*. It goes into `{emailAccountId}` in the single-read, update, and delete paths.
- `sys.version`: The resource version. It starts at 1 and increases each time you make a change. You send this value in the update request via the `X-Weegloo-Version` header (see [Status and constraints](#status-and-constraints) below).
- `name`: The label shown in the console (for example, `Order Notifications`). **It is not used for sending, and it is not the From display name.** It is only a name to tell multiple senders apart.
- `endpoint`: The SMTP server to connect to. It consists of three values: `host`, `port`, and `security`.
- `username`: The SMTP login username. It differs by provider. It may be the email address itself, a fixed string the sending service defines, or a domain-level login.
- `fromAddress`: The sending address. It is used as both the envelope return path (MAIL FROM) and the From address the recipient sees.
- `fromName`: The display name shown in the From header (optional). Without it, only the address appears.

The password (`password`) is a write-only value that you send only in the create request body, so it does not come back in the response above, nor in any later read or list. The `username` comes back in the read response exactly as you entered it.

## System properties (sys) {#system-properties-sys}

Every *Email Account* carries common system properties in the `sys` object. `space`, `createdBy`, and `updatedBy` come in the `Refer` shape (`{ "sys": { "id", "type": "Refer", "targetType" } }`).

| Property | Type | Description |
|---|---|---|
| `id` | string | The resource's unique identifier. |
| `type` | string | The resource kind. For an *Email Account* it is always `"EmailAccount"`. |
| `space` | Refer&lt;Space&gt; | The *Space* this sender belongs to. |
| `createdBy` | Refer&lt;User&gt; | The user who registered it. |
| `createdAt` | string (date-time) | The creation time. |
| `updatedBy` | Refer&lt;User&gt; | The user who last updated it. |
| `updatedAt` | string (date-time) | The last update time. |
| `version` | integer (≥1) | The resource version. On an update you send the current value via the `X-Weegloo-Version` header. |

Body properties:

| Property | Type | Description |
|---|---|---|
| `name` | string (1-64) | The label shown in the console. Not used for sending; not the From display name. |
| `endpoint` | SmtpEndpoint | The SMTP server to connect to (`host`, `port`, `security`). |
| `endpoint.host` | string | The SMTP server host (for example, `smtp.gmail.com`). |
| `endpoint.port` | integer (1-65535) | The SMTP port. By convention `587` pairs with `StartTls` and `465` with `Tls`. |
| `endpoint.security` | string | Transport security. Either `StartTls` or `Tls`. Because the password travels over the wire, plaintext connections are not allowed. |
| `username` | string | The SMTP login username. It differs by provider and may not be an email address. |
| `fromAddress` | string (email, ≤254) | The sending address. Used as the envelope return path (MAIL FROM) and the From header. The server may rewrite it (for example, Gmail forces the authenticated account). |
| `fromName` | string | The From header display name. Optional. Without it, only the address appears. |

Create-request-body-only input:

| Property | Type | Description |
|---|---|---|
| `password` | string | The SMTP login password. **Write-only.** It appears in no response, its value cannot be read back, and it can only be replaced (re-created). Required. |

## Sender info and connection info {#sender-vs-connection}

An *Email Account*'s values fall into two kinds. This distinction determines what you can change.

- **Connection info: `endpoint`, `username`, `password`.** These cannot be changed after creation. To move the sending server or rotate the login credentials, **create a new *Email Account* and delete the old one**. As explained above, the password cannot be read back, so if you lose it, handle it by re-creating rather than resetting.
- **Sender info: `name`, `fromAddress`, `fromName`.** These can still be changed after creation with an update (PUT). Use it to tidy up the label or change the sending address or display name; the connection info stays intact.

## An actual email is sent on creation {#create-sends-a-test-message}

Creating an *Email Account* is not merely an action that stores settings. Before saving, the server actually connects with the `endpoint`, `username`, and `password` you entered and **sends one test email.** The send target is `fromAddress`, and if `username` is a different address, that address may be included as well.

- The resource is saved only if the send succeeds.
- If the server rejects it at any stage of connecting, authenticating, or sending, it fails with **nothing created**, and the response includes the failure reason the server returned.

So note that repeating creation with wrong values attempts an actual send each time.

## Status and constraints {#status-and-constraints}

The value constraints enforced on create and update.

| Target | Constraint |
|---|---|
| `name` | 1-64 chars, required. |
| `endpoint.host` | Required. |
| `endpoint.port` | 1-65535, required. |
| `endpoint.security` | `StartTls` or `Tls`, required. Plaintext not allowed. |
| `username` | Required (on create). Immutable after creation. |
| `password` | Required (on create), write-only. Immutable after creation (replace by re-creating). |
| `fromAddress` | Email format, 254 chars or fewer, required. |
| `fromName` | Optional. |

Rules on behavior and permissions:

- **Connection info is immutable.** The only things `Update` (PUT) can change are `name`, `fromAddress`, and `fromName`. To change `endpoint`, `username`, or `password`, create a new one and delete the old.
- **An update needs the version.** Send the current `sys.version` value in the `Update` request via the `X-Weegloo-Version` header. If the value is not current, it is rejected as a version conflict. In that case, read the resource again and retry with the latest `sys.version`.
- **The password cannot be read back.** It appears in no read or list, so if you lose it, handle it by re-creating rather than resetting.
- **The SMTP servers you can use differ by plan.** The preset provider hosts (Gmail, Naver, Resend, Brevo) can be registered even on lower plans. An arbitrary (self-hosted) host that is not in the presets requires a registered payment method to use. For per-plan policy, see [Pricing](/pricing/pricing.md).

## API {#api}

The base URL for all the endpoints below is `https://cma.weegloo.com/v1`, and the `Authorization` header requires a Bearer token that authenticates to CMA. An update (PUT) additionally requires the `X-Weegloo-Version` header.

```api-endpoint
{
  "title": "List Email Accounts",
  "method": "GET",
  "path": "/spaces/{spaceId}/email-accounts",
  "description": "Reads the list of Email Accounts registered in a Space, page by page. The response does not include the password.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true }
  },
  "queryParameterSchema": {
    "limit": { "type": "integer", "description": "Number of items to return per page (1-100)", "default": 15 },
    "skip": { "type": "integer", "description": "Number of items to skip", "default": 0 },
    "next": { "type": "string", "description": "Next page cursor (the value obtained from links.next in the previous response)" },
    "prev": { "type": "string", "description": "Previous page cursor (the value obtained from links.prev in the previous response)" },
    "order": { "type": "string", "description": "Sort criteria. Comma-separated for multi-level sorting", "default": "sys.createdAt,sys.id" },
    "select": { "type": "string", "description": "Fields to include (sys.id,name) or exclude (-sys.id). Do not mix include and exclude." },
    "include": { "type": "integer", "description": "Related-resource inclusion level. 0=default, 1=related resources, 2=nested relations, 3=full", "default": 0 }
  },
  "additionalQueryParams": true,
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  },
  "responseExample": {
    "sys": { "type": "TotalPageResponse" },
    "limit": 15,
    "totalCount": 1,
    "items": [
      {
        "sys": {
          "id": "3trmXRMdKpLc7GfNbyVQeR2WsT9LnU",
          "type": "EmailAccount",
          "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
          "createdBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
          "createdAt": "2026-08-04T05:12:44.108Z",
          "updatedBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
          "updatedAt": "2026-08-04T05:12:44.108Z",
          "version": 1
        },
        "name": "Order Notifications",
        "endpoint": { "host": "smtp.gmail.com", "port": 587, "security": "StartTls" },
        "username": "orders@example-shop.com",
        "fromAddress": "orders@example-shop.com",
        "fromName": "Clothing Shop Orders"
      }
    ],
    "links": { "self": "/v1/spaces/HnQ32YiH/email-accounts" }
  }
}
```

```api-endpoint
{
  "title": "Create Email Account",
  "method": "POST",
  "path": "/spaces/{spaceId}/email-accounts",
  "description": "Registers a new Email Account in a Space. Before saving, the server actually connects with the entered endpoint, username, and password and sends one test email; if the send fails, nothing is created and it fails with the server's reason in the response. password is write-only, so it does not appear in the response.",
  "responseStatus": 201,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  },
  "requestBodySchema": {
    "type": "object",
    "required": ["name", "endpoint", "username", "password", "fromAddress"],
    "properties": {
      "name": { "type": "string", "minLength": 1, "maxLength": 64, "description": "The label shown in the console (not used for sending)" },
      "endpoint": {
        "type": "object",
        "description": "The SMTP server to connect to",
        "required": ["host", "port", "security"],
        "properties": {
          "host": { "type": "string", "description": "The SMTP host (for example, smtp.gmail.com)" },
          "port": { "type": "integer", "minimum": 1, "maximum": 65535, "description": "The SMTP port (by convention 587=StartTls, 465=Tls)" },
          "security": { "type": "string", "enum": ["StartTls", "Tls"], "description": "Transport security. Plaintext not allowed" }
        }
      },
      "username": { "type": "string", "description": "The SMTP login username (differs by provider and may not be an email address)" },
      "password": { "type": "string", "description": "The SMTP login password. Write-only; not returned in the response" },
      "fromAddress": { "type": "string", "format": "email", "maxLength": 254, "description": "The sending address (envelope return path + From header)" },
      "fromName": { "type": "string", "description": "The From header display name (optional)" }
    },
    "example": {
      "name": "Order Notifications",
      "endpoint": { "host": "smtp.gmail.com", "port": 587, "security": "StartTls" },
      "username": "orders@example-shop.com",
      "password": "wnBk4Qh2Xr7Ta9Lp",
      "fromAddress": "orders@example-shop.com",
      "fromName": "Clothing Shop Orders"
    }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRMdKpLc7GfNbyVQeR2WsT9LnU",
      "type": "EmailAccount",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "createdBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-08-04T05:12:44.108Z",
      "updatedBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-08-04T05:12:44.108Z",
      "version": 1
    },
    "name": "Order Notifications",
    "endpoint": { "host": "smtp.gmail.com", "port": 587, "security": "StartTls" },
    "username": "orders@example-shop.com",
    "fromAddress": "orders@example-shop.com",
    "fromName": "Clothing Shop Orders"
  }
}
```

```api-endpoint
{
  "title": "Get Email Account",
  "method": "GET",
  "path": "/spaces/{spaceId}/email-accounts/{emailAccountId}",
  "description": "Reads a single Email Account by sys.id. The response does not include the password.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "emailAccountId": { "type": "string", "description": "The sys.id of the Email Account", "required": true }
  },
  "queryParameterSchema": {
    "include": { "type": "integer", "description": "Related-resource inclusion level. 0=default, 1=related resources, 2=nested relations, 3=full", "default": 0 }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRMdKpLc7GfNbyVQeR2WsT9LnU",
      "type": "EmailAccount",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "createdBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-08-04T05:12:44.108Z",
      "updatedBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-08-04T05:12:44.108Z",
      "version": 1
    },
    "name": "Order Notifications",
    "endpoint": { "host": "smtp.gmail.com", "port": 587, "security": "StartTls" },
    "username": "orders@example-shop.com",
    "fromAddress": "orders@example-shop.com",
    "fromName": "Clothing Shop Orders"
  }
}
```

```api-endpoint
{
  "title": "Update Email Account",
  "method": "PUT",
  "path": "/spaces/{spaceId}/email-accounts/{emailAccountId}",
  "description": "Updates only the label and sender info (name, fromAddress, fromName) of an Email Account. endpoint, username, and password cannot be changed after creation, so they are not included in the body. Send the current sys.version via the X-Weegloo-Version header; if the value is not current, it is rejected as a version conflict.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "emailAccountId": { "type": "string", "description": "The sys.id of the Email Account", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" },
    "X-Weegloo-Version": { "type": "integer", "description": "The current sys.version of the resource to update" }
  },
  "requestBodySchema": {
    "type": "object",
    "required": ["name", "fromAddress"],
    "properties": {
      "name": { "type": "string", "minLength": 1, "maxLength": 64, "description": "The label shown in the console" },
      "fromAddress": { "type": "string", "format": "email", "maxLength": 254, "description": "The sending address (envelope return path + From header)" },
      "fromName": { "type": "string", "description": "The From header display name (optional)" }
    },
    "example": {
      "name": "Order & Shipping Notifications",
      "fromAddress": "orders@example-shop.com",
      "fromName": "Clothing store support"
    }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRMdKpLc7GfNbyVQeR2WsT9LnU",
      "type": "EmailAccount",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "createdBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-08-04T05:12:44.108Z",
      "updatedBy": { "sys": { "id": "9dLmQ2pVnRb8sTfWcXd3LhJ7gK", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-08-06T01:38:52.671Z",
      "version": 2
    },
    "name": "Order & Shipping Notifications",
    "endpoint": { "host": "smtp.gmail.com", "port": 587, "security": "StartTls" },
    "username": "orders@example-shop.com",
    "fromAddress": "orders@example-shop.com",
    "fromName": "Clothing store support"
  }
}
```

```api-endpoint
{
  "title": "Delete Email Account",
  "method": "DELETE",
  "path": "/spaces/{spaceId}/email-accounts/{emailAccountId}",
  "description": "Deletes an Email Account. On success it responds with 204 No Content and no response body. After deletion, a Script's EmailSend that referenced this sender can no longer send mail through this account. To change the connection info or the login, create a new one and then delete the old.",
  "responseStatus": 204,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "emailAccountId": { "type": "string", "description": "The sys.id of the Email Account", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  }
}
```

## Related documents {#related-documents}

- [Script](/api/reference/script.md): Send mail through this *Email Account* with the `EmailSend` statement.
- [SpaceRole](/api/reference/cma/space-role.md): The role that defines resource-access permissions for this *Space*.
- [Pricing](/pricing/pricing.md): The usage policy for preset provider hosts and arbitrary (self-hosted) SMTP hosts.
