---
title: Configure Email Delivery
description: Send SuperTokens emails through the default service, your own SMTP server and domain, or a custom delivery implementation.
sidebar:
  order: 3
---

## Email delivery summary

- Email delivery is owned by the `EmailPassword`, `EmailVerification`, `Passwordless`, and `WebAuthn` recipes. `AccountLinking` does not configure delivery.
- Without configuration, each recipe uses its built-in delivery service. The endpoint and failure behavior differ by recipe and SDK; this service does not support template customization.
- Configure your own SMTP server to send from your domain and optionally customize the subject and template.
- For complete control, provide a custom delivery implementation or override `sendEmail`.

## Overview

SuperTokens sends emails in different authentication scenarios.
Email delivery is configured on the recipe that generates the message: `EmailPassword` for password resets,
`EmailVerification`, `Passwordless` for email codes and links, and `WebAuthn` for account-recovery emails.
The `AccountLinking` recipe does not own an email-delivery configuration.

The following page shows you how to configure the email delivery method and adjust the content that gets sent to your users.

## Delivery methods

### Default service

If you provide no email-delivery configuration, the recipe uses the backend SDK's built-in delivery service. This applies
whether the Core is self-hosted or managed. Do not allow the external delivery endpoints from a single hostname: released
recipes use both `api.supertokens.io` and `api.supertokens.com`.

:::note
The built-in service does not support template customization. Configure SMTP or a custom delivery implementation when
you need to control the sender, content, delivery guarantees, or data-processing terms.
:::

:::caution[Failure behavior differs]
Do not treat the built-in service as a durable queue. In Node.js 24.0.3, Passwordless awaits delivery, while several other
email flows suppress built-in-service failures outside serverless environments. If delivery is security-critical, provide
your own service, await its result, monitor failures, and make retries idempotent.
:::

---

### SMTP service

Using this method, you can provide your own SMTP server configuration and the system sends emails through it.
Use this method if you want to:
- Send emails using your own domain.
- Optionally customize the default email template and subject.

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import supertokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
import { SMTPService } from "supertokens-node/recipe/emailpassword/emaildelivery";
import EmailVerification from "supertokens-node/recipe/emailverification";
import { SMTPService as EmailVerificationSMTPService } from "supertokens-node/recipe/emailverification/emaildelivery";
import Passwordless from "supertokens-node/recipe/passwordless";
import { SMTPService as PasswordlessSMTPService } from "supertokens-node/recipe/passwordless/emaildelivery";
import WebAuthn from "supertokens-node/recipe/webauthn";
import { SMTPService as WebAuthnSMTPService } from "supertokens-node/recipe/webauthn/emaildelivery";

const smtpSettings = {
  host: "...",
  authUsername: "...", // this is optional. In case not given, from.email will be used
  password: "...",
  port: 465,
  from: {
    name: "...",
    email: "...",
  },
  secure: true,
};

supertokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    EmailPassword.init({
      emailDelivery: {
        service: new SMTPService({ smtpSettings }),
      },
    }),

    // if email verification is enabled..
    EmailVerification.init({
      mode: "OPTIONAL",
      emailDelivery: {
        service: new EmailVerificationSMTPService({ smtpSettings }),
      },
    }),
    Passwordless.init({
      contactMethod: "EMAIL",
      flowType: "USER_INPUT_CODE",
      emailDelivery: {
        service: new PasswordlessSMTPService({ smtpSettings }),
      },
    }),
    WebAuthn.init({
      emailDelivery: {
        service: new WebAuthnSMTPService({ smtpSettings }),
      },
    }),
    Session.init(),
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/ingredients/emaildelivery"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword/epmodels"
	"github.com/supertokens/supertokens-golang/recipe/emailverification"
	"github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
	"github.com/supertokens/supertokens-golang/recipe/passwordless"
	"github.com/supertokens/supertokens-golang/recipe/passwordless/plessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"

)

