Manage Email Addresses
Provides the essentials to give your users their own email address with the privacy and security benefits of a Sudo
Email addresses are a core component of the Email SDK. Addresses for different configured domains can be provisioned and used to communicate with other recipients.
Provisioning an email address is a two-step process. First, a check should be performed to determine if the email address is valid and available. Once results are returned and the desired address is selected, the address can be provisioned to a Sudo.
When provisioning a new email address for your user, a domain is needed to ensure the email address will be valid. The Sudo Platform email service can be configured to support issuing email addresses for multiple domains.
Each project in your Sudo Platform account can be configured to support a set of email domains. Your solutions engineer can assist you in configuring DNS entries for domains you own or you can have the Sudo Platform do that on your behalf.
A call to the
getSupportedEmailDomains
method provides a list of supported domains for provisioning an email address.It is required that
CachePolicy
set to RemoteOnly
be used before CacheOnly
for at least one successful call to the service.TypeScript
Swift
Kotlin
try {
const domains = await emailClient.getSupportedEmailDomains(
CachePolicy.RemoteOnly
)
// `domains` contains a list of supported domains to be used for email address provisioning.
} catch {
// Handle/notify user of errors
}
do {
let domains = try await self.getSupportedEmailDomains(
cachePolicy: .remoteOnly
)
/// `domains` contains a list of supported domains to be used for email address provisioning.
} catch {
/// Handle/notify user of errors
}
launch {
try {
val domains = withContext(Dispatchers.IO) {
emailClient.getSupportedEmailDomains(CachePolicy.REMOTE_ONLY)
}
// [domains] contains a list of supported domains to be used for email address provisioning.
} catch (e: EmailAddressException) {
// Handle/notify user of exception
}
}
When choosing a unique email address, it is important to give your user feedback as to whether the email address they are attempting to provision is valid or not. This is achieved by using the
checkEmailAddressAvailability
method.The first input property,
localParts
, takes in a set of local parts to validate and check if they are available. If any of the local parts are invalid or the input contains more than five local parts to check, an invalid argument error will be returned.The second input property,
domains
, should be a set of email domains exclusively supported by the email service. It is recommended to use the getSupportedEmailDomains
method to retrieve this set. If an unsupported domain is supplied, an invalid email domain error will be returned.TypeScript
Swift
Kotlin
try {
const localParts = Set(['johndoe', 'jane.citizen'])
const domains = await emailClient.getSupportedEmailDomains(
CachePolicy.RemoteOnly
)
const emailAddresses = await emailClient.checkEmailAddressAvailability({
localParts,
domains,
})
// For example, if the domains list is:
// [
// "example.com",
// "sudoplatform.com"
// ]
// And all emails are available for both domains, this would return a result
// that looks like this:
// [
// "[email protected]",
// "[email protected]",
// "[email protected]",
// "[email protected]"
// ]
} catch {
// Handle/notify user of errors
}
let localParts = ["johndoe", "jane.citizen"]
/// In reality, this would be a subset of the result of `getSupportedDomains`.
let supportedDomains = ["example.com", "sudoplatform.com"]
do {
let checkAddressInput = CheckEmailAddressAvailabilityInput(
localParts: [localPart],
domains: [domain]
)
let validAddresses = try await emailClient.checkEmailAddressAvailability(
withInput: checkAddressInput
)
/// If all emails were available for both domains, this would return a result that looks like this:
/// [
/// "[email protected]",
/// "[email protected]",
/// "[email protected]",
/// "[email protected]"
/// ]
} catch {
/// Handle/notify user of error
}
launch {
try {
val localParts = listOf("johndoe", "jane.citizen")
val supportedDomains = emailClient.getSupportedEmailDomains()
val input = CheckEmailAddressAvailabilityInput(
localParts = localParts,
domains = supportedDomains
)
val emailAddresses = emailClient.checkEmailAddressAvailability(input)
// If all emails are available for both domains,
// this would return a result that looks like this:
// [
// "[email protected]",
// "[email protected]",
// "[email protected]",
// "[email protected]"
// ]
} catch (e: EmailAddressException) {
// Handle/notify user of error
}
}
All email addresses will be lower-cased in the return result. For example a local part input of
JoHnDoE
would be returned as johndoe...
.Once an available email address has been found, it can be used to provision a valid email address for a Sudo. An email address can be provisioned by calling the
provisionEmailAddress
method and will return the newly provisioned email address object.The input email address must be valid and available, so it is highly recommended that you use the Check Email Address Availability API to validate the email address first.
An
ownershipProofToken
is required as part of the input. This ties together the Sudo and email address such that the Sudo becomes the owner of the email address. Use the getOwnershipProof
method on the SudoProfilesClient
in the Sudo Profiles SDK in order to obtain an ownershipProofToken
. See the Sudo section for more information.An optional
alias
can also be provided as part of the input to provision an email address. The alias can be updated after initially provisioning the email address as discussed in the Updating Metadata of an Email Address section.When an email address is provisioned, a set of standard email folders is also created and associated with the newly provisioned email address. Find out more about managing email folders here.
TypeScript
Swift
Kotlin
const emailAddressInput: string = // Found via the check email address availability API
const ownershipProofToken: string = // Found via the get ownership proof API (See "Sudos" section)
try {
const emailAddress = await emailClient.provisionEmailAddress({
emailAddressInput,
ownershipProofToken,
alias: 'John Smith' // Optionally supply an alias
})
} catch {
// Handle/notify user of errors
}
let emailAddress = self.input.emailAddress /// String of the form "\(localPart)@\(domain)"
let ownershipProofToken = self.input.ownershipProofToken /// Found via the get ownership proof API (See "Sudos" section)
do {
let provisionAddressInput = ProvisionEmailAddressInput(
emailAddress: emailAddress,
ownershipProofToken: ownershipProofToken,
alias: "Fred Smith" /// optional alias for the provisioned email address
)
let provisionedEmailAddress = try await emailClient.provisionEmailAddress(
withInput: provisionAddressInput
)
/// `provisionedEmailAddress` contains the newly provisioned email address.
} catch {
/// Handle/notify user of error
}
val emailAddress: String = // Found via the check email address availability API
val ownershipProofToken: String = // Found via the getOwnershipProof API (See "Sudos" section)
launch {
try {
val input = ProvisionEmailAddressInput(
emailAddress = emailAddress,
ownershipProofToken = ownershipProofToken,
alias = 'John Smith' // Optionally supply an alias
)
val emailAddress = withContext(Dispatchers.IO) {
emailClient.provisionEmailAddress(input)
}
// The returned [emailAddress] has been provisioned
} catch (e: EmailAddressException) {
// Handle/notify user of exception
}
}
In order to be able to provision an email address, the user must be entitled. To provision an email address the following entitlement checks are performed:
- 1.The user must not have more Sudo Profiles than permitted by their
sudoplatform.sudo.max
entitlement. - 2.The user is entitled to provision email addresses by the
sudoplatform.email.emailAddressUserEntitled
entitlement. - 3.The Sudo Profile against which the new email address is to be provisioned has at least 1 remaining
sudoplatform.email.emailAddressMaxPerSudo
entitlement to consume.
If these entitlements' checks do not succeed, the
provisionEmailAddress
API fails with an insufficient entitlements error.See Email Entitlements for an overview of how the Email service integrates with the Sudo Platform Entitlements system.
An email address can be deprovisioned using the
deprovisionEmailAddress
method by passing in the id
of an existing email address object. The email address object that was deprovisioned will be returned and will no longer be usable for provisioning another email address.By deprovisioning the email address, the user's address and all associated user data including messages and folders will be deleted; the email address will no longer be usable. The deprovisioned address will also be held indefinitely and be blocked for re-use from a subsequent provision call.
TypeScript
Swift
Kotlin
// Collect the input email address id however makes sense for your implementation.
const emailAddressId = emailAddress.id
try {
const emailAddress = await emailClient.deprovisionEmailAddress(
emailAddressId
)
// The returned `emailAddress` has now been deprovisioned.
} catch {
// Handle/notify user of errors
}
/// Collect the input email address id however makes sense for your implementation.
let provisionedEmailAddressId = self.input.emailAddressId
do {
let deprovisionedEmailAddress = try await emailClient.deprovisionEmailAddress(
provisionedEmailAddressId
)
/// `deprovisionedEmailAddress` is the record that was just deprovisioned.
} catch {
/// Handle/notify user of error
}
// Collect the input email address id however makes sense for your implementation.
val emailAddressId = emailAddress.id
launch {
try {
val emailAddress = withContext(Dispatchers.IO) {
emailClient.deprovisionEmailAddress(emailAddressId)
}
// The returned [emailAddress] has now been deprovisioned.
} catch (e: EmailAddressException) {
// Handle/notify user of exception
}
}
The metadata of an email address object can be updated by calling the
updateEmailAddressMetadata
method. Currently, the only attribute that can be updated on an email address object is the alias
. The alias
is an encrypted optional attribute on the email address object which can be modified by the user.TypeScript
Swift
Kotlin
// Collect the input email address id however makes sense for your implementation.
try {
const id = await emailClient.updateEmailAddressMetadata({
id,
values: { alias: 'John Smith' },
})
// `id` contains the identifier of the newly updated email address object.
} catch {
// Handle/notify user of errors
}
/// Collect the input email address id however makes sense for your implementation.
let emailAddressId = input.emailAddress.id
let updateEmailAddressMetadataInput = UpdateEmailAddressMetadataInput(
id: emailAddress.id,
values: UpdateEmailAddressMetadataValues(alias: "newAlias")
)
do {
let updatedEmailAddressId = try await client.updateEmailAddressMetadata(
withInput: updateEmailAddressMetadataInput
)
/// `updatedEmailAddressId` contains the identifier of the newly updated email address object.
} catch {
/// Handle/notify user of error
}
/// Collect the input email address id however makes sense for your implementation.
val emailAddressId = emailAddress.id
launch {
try {
val input = UpdateEmailAddressMetadataInput(
id = emailAddress.id,
alias = "newAlias"
)
val updatedEmailAddressId = withContext(Dispatchers.IO) {
emailClient.updateEmailAddressMetadata(input)
}
// The returned [updatedEmailAddressId] contains the identifier of the newly updated email address object.
} catch (e: EmailAddressException) {
// Handle/notify user of exception
}
}
Previously provisioned email addresses can be accessed in two ways: via its identifier (Single Email Address by Id), or via a broad multi access method (Multiple Provisioned Email Addresses).
If an email address has been provisioned and then deprovisioned, it will no longer be available via the methods discussed in this section.
A fetch of single or multiple email addresses can be performed remotely or locally by specifying the appropriate CachePolicy as part of the input.
To retrieve a single email address given its unique
id
, use the getEmailAddress
method. This method will return the record if it exists.TypeScript
Swift
Kotlin
try {
const emailAddress = await emailClient.getEmailAddress({
id,
cachePolicy: CachePolicy.RemoteOnly,
})
// `emailAddress` contains the email address object, else `undefined` if not found.
} catch {
// Handle/notify user of errors
}
/// Collect the input address of the email address object.
let emailAddressId = input.address.id
let getEmailAddressInput = GetEmailAddressInput(
id: emailAddressId,
cachePolicy: .remoteOnly
)
do {
let emailAddress = try await emailClient.getEmailAddress(
withInput: getEmailAddressInput
)
/// `emailAddress` contains the email address object, else `nil` if not found.
} catch {
/// Handle/notify user of error
}
val emailAddressId = emailAddress.id
launch {
try {
val input = GetEmailAddressInput(
id = emailAddressId,
cachePolicy = CachePolicy.REMOTE_ONLY
)
val emailAddress = withContext(Dispatchers.IO) {
emailClient.getEmailAddress(input)
}
// [emailAddress] contains the email address object, else [null] if not found.
} catch (e: EmailAddressException) {
// Handle/notify user of exception
}
}
The ability to retrieve multiple or all email addresses available to the user is supported. These results can be paginated.
A call to a list API will return a
ListEmailAddressesResult
with a status
and depending on the status, a list of matching items
and a nextToken
to support pagination. If no results matching the input are found, the result will contain empty items. There can be three possible statuses returned:Status | Definition |
---|---|
Success | A list of all requested email addresses are returned. |
Partial | A list of all email addresses that were successfully fetched and unencrypted are returned as well as a list of all email addresses that failed to unencrypt successfully, including an error indicating the reason for the failure. |
Failure | All email addresses failed to be fetched or unencrypted. Contains an error indicating the reason for the failure. |
An email address may fail to be unencrypted if the version of the client is not up-to-date or if the required cryptographic key is missing from the client device.
To retrieve multiple email addresses that are owned by the signed in user, call the
listEmailAddresses
method.TypeScript
Swift
Kotlin
try {
const result = await emailClient.listEmailAddresses({
cachePolicy: CachePolicy.RemoteOnly,
limit: 20,
nextToken,
})
if (result.status === ListOperationResultStatus.Success) {
// `result` contains the list of items matching the input.
// Page through the results if result.nextToken != undefined.
}
} catch {
// Handle/notify user of errors
}
let listEmailAddressesInput = ListEmailAddressesInput(
cachePolicy: .remoteOnly,
limit: 20,
nextToken: nil
)
do {
let output = try await emailClient.listEmailAddresses(
withInput: input
)
/// `output` contains a `ListOutput` item of results matching the call.
/// `output.items` contains an array of `EmailAddress`
} catch {
/// Handle/notify user
}
launch {
try {
val input = ListEmailAddressesInput(
cachePolicy = CachePolicy.REMOTE_ONLY,
limit = 20,
nextToken = nextToken
)
val result = withContext(Dispatchers.IO) {
emailClient.listEmailAddresses(input)
}
when (result) {
is ListAPIResult.Success -> {
// [result.items] contains the list of items matching the input.
// Page through the results if [output.nextToken] != null.
}
is ListAPIResult.Partial -> {
// [result.items] contains the list of items matching the input that decrypted successfully.
// [result.failed] contains the list of items that failed decryption with associated error.
// Page through the results if [partial.nextToken] != null.
}
}
} catch (e: EmailAddressException) {
// Handle/notify user of exception
}
}
All Provisioned Email Addresses for a Sudo
To retrieve multiple email addresses that are owned by a particular Sudo, call the
listEmailAddressesForSudoId
method by passing in the id
of the Sudo to query.TypeScript
Swift
Kotlin
// Collect the input sudo id however makes sense for your implementation.
const sudoId = sudo.id
try {
const result = await emailClient.listEmailAddressesForSudoId({
sudoId,
cachePolicy: CachePolicy.RemoteOnly,
limit: 20,
nextToken,
})
if (result.status === ListOperationResultStatus.Success) {
// `result` contains the list of items matching the input.
// Page through the results if result.nextToken != undefined.
}
} catch {
// Handle/notify user of errors
}
/// Collect the input sudo id however makes sense for your implementation.
let sudoId = sudo.id
let listEmailAddressesForSudoIdInput = ListEmailAddressesForSudoIdInput(
sudoId: sudoId,
cachePolicy: .remoteOnly,
limit: 20,
nextToken: nil
)
do {
let output = try await emailClient.listEmailAddressesForSudoId(
withInput: listEmailAddressesForSudoId
)
/// `output` contains a `ListOutput` item of results matching the call.
/// `output.items` contains an array of `EmailAddress`
} catch {
/// Handle/notify user
}
// Collect the input sudo id however makes sense for your implementation.
val sudoId = sudo.id
launch {
try {
val input = ListEmailAddressesForSudoIdInput(
sudoId = sudoId,
cachePolicy = CachePolicy.REMOTE_ONLY,
limit = 20,
nextToken = nextToken
)
val result = withContext(Dispatchers.IO) {
emailClient.listEmailAddressesForSudoId(input)
}
when (result) {
is ListAPIResult.Success -> {
// [result.items] contains the list of items matching the input.
// Page through the results if [output.nextToken] != null.
}
is ListAPIResult.Partial -> {
// [result.items] contains the list of items matching the input that decrypted successfully.
// [result.failed] contains the list of items that failed decryption with associated error.
// Page through the results if [partial.nextToken] != null.
}
}
} catch (e: EmailAddressException) {
// Handle/notify user of exception
}
}
For the best performance depending on your use case, look up email addresses by Sudo.
By default, list email addresses API have a limit of 1MB of data when no limit is supplied.
Last modified 4mo ago