---
title: Hooks and overrides
description: Add custom logic in the email verification flow by overriding the SuperTokens APIs.
sidebar:
  order: 70
---

**SuperTokens** exposes a set of constructs that allow you to trigger different actions during the authentication lifecycle or to even fully customize the logic based on your use case. 
The following sections describe how you can modify adjust the `emailverification` recipe to your needs.

Explore the [references pages](/references) for a more in depth guide on hooks and overrides.


## Backend override

To perform any task post email verification like analytics, sending a user a welcome email or notifying an internal dashboard, you need to override the `verifyEmailPOST` API.


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

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    EmailVerification.init({
      mode: "REQUIRED",
      override: {
        apis: (originalImplementation) => {
          return {
            ...originalImplementation,
            verifyEmailPOST: async function (input) {
              if (originalImplementation.verifyEmailPOST === undefined) {
                throw Error("Should never come here");
              }

              // First we call the original implementation
              let response = await originalImplementation.verifyEmailPOST(input);

              // Then we check if it was successfully completed
              if (response.status === "OK") {
                let { recipeUserId, email } = response.user;
                // TODO: post email verification logic
              }
              return response;
            },
          };
        },
      },
    }),
    Session.init(),
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"fmt"

	"github.com/supertokens/supertokens-golang/recipe/emailverification"
	"github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
	"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			emailverification.Init(evmodels.TypeInput{
				Mode: evmodels.ModeRequired,
				Override: &evmodels.OverrideStruct{
					APIs: func(originalImplementation evmodels.APIInterface) evmodels.APIInterface {
						ogVerifyEmailPOST := *originalImplementation.VerifyEmailPOST
						(*originalImplementation.VerifyEmailPOST) = func(token string, sessionContainer sessmodels.SessionContainer, tenantId string, options evmodels.APIOptions, userContext supertokens.UserContext) (evmodels.VerifyEmailPOSTResponse, error) {
							resp, err := ogVerifyEmailPOST(token, sessionContainer, tenantId, options, userContext)
							if err != nil {
								return evmodels.VerifyEmailPOSTResponse{}, err
							}

							if resp.OK != nil {
								id := resp.OK.User.ID
								email := resp.OK.User.Email
								fmt.Println(id)
								fmt.Println(email)
								// TODO: post email verification logic
							}

							return resp, nil
						}
						return originalImplementation
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="initialization excerpt omits deployment connection config"
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import emailverification
from supertokens_python.recipe.emailverification.interfaces import APIInterface, APIOptions, EmailVerifyPostOkResult
from typing import Dict, Any, Optional
from supertokens_python.recipe.session.interfaces import SessionContainer

def override_email_verification_apis(original_implementation_email_verification: APIInterface):
    original_email_verify_post = original_implementation_email_verification.email_verify_post

    async def email_verify_post(token: str,
                                session: Optional[SessionContainer],
                                tenant_id: str,
                                api_options: APIOptions,
                                user_context: Dict[str, Any],):

        response = await original_email_verify_post(token, session, tenant_id, api_options, user_context)

        # Then we check if it was successfully completed
        if isinstance(response, EmailVerifyPostOkResult):
            _ = response.user
            # TODO: post email verification logic
        return response

    original_implementation_email_verification.email_verify_post = email_verify_post
    return original_implementation_email_verification

init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',  
    recipe_list=[
        emailverification.init(
            mode="REQUIRED",
            override=emailverification.InputOverrideConfig(
                apis=override_email_verification_apis
            )
        )
    ]
)
```
</Tab>
</CodeGroup>