func main() {
	smtpUsername := "..."
	smtpSettings := emaildelivery.SMTPSettings{
		Host: "...",
		From: emaildelivery.SMTPFrom{
			Name:  "...",
			Email: "...",
		},
		Port:     465,
		Username: &smtpUsername, // this is optional. In case not given, from.email will be used
		Password: "...",
		Secure:   true,

	}

	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			emailpassword.Init(&epmodels.TypeInput{
				EmailDelivery: &emaildelivery.TypeInput{
					Service: emailpassword.MakeSMTPService(emaildelivery.SMTPServiceConfig{
						Settings: smtpSettings,
					}),
				},
			}),

			// if email verification is enabled
			emailverification.Init(evmodels.TypeInput{
				EmailDelivery: &emaildelivery.TypeInput{
					Service: emailverification.MakeSMTPService(emaildelivery.SMTPServiceConfig{
						Settings: smtpSettings,
					}),
				},
			}),
			passwordless.Init(plessmodels.TypeInput{
				ContactMethodEmail: plessmodels.ContactMethodEmailConfig{Enabled: true},
				FlowType:          "USER_INPUT_CODE",
				EmailDelivery: &emaildelivery.TypeInput{
					Service: passwordless.MakeSMTPService(emaildelivery.SMTPServiceConfig{
						Settings: smtpSettings,
					}),
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="Partial configuration example"
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import emailpassword
from supertokens_python.ingredients.emaildelivery.types import EmailDeliveryConfig, SMTPSettingsFrom, SMTPSettings
from supertokens_python.recipe import emailverification
from supertokens_python.recipe import passwordless
from supertokens_python.recipe.passwordless import ContactEmailOnlyConfig

smtp_settings = SMTPSettings(
    host="...",
    port=465,
    from_=SMTPSettingsFrom(
        name="...",
        email="..."
    ),
    password="...",
    secure=True,
    username="..." # this is optional. In case not given, from_.email will be used
)

init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        emailpassword.init(
            email_delivery=EmailDeliveryConfig(
                service=emailpassword.SMTPService(
                    smtp_settings=smtp_settings
                )
            )
        ),

        # If email verification is enabled
        emailverification.init(
            mode="OPTIONAL",
            email_delivery=EmailDeliveryConfig(
                service=emailverification.SMTPService(
                    smtp_settings=smtp_settings
                )
            )
        ),
        passwordless.init(
            contact_config=ContactEmailOnlyConfig(),
            flow_type="USER_INPUT_CODE",
            email_delivery=EmailDeliveryConfig(
                service=passwordless.SMTPService(smtp_settings=smtp_settings)
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

Port 465 conventionally uses implicit TLS, so the examples set `secure`/`Secure` to `true`. For STARTTLS, use the port
specified by your provider (commonly 587) and set `secure`/`Secure` to `false`; the connection starts without encryption
and is then upgraded. Never disable certificate or hostname verification. Node.js 24.0.3 exports a WebAuthn SMTP template
service. Python 0.31.3 and Go 0.26.0 accept WebAuthn email-delivery implementations but do not export a public,
recipe-specific WebAuthn SMTP template service; configure a WebAuthn delivery override in those SDKs instead of importing
an internal module or reusing another recipe's template service.

### Custom method

This method allows you to define your own email sending abstraction.

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import supertokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
import EmailVerification from "supertokens-node/recipe/emailverification";

supertokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    EmailPassword.init({
      emailDelivery: {
        override: (originalImplementation) => {
          return {
            ...originalImplementation,
            sendEmail: async function (input) {
              // TODO: create and send password reset email

              // Or use the original implementation which calls the default service,
              // or a service that you may have specified in the emailDelivery object.
              return originalImplementation.sendEmail(input);
            },
          };
        },
      },
    }),

    // if email verification is enabled
    EmailVerification.init({
      mode: "OPTIONAL",
      emailDelivery: {
        override: (originalImplementation) => {
          return {
            ...originalImplementation,
            sendEmail: async function (input) {
              // TODO: create and send email verification email

              // Or use the original implementation which calls the default service,
              // or a service that you may have specified in the emailDelivery object.
              return originalImplementation.sendEmail(input);
            },
          };
        },
      },
    }),
    Session.init(),
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/ingredients/emaildelivery"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword/epmodels"
	"github.com/supertokens/supertokens-golang/recipe/emailverification"
	"github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			emailpassword.Init(&epmodels.TypeInput{
				EmailDelivery: &emaildelivery.TypeInput{
					Override: func(originalImplementation emaildelivery.EmailDeliveryInterface) emaildelivery.EmailDeliveryInterface {
						originalSendEmail := *originalImplementation.SendEmail

						(*originalImplementation.SendEmail) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
							// TODO: create and send password reset email

							// Or use the original implementation which calls the default service,
							// or a service that you may have specified in the EmailDelivery object.
							return originalSendEmail(input, userContext)
						}

						return originalImplementation
					},
				},
			}),

			// if email verification is enabled
			emailverification.Init(evmodels.TypeInput{
				Mode: evmodels.ModeRequired,
				EmailDelivery: &emaildelivery.TypeInput{
					Override: func(originalImplementation emaildelivery.EmailDeliveryInterface) emaildelivery.EmailDeliveryInterface {
						originalSendEmail := *originalImplementation.SendEmail

						(*originalImplementation.SendEmail) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
							// TODO: create and email verification email

							// Or use the original implementation which calls the default service,
							// or a service that you may have specified in the EmailDelivery object.
							return originalSendEmail(input, userContext)
						}

						return originalImplementation
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="Partial configuration example"
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe.emailpassword.types import EmailDeliveryOverrideInput, EmailTemplateVars
from supertokens_python.recipe import emailpassword
from typing import Dict, Any
from supertokens_python.ingredients.emaildelivery.types import EmailDeliveryConfig
from supertokens_python.recipe.emailverification.types import EmailDeliveryOverrideInput as EVEmailDeliveryOverrideInput, EmailTemplateVars as EVEmailTemplateVars
from supertokens_python.recipe import emailverification

def custom_email_deliver(original_implementation: EmailDeliveryOverrideInput) -> EmailDeliveryOverrideInput:
    original_send_email = original_implementation.send_email

    async def send_email(template_vars: EmailTemplateVars, user_context: Dict[str, Any]) -> None:
        # TODO: create and send password reset email

        # Or use the original implementation which calls the default service,
        # or a service that you may have specified in the email_delivery object.
        return await original_send_email(template_vars, user_context)

    original_implementation.send_email = send_email
    return original_implementation

def custom_emailverification_delivery(original_implementation: EVEmailDeliveryOverrideInput) -> EVEmailDeliveryOverrideInput:
    original_send_email = original_implementation.send_email

    async def send_email(template_vars: EVEmailTemplateVars, user_context: Dict[str, Any]) -> None:
        # TODO: create and send email verification email

        # Or use the original implementation which calls the default service,
        # or a service that you may have specified in the email_delivery object.
        return await original_send_email(template_vars, user_context)

    original_implementation.send_email = send_email
    return original_implementation

init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
         emailpassword.init(
            email_delivery=EmailDeliveryConfig(override=custom_email_deliver)
        ),

        # If email verification is enabled
        emailverification.init(
            mode="OPTIONAL",
            email_delivery=EmailDeliveryConfig(override=custom_emailverification_delivery))
    ]
)
```
</Tab>
</CodeGroup>

If you call the original implementation function for `sendEmail`, it uses the service that you have configured. If you have not configured any service, it uses the default service.

Using this method, you can, for example, have your custom way of sending email verification emails, but use the default or SMTP service to send the reset password emails.

:::note[Error management]
Throw or return an error from your custom `sendEmail` implementation when delivery fails. API-triggered delivery can
propagate the error through the SDK's error handler; non-API calls may log it. This does not describe every recipe's
built-in service behavior; see the warning under [Default service](#default-service).
:::

---

## Email content customization

You can access the default email UI through the following links:
- Default [email verification template](/references/frontend-sdks/prebuilt-ui/ui-showcase#email-verification) and its [source code](https://github.com/supertokens/email-sms-templates/blob/master/email-html/email-verification.html).
- Default [password reset template](/references/frontend-sdks/prebuilt-ui/ui-showcase#password-reset) and its [source code](https://github.com/supertokens/email-sms-templates/blob/master/email-html/password-reset.html).

To change the content you can create a custom `SMTPService` like and update the property which builds the content.
The method allows you to return an object that has the following properties:
- `body`: This is the email's body. This can be HTML or text as well.
- `isHtml`: If the body is HTML, then this should be `true`.
- `subject`: This is the subject of the email to send.
- `toEmail`: The system sends the email to this email.

Other information like which email address to send from appears in the `smtpSettings` object.

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx check=false reason="Requires surrounding application context"
import supertokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
import { SMTPService } from "supertokens-node/recipe/emailpassword/emaildelivery";
import EmailVerification from "supertokens-node/recipe/emailverification";
import { SMTPService as EmailVerificationSMTPService } from "supertokens-node/recipe/emailverification/emaildelivery";

supertokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    EmailPassword.init({
      emailDelivery: {
        service: new SMTPService({
          smtpSettings: {
            /*...*/
          },
          override: (originalImplementation) => {
            return {
              ...originalImplementation,
              getContent: async function (input) {
                // password reset content
                let { passwordResetLink, user } = input;

                // you can even call the original implementation and modify that
                let originalContent = await originalImplementation.getContent(input);
                originalContent.subject = "My custom subject";
                return originalContent;
              },
            };
          },
        }),
      },
    }),

    // if email verification is enabled
    EmailVerification.init({
      mode: "OPTIONAL",
      emailDelivery: {
        service: new EmailVerificationSMTPService({
          smtpSettings: {
            /*...*/
          },
          override: (originalImplementation) => {
            return {
              ...originalImplementation,
              getContent: async function (input) {
                // email verification content
                let { emailVerifyLink, user } = input;

                // you can even call the original implementation and modify that
                let originalContent = await originalImplementation.getContent(input);
                originalContent.subject = "My custom subject";
                return originalContent;
              },
            };
          },
        }),
      },
    }),
    Session.init(),
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"fmt"

	"github.com/supertokens/supertokens-golang/ingredients/emaildelivery"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword/epmodels"
	"github.com/supertokens/supertokens-golang/recipe/emailverification"
	"github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			emailpassword.Init(&epmodels.TypeInput{
				EmailDelivery: &emaildelivery.TypeInput{
					Service: emailpassword.MakeSMTPService(emaildelivery.SMTPServiceConfig{
						Settings: emaildelivery.SMTPSettings{ /* ... */ },

						Override: func(originalImplementation emaildelivery.SMTPInterface) emaildelivery.SMTPInterface {
							originalGetContent := *originalImplementation.GetContent

							(*originalImplementation.GetContent) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) (emaildelivery.EmailContent, error) {
								// password reset content
								passwordResetLink := input.PasswordReset.PasswordResetLink
								user := input.PasswordReset.User
								fmt.Println(passwordResetLink)
								fmt.Println(user)

								// you can even call the original implementation and modify that
								originalContent, err := originalGetContent(input, userContext)
								if err != nil {
									return emaildelivery.EmailContent{}, err
								}
								originalContent.Subject = "My custom subject"
								return originalContent, nil
							}

							return originalImplementation
						},
					}),
				},
			}),

			// if email verification is enabled
			emailverification.Init(evmodels.TypeInput{
				EmailDelivery: &emaildelivery.TypeInput{
					Service: emailverification.MakeSMTPService(emaildelivery.SMTPServiceConfig{
						Settings: emaildelivery.SMTPSettings{ /* ... */ },

						Override: func(originalImplementation emaildelivery.SMTPInterface) emaildelivery.SMTPInterface {
							originalGetContent := *originalImplementation.GetContent

							(*originalImplementation.GetContent) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) (emaildelivery.EmailContent, error) {
								// email verification email content
								emailVerificationLink := input.EmailVerification.EmailVerifyLink
								user := input.EmailVerification.User
								fmt.Println(emailVerificationLink)
								fmt.Println(user)

								// you can even call the original implementation and modify that
								originalContent, err := originalGetContent(input, userContext)
								if err != nil {
									return emaildelivery.EmailContent{}, err
								}
								originalContent.Subject = "My custom subject"
								return originalContent, nil
							}

							return originalImplementation
						},
					}),
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="Partial configuration example"
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import emailpassword
from supertokens_python.ingredients.emaildelivery.types import EmailDeliveryConfig, EmailContent, SMTPSettings
from supertokens_python.recipe.emailpassword.types import SMTPOverrideInput, EmailTemplateVars
from typing import Dict, Any
from supertokens_python.recipe.emailverification.types import SMTPOverrideInput as EVSMTPOverrideInput, EmailTemplateVars as EVEmailTemplateVars
from supertokens_python.recipe import emailverification

def custom_smtp_content_override(original_implementation: SMTPOverrideInput) -> SMTPOverrideInput:
    original_get_content = original_implementation.get_content

    async def get_content(template_vars: EmailTemplateVars, user_context: Dict[str, Any]) -> EmailContent:
        # password reset content
        _ = template_vars.password_reset_link
        __ = template_vars.user

        # you can even call the original implementation and modify that
        original_content = await original_get_content(template_vars, user_context)
        original_content.subject = "My custom subject"
        return original_content

    original_implementation.get_content = get_content
    return original_implementation

def custom_smtp_email_verification_content_override(original_implementation: EVSMTPOverrideInput) -> EVSMTPOverrideInput:
    original_get_content = original_implementation.get_content

    async def get_content(template_vars: EVEmailTemplateVars, user_context: Dict[str, Any]) -> EmailContent:
        # email verification content
        _ = template_vars.email_verify_link
        __ = template_vars.user

        # you can even call the original implementation and modify that
        original_content = await original_get_content(template_vars, user_context)
        original_content.subject = "My custom subject"
        return original_content

    original_implementation.get_content = get_content
    return original_implementation


init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        emailpassword.init(
            email_delivery=EmailDeliveryConfig(
                service=emailpassword.SMTPService(
                    smtp_settings=SMTPSettings(...),
                    override=custom_smtp_content_override
                )
            )
        ),

        # If email verification is enabled
        emailverification.init(
            mode="OPTIONAL",
            email_delivery=EmailDeliveryConfig(
                service=emailverification.SMTPService(
                    smtp_settings=SMTPSettings(...),
                    override=custom_smtp_email_verification_content_override
                )
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## Overrides

You can use the override functionality to trigger any kind of behavior before and after email sending.
This can include things like:
- Logging
- Spam protection actions
- Modifying the email template variables before sending the emails

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import supertokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
import EmailVerification from "supertokens-node/recipe/emailverification";

supertokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    EmailPassword.init({
      emailDelivery: {
        override: (originalImplementation) => {
          return {
            ...originalImplementation,
            sendEmail: async function (input) {
              // TODO: run some logic before sending the email

              await originalImplementation.sendEmail(input);

              // TODO: run some logic post sending the email
            },
          };
        },
      },
    }),

    // if email verification is enabled
    EmailVerification.init({
      mode: "OPTIONAL",
      emailDelivery: {
        override: (originalImplementation) => {
          return {
            ...originalImplementation,
            sendEmail: async function (input) {
              // TODO: run some logic before sending the email

              await originalImplementation.sendEmail(input);

              // TODO: run some logic post sending the email
            },
          };
        },
      },
    }),
    Session.init(),
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/ingredients/emaildelivery"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword/epmodels"
	"github.com/supertokens/supertokens-golang/recipe/emailverification"
	"github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			emailpassword.Init(&epmodels.TypeInput{
				EmailDelivery: &emaildelivery.TypeInput{
					Override: func(originalImplementation emaildelivery.EmailDeliveryInterface) emaildelivery.EmailDeliveryInterface {
						originalSendEmail := *originalImplementation.SendEmail

						(*originalImplementation.SendEmail) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
							// TODO: run some logic before sending the email

							err := originalSendEmail(input, userContext)
							if err != nil {
								return err
							}

							// TODO: run some logic post sending the email
							return nil
						}

						return originalImplementation
					},
				},
			}),

			// if email verification is enabled
			emailverification.Init(evmodels.TypeInput{
				Mode: evmodels.ModeRequired,
				EmailDelivery: &emaildelivery.TypeInput{
					Override: func(originalImplementation emaildelivery.EmailDeliveryInterface) emaildelivery.EmailDeliveryInterface {
						originalSendEmail := *originalImplementation.SendEmail

						(*originalImplementation.SendEmail) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
							// TODO: run some logic before sending the email

							err := originalSendEmail(input, userContext)
							if err != nil {
								return err
							}

							// TODO: run some logic post sending the email
							return nil
						}

						return originalImplementation
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="Partial configuration example"
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe.emailpassword.types import EmailDeliveryOverrideInput, EmailTemplateVars
from supertokens_python.recipe import emailpassword
from typing import Dict, Any
from supertokens_python.ingredients.emaildelivery.types import EmailDeliveryConfig
from supertokens_python.recipe.emailverification.types import EmailDeliveryOverrideInput as EVEmailDeliveryOverrideInput, EmailTemplateVars as EVEmailTemplateVars
from supertokens_python.recipe import emailverification

def custom_email_deliver(original_implementation: EmailDeliveryOverrideInput) -> EmailDeliveryOverrideInput:
    original_send_email = original_implementation.send_email

    async def send_email(template_vars: EmailTemplateVars, user_context: Dict[str, Any]) -> None:
        # TODO: run some logic before sending the email

        resp = await original_send_email(template_vars, user_context)

        # TODO: run some logic after sending the email
        return resp

    original_implementation.send_email = send_email
    return original_implementation

def custom_emailverification_delivery(original_implementation: EVEmailDeliveryOverrideInput) -> EVEmailDeliveryOverrideInput:
    original_send_email = original_implementation.send_email

    async def send_email(template_vars: EVEmailTemplateVars, user_context: Dict[str, Any]) -> None:

        # TODO: run some logic before sending the email

        resp = await original_send_email(template_vars, user_context)

        # TODO: run some logic after sending the email

        return resp

    original_implementation.send_email = send_email
    return original_implementation

init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
         emailpassword.init(
            email_delivery=EmailDeliveryConfig(override=custom_email_deliver)
        ),

        # If email verification is enabled
        emailverification.init(
            mode="OPTIONAL",
            email_delivery=EmailDeliveryConfig(override=custom_emailverification_delivery))
    ]
)
```
</Tab>
</CodeGroup>
