diff --git a/src/reflex/verify.ts b/src/reflex/verify.ts
new file mode 100644
index 0000000..9d90dde
--- /dev/null
+++ b/src/reflex/verify.ts
@@ -0,0 +1,142 @@
+import Discord, { GuildMember } from "discord.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
+import fetch from "node-fetch";
+import { TestString, NSFWCheck } from "./scanners.js";
+import createPageIndicator from "../utils/createPageIndicator.js";
+import client from "../utils/client.js";
+
+function step(i) {
+    return "\n\n" + createPageIndicator(5, i);
+}
+
+export default async function(interaction) {
+    let verify = client.verify
+    await interaction.reply({embeds: [new EmojiEmbed()
+        .setTitle("Loading")
+        .setDescription(step(-1))
+        .setStatus("Danger")
+        .setEmoji("NUCLEUS.LOADING")
+    ], ephemeral: true, fetchReply: true});
+    let config = await client.database.guilds.read(interaction.guild.id);
+    if ((!config.verify.enabled ) || (!config.verify.role)) return interaction.editReply({embeds: [new EmojiEmbed()
+        .setTitle("Verify")
+        .setDescription(`Verify is not enabled on this server`)
+        .setStatus("Danger")
+        .setEmoji("CONTROL.BLOCKCROSS")
+    ], ephemeral: true, fetchReply: true});
+    if ((interaction.member as GuildMember).roles.cache.has(config.verify.role)) {
+        return await interaction.editReply({embeds: [new EmojiEmbed()
+            .setTitle("Verify")
+            .setDescription(`You already have the <@&${config.verify.role}> role` + step(0))
+            .setStatus("Danger")
+            .setEmoji("CONTROL.BLOCKCROSS")
+        ]});
+    }
+    await interaction.editReply({embeds: [new EmojiEmbed()
+        .setTitle("Verify")
+        .setDescription(`Checking our servers are up` + step(0))
+        .setStatus("Warning")
+        .setEmoji("NUCLEUS.LOADING")
+    ]});
+    try {
+        let status = await fetch(client.config.baseUrl).then(res => res.status);
+        if (status != 200) {
+            return await interaction.editReply({embeds: [new EmojiEmbed()
+                .setTitle("Verify")
+                .setDescription(`Our servers appear to be down, please try again later` + step(0))
+                .setStatus("Danger")
+                .setEmoji("CONTROL.BLOCKCROSS")
+            ]});
+        }
+    } catch {
+        return await interaction.editReply({embeds: [new EmojiEmbed()
+            .setTitle("Verify")
+            .setDescription(`Our servers appear to be down, please try again later` + step(0))
+            .setStatus("Danger")
+            .setEmoji("CONTROL.BLOCKCROSS")
+        ], components: [new Discord.MessageActionRow().addComponents([
+            new Discord.MessageButton()
+                .setLabel("Check webpage")
+                .setStyle("LINK")
+                .setURL(client.config.baseUrl),
+            new Discord.MessageButton()
+                .setLabel("Support")
+                .setStyle("LINK")
+                .setURL("https://discord.gg/bPaNnxe")
+        ])]});
+    }
+    if (config.filters.images.NSFW) {
+        await interaction.editReply({embeds: [new EmojiEmbed()
+            .setTitle("Verify")
+            .setDescription(`Checking your avatar is safe for work` + step(1))
+            .setStatus("Warning")
+            .setEmoji("NUCLEUS.LOADING")
+        ]});
+        if (await NSFWCheck((interaction.member as GuildMember).user.avatarURL({format: "png"}))) {
+            return await interaction.editReply({embeds: [new EmojiEmbed()
+                .setTitle("Verify")
+                .setDescription(`Your avatar was detected as NSFW, which we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake` + step(1))
+                .setStatus("Danger")
+                .setEmoji("CONTROL.BLOCKCROSS")
+            ]});
+        }
+    }
+    if (config.filters.wordFilter) {
+        await interaction.editReply({embeds: [new EmojiEmbed()
+            .setTitle("Verify")
+            .setDescription(`Checking your name is allowed` + step(2))
+            .setStatus("Warning")
+            .setEmoji("NUCLEUS.LOADING")
+        ]});
+        if (TestString((interaction.member as Discord.GuildMember).displayName, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict) !== null) {
+            return await interaction.editReply({embeds: [new EmojiEmbed()
+                .setTitle("Verify")
+                .setDescription(`Your name contained a word we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake` + step(2))
+                .setStatus("Danger")
+                .setEmoji("CONTROL.BLOCKCROSS")
+            ]});
+        }
+    }
+    await interaction.editReply({embeds: [new EmojiEmbed()
+        .setTitle("Verify")
+        .setDescription(`One moment...` + step(3))
+        .setStatus("Warning")
+        .setEmoji("NUCLEUS.LOADING")
+    ]});
+    let code = ""
+    let length = 5
+    let itt = 0
+    const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+    while (true) {
+        itt += 1
+        code = ""
+        for (let i = 0; i < length; i++) { code += chars.charAt(Math.floor(Math.random() * chars.length)); }
+        if (code in verify) continue;
+        if (itt > 1000) {
+            itt = 0
+            length += 1
+            continue
+        }
+        break;
+    }
+    verify[code] = {
+        uID: interaction.member.user.id,
+        gID: interaction.guild.id,
+        rID: config.verify.role,
+        rName: (await interaction.guild.roles.fetch(config.verify.role)).name,
+        uName: interaction.member.user.username,
+        gName: interaction.guild.name,
+        gIcon: interaction.guild.iconURL({format: "png"}),
+        interaction: interaction
+    }
+    await interaction.editReply({embeds: [new EmojiEmbed()
+        .setTitle("Verify")
+        .setDescription(`Looking good!\nClick the button below to get verified` + step(4))
+        .setStatus("Success")
+        .setEmoji("MEMBER.JOIN")
+    ], components: [new Discord.MessageActionRow().addComponents([new Discord.MessageButton()
+        .setLabel("Verify")
+        .setStyle("LINK")
+        .setURL(`${client.config.baseUrl}/nucleus/verify?code=${code}`)
+    ])]});
+}
