SMTP Credentials

Route Blue's outbound mail through your own SMTP server, with a live connection test and a standalone verify call.


Route the transactional email Blue sends on your behalf through your own SMTP server instead of Blue’s. Store your mail server’s connection details once, and Blue uses them to deliver invitations, notifications, and other outbound mail with your own sending domain and reputation.

Mail-routing settings are SmtpCredential objects in the API, scoped to an organization (Company). Use createSmtpCredential to store a server, smtpCredentials to read them back, updateSmtpCredential / deleteSmtpCredential to manage them, and verifySmtpCredential to test a connection without saving anything.

The password is returned in plaintext on read

The stored password is encrypted at rest, but the smtpCredentials query decrypts it and returns SmtpCredential.password in plaintext in the response. This is only ever exposed to authorized members of the organization, but treat the query’s output as a secret: do not log it, cache it, or surface it in a client you don’t control.

All four mutations on this page require the organization to have the company-level white_label feature enabled — membership alone is not enough. The smtpCredentials query requires only that you are a member of the organization. See Permissions.

The SmtpCredential type

FieldTypeDescription
idID!Unique identifier.
uidString!Short public identifier.
hostStringSMTP server hostname (e.g. smtp.example.com).
portIntSMTP port. Defaults to 587 when omitted on a connection test.
usernameStringSMTP auth username.
passwordStringSMTP auth password. Encrypted at rest; decrypted and returned in plaintext by the smtpCredentials query.
senderNameStringDisplay name on outbound mail. The literal value blue is reserved.
senderEmailStringFrom-address on outbound mail. Any address containing @blue.cc is reserved.
verifiedAtDateTimeWhen the connection was last verified successfully, or null if the most recent attempt failed. Stamped automatically on create and update.
createdAtDateTimeCreation timestamp.
updatedAtDateTimeLast-update timestamp.

Create credentials

Use the createSmtpCredential mutation to store a mail server for an organization. companyId, host, port, username, and password are required; senderName and senderEmail are optional.

On create, Blue encrypts the password, then immediately attempts a live connection to the server with the supplied credentials. If the connection succeeds, verifiedAt is set to the current time; if it fails, verifiedAt is left null. The mutation still returns the created SmtpCredential either way — inspect verifiedAt to know whether the server is actually usable.

Reserved sender values

senderName equal to blue (case-insensitive) is rejected with SMTP_CREDENTIAL_RESERVED_SENDER_NAME, and any senderEmail containing @blue.cc (case-insensitive) is rejected with SMTP_CREDENTIAL_RESERVED_SENDER_EMAIL. These keep white-label mail from impersonating Blue’s own domain.

Request

mutation CreateSmtpCredential {
  createSmtpCredential(
    input: {
      companyId: "company_123"
      host: "smtp.example.com"
      port: 587
      username: "[email protected]"
      password: "YOUR_SMTP_PASSWORD"
      senderName: "Acme"
      senderEmail: "[email protected]"
    }
  ) {
    id
    uid
    host
    port
    senderName
    senderEmail
    verifiedAt
  }
}

companyId accepts an organization ID or its slug.

Parameters

CreateSmtpCredentialInput

ParameterTypeRequiredDescription
companyIdString!YesOrganization that owns the credential. Must have the white_label feature.
hostString!YesSMTP server hostname.
portInt!YesSMTP port (commonly 587 for STARTTLS or 465 for SMTPS).
usernameString!YesSMTP auth username.
passwordString!YesSMTP auth password. Encrypted before storage.
senderNameStringNoDisplay name on outbound mail. The value blue is reserved.
senderEmailStringNoFrom-address on outbound mail. Addresses containing @blue.cc are reserved.

Response

A successful connection stamps verifiedAt:

{
  "data": {
    "createSmtpCredential": {
      "id": "clm4n8qwx000008l0g4oxdqn7",
      "uid": "smtp_8f3a2c1e",
      "host": "smtp.example.com",
      "port": 587,
      "senderName": "Acme",
      "senderEmail": "[email protected]",
      "verifiedAt": "2026-05-29T14:22:05.000Z"
    }
  }
}

If the live connection fails, the credential is still created but verifiedAt is null:

{
  "data": {
    "createSmtpCredential": {
      "id": "clm4n8qwx000008l0g4oxdqn7",
      "uid": "smtp_8f3a2c1e",
      "host": "smtp.example.com",
      "port": 587,
      "senderName": "Acme",
      "senderEmail": "[email protected]",
      "verifiedAt": null
    }
  }
}

Returns

SmtpCredential! — see The SmtpCredential type.

Errors

CodeWhen
SMTP_CREDENTIAL_RESERVED_SENDER_NAMEsenderName is blue (case-insensitive).
SMTP_CREDENTIAL_RESERVED_SENDER_EMAILsenderEmail contains @blue.cc (case-insensitive).
FORBIDDENYou are not an OWNER or ADMIN of the organization.
PRO_REQUIREDThe organization does not have the white_label feature enabled.

List credentials

Use the smtpCredentials query to page through the SMTP credentials stored for the organization in the X-Bloo-Company-ID header. Results are scoped to that organization; only its members can read them.

This query returns the password in plaintext

SmtpCredential.password comes back decrypted from this query. Request it only when you need it, and never expose the response to an untrusted client.

Request

query SmtpCredentials {
  smtpCredentials(skip: 0, take: 20) {
    items {
      id
      host
      port
      username
      senderName
      senderEmail
      verifiedAt
    }
    pageInfo {
      totalItems
      totalPages
      page
      perPage
      hasNextPage
      hasPreviousPage
    }
  }
}

Parameters

ParameterTypeRequiredDescription
skipIntNoNumber of records to skip. Defaults to 0.
takeIntNoPage size. Defaults to 20.

