# Save custom email server (/docs/api-reference/reseller-identity/saveResellerIdentitySmtp)

> Send your clients' emails through your own email server, so they come from your domain. The server is checked with a live login before anything is saved. If the login fails, nothing changes and the response is 400 with the reason. Save your brand first.

> **Reseller accounts only.** [Request access](https://omnidim.io/contact-us?reason=reseller_api&lock=1).

**POST** `/reseller/identity/smtp/save`

Send your clients' emails through your own email server, so they
come from your domain. The server is checked with a live login
before anything is saved. If the login fails, nothing changes and
the response is `400` with the reason. Save your brand first.

Who may call: a key whose user is the owner or an admin of a
reseller organization that can hold a brand and use a custom email
server. Any other user gets `403`.

`host` and `port` are required. `encryption` is `starttls` (the
default), `ssl` or `none`. If you leave `password` blank and a
server is already saved, the saved password is used. The password
is never returned.

The response is the full brand state, the same object that
`GET /reseller/identity` returns, with `smtp.active` set to `true`.
Use `POST /reseller/identity/smtp/test` to check a server without
saving it, and `POST /reseller/identity/smtp/disable` to stop
using it.

Errors: `400 invalid_request` when no brand is saved yet, when
`host` or `port` is missing, when `encryption` is not one of the
three values, or when the login fails. `401` for a missing or
invalid key. `403 forbidden` when the user is not the owner or an
admin, or the account cannot hold a brand or use a custom email
server. `500 server_error` for a server error.

```yaml
operationId: saveResellerIdentitySmtp
requestBody:
  required: true
  content:
    application/json:
      schema:
        type: object
        required:
          - host
          - port
        properties:
          host:
            type: string
            description: Email server host name.
          port:
            type: integer
            description: Email server port, usually 587 for `starttls` or 465 for `ssl`.
          username:
            type: string
            description: Login name.
          password:
            type: string
            description: Login password. Leave it blank to use the saved password.
          encryption:
            type: string
            enum:
              - starttls
              - ssl
              - none
            default: starttls
          from_email:
            type: string
            description: Address your clients' emails are sent from.
      example:
        host: smtp.acme.example
        port: 587
        username: mailer@acme.example
        password: app-password
        encryption: starttls
        from_email: hello@acme.example
responses:
  '200':
    description: The server was saved and is in use. The body is the full brand state.
    content:
      application/json:
        schema:
          type: object
          description: Your brand and custom email server state. The SMTP password is never returned.
          properties:
            success:
              type: boolean
            can_use_brand_identity:
              type: boolean
              description: Whether this account may hold a brand. When `false`, every write returns `403`.
            can_use_custom_smtp:
              type: boolean
              description: Whether this account may send clients' emails through its own email server.
            has_identity:
              type: boolean
              description: '`false` until the first save.'
            identity:
              type: object
              description: The saved brand. Empty until the first save. Other branding keys can appear.
              additionalProperties: true
              properties:
                platform_name:
                  type: string
                company_name:
                  type: string
                logo_url:
                  type: string
                primary_color:
                  type: string
                real_email:
                  type: string
            smtp:
              type: object
              properties:
                configured:
                  type: boolean
                  description: A server is saved.
                active:
                  type: boolean
                  description: Clients' emails go out through the saved server now.
                host:
                  type: string
                port:
                  type: integer
                username:
                  type: string
                encryption:
                  type: string
                  enum:
                    - starttls
                    - ssl
                    - none
                from_email:
                  type: string
        example:
          success: true
          can_use_brand_identity: true
          can_use_custom_smtp: true
          has_identity: true
          identity:
            platform_name: Acme Voice
            company_name: Acme Ltd
            real_email: hello@acme.example
          smtp:
            configured: true
            active: true
            host: smtp.acme.example
            port: 587
            username: mailer@acme.example
            encryption: starttls
            from_email: hello@acme.example
  '400':
    description: |
      No brand is saved yet, a field is missing or invalid, or the
      login to the server failed. `error_description` gives the reason.
    content:
      application/json:
        schema:
          type: object
          properties:
            error:
              type: string
              description: Machine-readable error code.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: |
                Stable, specific reason. Present on the newer endpoints (Voice
                cloning, WhatsApp); older endpoints return only `error`.
            request_id:
              type: string
              description: |
                Correlates this response with the server log. Present alongside
                `code`. Also sent as the `X-Request-Id` header.
        example:
          error: invalid_request
          error_description: Save your brand before connecting an email server.
  '401':
    description: Missing or invalid API key.
  '403':
    description: |
      The key's user is not the owner or an admin of the organization,
      or the account cannot hold a brand or use a custom email server.
    content:
      application/json:
        schema:
          type: object
          properties:
            error:
              type: string
              description: Machine-readable error code.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: |
                Stable, specific reason. Present on the newer endpoints (Voice
                cloning, WhatsApp); older endpoints return only `error`.
            request_id:
              type: string
              description: |
                Correlates this response with the server log. Present alongside
                `code`. Also sent as the `X-Request-Id` header.
        example:
          error: forbidden
          error_description: Brand settings are not available for your account.
  '500':
    description: Server error.
    content:
      application/json:
        schema:
          type: object
          properties:
            error:
              type: string
              description: Machine-readable error code.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: |
                Stable, specific reason. Present on the newer endpoints (Voice
                cloning, WhatsApp); older endpoints return only `error`.
            request_id:
              type: string
              description: |
                Correlates this response with the server log. Present alongside
                `code`. Also sent as the `X-Request-Id` header.
        example:
          error: server_error
          error_description: Something went wrong. Please try again.
```

**Python SDK**

```python
from omnidimension import Client
client = Client(api_key)

state = client.reseller.save_identity_smtp(
    host="smtp.acme.example",
    port=587,
    username="mailer@acme.example",
    password="app-password",
    encryption="starttls",
    from_email="hello@acme.example",
)["json"]
print(state["smtp"]["active"])
```

**curl**

```bash
curl -X POST "https://backend.omnidim.io/api/v1/reseller/identity/smtp/save" \
  -H "Authorization: Bearer $OMNIDIM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "host": "smtp.acme.example",
  "port": 587,
  "username": "mailer@acme.example",
  "password": "app-password",
  "encryption": "starttls",
  "from_email": "hello@acme.example"
}'
```