Response

{
  "data": {
    "smtpCredentials": {
      "items": [
        {
          "id": "clm4n8qwx000008l0g4oxdqn7",
          "host": "smtp.example.com",
          "port": 587,
          "username": "[email protected]",
          "senderName": "Acme",
          "senderEmail": "[email protected]",
          "verifiedAt": "2026-05-29T14:22:05.000Z"
        }
      ],
      "pageInfo": {
        "totalItems": 1,
        "totalPages": 1,
        "page": 1,
        "perPage": 20,
        "hasNextPage": false,
        "hasPreviousPage": false
      }
    }
  }
}

SmtpCredentialPagination

FieldTypeDescription
items[SmtpCredential!]!The credentials on this page.
pageInfoPageInfo!Pagination metadata (totalItems, totalPages, page, perPage, hasNextPage, hasPreviousPage).

Errors

CodeWhen
FORBIDDENYou are not a member of the organization in X-Bloo-Company-ID.

Update credentials

Use the updateSmtpCredential mutation to change a stored server. Only id is required; every other field is optional and only the fields you pass are changed. As with create, Blue runs a live connection test after the update and re-stamps verifiedAt (success) or clears it to null (failure).

Password handling on update is specific:

  • Pass a non-empty password to set a new one (it is re-encrypted).
  • Pass "" (empty string) or null to clear the stored password.
  • Omit password entirely to leave the existing one unchanged.

The same reserved-value rules apply: senderName of blue and any senderEmail containing @blue.cc are rejected.

Request

mutation UpdateSmtpCredential {
  updateSmtpCredential(
    input: { id: "smtp_123", host: "smtp.new-provider.example.com", port: 465 }
  ) {
    id
    host
    port
    verifiedAt
  }
}

Parameters

UpdateSmtpCredentialInput

ParameterTypeRequiredDescription
idString!YesThe credential to update.
hostStringNoNew SMTP hostname.
portIntNoNew SMTP port.
usernameStringNoNew SMTP auth username.
passwordStringNoNew password. Empty string or null clears it; omitting leaves it unchanged.
senderNameStringNoNew display name. The value blue is reserved.
senderEmailStringNoNew from-address. Addresses containing @blue.cc are reserved.

Response

{
  "data": {
    "updateSmtpCredential": {
      "id": "clm4n8qwx000008l0g4oxdqn7",
      "host": "smtp.new-provider.example.com",
      "port": 465,
      "verifiedAt": "2026-05-29T15:01:40.000Z"
    }
  }
}

Returns

SmtpCredential! — see The SmtpCredential type.

Errors

CodeWhen
SMTP_CREDENTIAL_NOT_FOUNDNo credential with the given id exists.
SMTP_CREDENTIAL_RESERVED_SENDER_NAMEsenderName is blue (case-insensitive).
SMTP_CREDENTIAL_RESERVED_SENDER_EMAILsenderEmail contains @blue.cc (case-insensitive).
FORBIDDENYou are not an OWNER or ADMIN of the organization that owns the credential.
PRO_REQUIREDThe organization does not have the white_label feature enabled.

Delete credentials

Use the deleteSmtpCredential mutation to permanently remove a stored server. Once deleted, Blue falls back to sending mail from its own infrastructure for that organization. This mutation returns Boolean (true on success) and takes no sub-selection.

Request

mutation DeleteSmtpCredential {
  deleteSmtpCredential(id: "smtp_123")
}

Parameters

ParameterTypeRequiredDescription
idString!YesThe credential to delete.

Response

{ "data": { "deleteSmtpCredential": true } }

Errors

CodeWhen
SMTP_CREDENTIAL_NOT_FOUNDNo credential with the given id exists.
FORBIDDENYou are not an OWNER or ADMIN of the organization that owns the credential.
PRO_REQUIREDThe organization does not have the white_label feature enabled.

Verify without saving

Use the verifySmtpCredential mutation to test a set of connection details without storing anything. It opens a connection to the server with the supplied values and returns Boolean!true if the server accepts the connection and credentials, false otherwise. Nothing is persisted and no SmtpCredential is created, so this is the right call for validating a form before you save.

Every field on the input is optional. If you omit port, the test defaults to 587. This mutation returns Boolean! and takes no sub-selection.

Request

mutation VerifySmtpCredential {
  verifySmtpCredential(
    input: {
      host: "smtp.example.com"
      port: 587
      username: "[email protected]"
      password: "YOUR_SMTP_PASSWORD"
    }
  )
}

Parameters

VerifySmtpCredentialInput

ParameterTypeRequiredDescription
hostStringNoSMTP server hostname.
portIntNoSMTP port. Defaults to 587 when omitted.
usernameStringNoSMTP auth username.
passwordStringNoSMTP auth password.

Response

{ "data": { "verifySmtpCredential": true } }

A failed connection returns false rather than erroring:

{ "data": { "verifySmtpCredential": false } }

Errors

CodeWhen
FORBIDDENYou are not an OWNER or ADMIN of the organization.
PRO_REQUIREDThe organization does not have the white_label feature enabled.

Permissions

Access to this resource is asymmetric:

  • Mutations (createSmtpCredential, updateSmtpCredential, deleteSmtpCredential, verifySmtpCredential) require you to be an OWNER or ADMIN of the organization and require the organization to have the white_label feature enabled. Missing membership/role yields FORBIDDEN; a missing feature yields PRO_REQUIRED. White-label is bundled with the Pro plan — see the section overview.
  • The smtpCredentials query requires only that you are a member of the organization in X-Bloo-Company-ID (any CompanyUser row). It does not require the white_label feature. Because it returns the decrypted password, treat its output as sensitive.