summary refs log tree commit diff
diff options
context:
space:
mode:
authorTheArcaneBrony <myrainbowdash949@gmail.com>2022-08-12 11:36:39 +0200
committerTheArcaneBrony <myrainbowdash949@gmail.com>2022-08-13 21:57:51 +0200
commit10bd81274722823f875ba31eaf5fc670bfb22ceb (patch)
tree9c622935ca99e791f7ee1e27ef67c9d23388012a
parentMove some invite defaults into class (diff)
downloadserver-10bd81274722823f875ba31eaf5fc670bfb22ceb.tar.xz
Split schemas into files in util
-rw-r--r--api/assets/schemas.json2017
-rw-r--r--api/src/routes/auth/login.ts11
-rw-r--r--api/src/routes/auth/mfa/totp.ts9
-rw-r--r--api/src/routes/auth/register.ts29
-rw-r--r--api/src/routes/channels/#channel_id/index.ts30
-rw-r--r--api/src/routes/channels/#channel_id/invites.ts12
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/ack.ts9
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/index.ts4
-rw-r--r--api/src/routes/channels/#channel_id/messages/bulk-delete.ts4
-rw-r--r--api/src/routes/channels/#channel_id/messages/index.ts36
-rw-r--r--api/src/routes/channels/#channel_id/permissions.ts7
-rw-r--r--api/src/routes/channels/#channel_id/purge.ts7
-rw-r--r--api/src/routes/channels/#channel_id/webhooks.ts8
-rw-r--r--api/src/routes/guilds/#guild_id/audit-logs.ts3
-rw-r--r--api/src/routes/guilds/#guild_id/bans.ts24
-rw-r--r--api/src/routes/guilds/#guild_id/channels.ts3
-rw-r--r--api/src/routes/guilds/#guild_id/emojis.ts14
-rw-r--r--api/src/routes/guilds/#guild_id/index.ts20
-rw-r--r--api/src/routes/guilds/#guild_id/integrations.ts1
-rw-r--r--api/src/routes/guilds/#guild_id/members/#member_id/index.ts6
-rw-r--r--api/src/routes/guilds/#guild_id/members/#member_id/nick.ts4
-rw-r--r--api/src/routes/guilds/#guild_id/prune.ts7
-rw-r--r--api/src/routes/guilds/#guild_id/roles/#role_id/index.ts3
-rw-r--r--api/src/routes/guilds/#guild_id/roles/index.ts14
-rw-r--r--api/src/routes/guilds/#guild_id/stickers.ts17
-rw-r--r--api/src/routes/guilds/#guild_id/templates.ts10
-rw-r--r--api/src/routes/guilds/#guild_id/vanity-url.ts10
-rw-r--r--api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts14
-rw-r--r--api/src/routes/guilds/#guild_id/webhooks.ts1
-rw-r--r--api/src/routes/guilds/#guild_id/welcome_screen.ts13
-rw-r--r--api/src/routes/guilds/#guild_id/widget.ts7
-rw-r--r--api/src/routes/guilds/index.ts16
-rw-r--r--api/src/routes/guilds/templates/index.ts9
-rw-r--r--api/src/routes/users/@me/channels.ts7
-rw-r--r--api/src/routes/users/@me/index.ts21
-rw-r--r--api/src/routes/users/@me/mfa/codes.ts7
-rw-r--r--api/src/routes/users/@me/mfa/totp/disable.ts6
-rw-r--r--api/src/routes/users/@me/mfa/totp/enable.ts8
-rw-r--r--api/src/routes/users/@me/relationships.ts9
-rw-r--r--api/src/routes/users/@me/settings.ts2
-rw-r--r--api/src/util/handlers/Message.ts3
-rw-r--r--gateway/src/opcodes/Identify.ts2
-rw-r--r--gateway/src/opcodes/LazyRequest.ts3
-rw-r--r--gateway/src/opcodes/PresenceUpdate.ts3
-rw-r--r--gateway/src/opcodes/VoiceStateUpdate.ts2
-rw-r--r--gateway/src/schema/VoiceStateUpdateSchema.ts15
-rw-r--r--util/src/index.ts3
-rw-r--r--util/src/schemas/ActivitySchema.ts (renamed from gateway/src/schema/Activity.ts)0
-rw-r--r--util/src/schemas/BanCreateSchema.ts5
-rw-r--r--util/src/schemas/BanModeratorSchema.ts8
-rw-r--r--util/src/schemas/BanRegistrySchema.ts9
-rw-r--r--util/src/schemas/BulkDeleteSchema.ts4
-rw-r--r--util/src/schemas/ChannelModifySchema.ts29
-rw-r--r--util/src/schemas/ChannelPermissionOverwriteSchema.ts5
-rw-r--r--util/src/schemas/DmChannelCreateSchema.ts5
-rw-r--r--util/src/schemas/EmojiCreateSchema.ts7
-rw-r--r--util/src/schemas/EmojiModifySchema.ts5
-rw-r--r--util/src/schemas/GuildCreateSchema.ts14
-rw-r--r--util/src/schemas/GuildTemplateCreateSchema.ts5
-rw-r--r--util/src/schemas/GuildUpdateSchema.ts18
-rw-r--r--util/src/schemas/GuildUpdateWelcomeScreenSchema.ts11
-rw-r--r--util/src/schemas/IdentifySchema.ts (renamed from gateway/src/schema/Identify.ts)2
-rw-r--r--util/src/schemas/InviteCreateSchema.ts12
-rw-r--r--util/src/schemas/LazyRequestSchema.ts (renamed from gateway/src/schema/LazyRequest.ts)0
-rw-r--r--util/src/schemas/LoginSchema.ts9
-rw-r--r--util/src/schemas/MemberChangeSchema.ts4
-rw-r--r--util/src/schemas/MemberNickChangeSchema.ts4
-rw-r--r--util/src/schemas/MessageAcknowledgeSchema.ts8
-rw-r--r--util/src/schemas/MessageCreateSchema.ts34
-rw-r--r--util/src/schemas/MfaCodesSchema.ts5
-rw-r--r--util/src/schemas/ModifyGuildStickerSchema.ts16
-rw-r--r--util/src/schemas/PruneSchema.ts7
-rw-r--r--util/src/schemas/PurgeSchema.ts5
-rw-r--r--util/src/schemas/RegisterSchema.ts27
-rw-r--r--util/src/schemas/RelationshipPostSchema.ts5
-rw-r--r--util/src/schemas/RelationshipPutSchema.ts6
-rw-r--r--util/src/schemas/RoleModifySchema.ts11
-rw-r--r--util/src/schemas/TemplateCreateSchema.ts5
-rw-r--r--util/src/schemas/TemplateModifySchema.ts5
-rw-r--r--util/src/schemas/TotpDisableSchema.ts4
-rw-r--r--util/src/schemas/TotpEnableSchema.ts6
-rw-r--r--util/src/schemas/TotpSchema.ts7
-rw-r--r--util/src/schemas/UserModifySchema.ts19
-rw-r--r--util/src/schemas/UserSettingsSchema.ts4
-rw-r--r--util/src/schemas/VanityUrlSchema.ts8
-rw-r--r--util/src/schemas/VoiceStateUpdateSchema.ts18
-rw-r--r--util/src/schemas/WebhookCreateSchema.ts8
-rw-r--r--util/src/schemas/WidgetModifySchema.ts5
-rw-r--r--util/src/schemas/index.ts41
-rw-r--r--util/src/util/Config.ts5
90 files changed, 1701 insertions, 1184 deletions
diff --git a/api/assets/schemas.json b/api/assets/schemas.json
index d8576514..f102f9d0 100644
--- a/api/assets/schemas.json
+++ b/api/assets/schemas.json
@@ -98,362 +98,264 @@
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "MessageCreateSchema": {
+    "ActivitySchema": {
         "type": "object",
         "properties": {
-            "type": {
-                "type": "integer"
-            },
-            "content": {
-                "type": "string"
-            },
-            "nonce": {
-                "type": "string"
-            },
-            "channel_id": {
-                "type": "string"
-            },
-            "tts": {
+            "afk": {
                 "type": "boolean"
             },
-            "flags": {
-                "type": "string"
+            "status": {
+                "$ref": "#/definitions/Status"
             },
-            "embeds": {
+            "activities": {
                 "type": "array",
                 "items": {
-                    "$ref": "#/definitions/Embed"
+                    "$ref": "#/definitions/Activity"
                 }
             },
-            "embed": {
-                "$ref": "#/definitions/Embed"
-            },
-            "allowed_mentions": {
-                "type": "object",
-                "properties": {
-                    "parse": {
-                        "type": "array",
-                        "items": {
-                            "type": "string"
-                        }
-                    },
-                    "roles": {
-                        "type": "array",
-                        "items": {
-                            "type": "string"
-                        }
-                    },
-                    "users": {
-                        "type": "array",
-                        "items": {
-                            "type": "string"
-                        }
-                    },
-                    "replied_user": {
-                        "type": "boolean"
-                    }
-                },
-                "additionalProperties": false
-            },
-            "message_reference": {
-                "type": "object",
-                "properties": {
-                    "message_id": {
-                        "type": "string"
-                    },
-                    "channel_id": {
-                        "type": "string"
-                    },
-                    "guild_id": {
-                        "type": "string"
-                    },
-                    "fail_if_not_exists": {
-                        "type": "boolean"
-                    }
-                },
-                "additionalProperties": false,
-                "required": [
-                    "channel_id",
-                    "message_id"
-                ]
-            },
-            "payload_json": {
-                "type": "string"
-            },
-            "file": {},
-            "attachments": {
-                "description": "TODO: we should create an interface for attachments\nTODO: OpenWAAO<-->attachment-style metadata conversion",
-                "type": "array",
-                "items": {}
-            },
-            "sticker_ids": {
-                "type": "array",
-                "items": {
-                    "type": "string"
-                }
+            "since": {
+                "type": "integer"
             }
         },
         "additionalProperties": false,
+        "required": [
+            "afk",
+            "status"
+        ],
         "definitions": {
-            "Embed": {
+            "Status": {
+                "enum": [
+                    "dnd",
+                    "idle",
+                    "invisible",
+                    "offline",
+                    "online"
+                ],
+                "type": "string"
+            },
+            "Activity": {
                 "type": "object",
                 "properties": {
-                    "title": {
+                    "name": {
                         "type": "string"
                     },
                     "type": {
-                        "enum": [
-                            "article",
-                            "gifv",
-                            "image",
-                            "link",
-                            "rich",
-                            "video"
-                        ],
-                        "type": "string"
-                    },
-                    "description": {
-                        "type": "string"
+                        "$ref": "#/definitions/ActivityType"
                     },
                     "url": {
                         "type": "string"
                     },
-                    "timestamp": {
-                        "type": "string",
-                        "format": "date-time"
-                    },
-                    "color": {
+                    "created_at": {
                         "type": "integer"
                     },
-                    "footer": {
+                    "timestamps": {
                         "type": "object",
                         "properties": {
-                            "text": {
-                                "type": "string"
-                            },
-                            "icon_url": {
-                                "type": "string"
+                            "start": {
+                                "type": "integer"
                             },
-                            "proxy_icon_url": {
-                                "type": "string"
+                            "end": {
+                                "type": "integer"
                             }
                         },
                         "additionalProperties": false,
                         "required": [
-                            "text"
+                            "end",
+                            "start"
                         ]
                     },
-                    "image": {
-                        "$ref": "#/definitions/EmbedImage"
+                    "application_id": {
+                        "type": "string"
                     },
-                    "thumbnail": {
-                        "$ref": "#/definitions/EmbedImage"
+                    "details": {
+                        "type": "string"
                     },
-                    "video": {
-                        "$ref": "#/definitions/EmbedImage"
+                    "state": {
+                        "type": "string"
                     },
-                    "provider": {
+                    "emoji": {
                         "type": "object",
                         "properties": {
                             "name": {
                                 "type": "string"
                             },
-                            "url": {
+                            "id": {
+                                "type": "string"
+                            },
+                            "animated": {
+                                "type": "boolean"
+                            }
+                        },
+                        "additionalProperties": false,
+                        "required": [
+                            "animated",
+                            "name"
+                        ]
+                    },
+                    "party": {
+                        "type": "object",
+                        "properties": {
+                            "id": {
                                 "type": "string"
+                            },
+                            "size": {
+                                "type": "array",
+                                "items": [
+                                    {
+                                        "type": "integer"
+                                    }
+                                ],
+                                "minItems": 1,
+                                "maxItems": 1
                             }
                         },
                         "additionalProperties": false
                     },
-                    "author": {
+                    "assets": {
                         "type": "object",
                         "properties": {
-                            "name": {
+                            "large_image": {
                                 "type": "string"
                             },
-                            "url": {
+                            "large_text": {
                                 "type": "string"
                             },
-                            "icon_url": {
+                            "small_image": {
                                 "type": "string"
                             },
-                            "proxy_icon_url": {
+                            "small_text": {
                                 "type": "string"
                             }
                         },
                         "additionalProperties": false
                     },
-                    "fields": {
-                        "type": "array",
-                        "items": {
-                            "type": "object",
-                            "properties": {
-                                "name": {
-                                    "type": "string"
-                                },
-                                "value": {
-                                    "type": "string"
-                                },
-                                "inline": {
-                                    "type": "boolean"
-                                }
+                    "secrets": {
+                        "type": "object",
+                        "properties": {
+                            "join": {
+                                "type": "string"
                             },
-                            "additionalProperties": false,
-                            "required": [
-                                "name",
-                                "value"
-                            ]
-                        }
-                    }
-                },
-                "additionalProperties": false
-            },
-            "EmbedImage": {
-                "type": "object",
-                "properties": {
-                    "url": {
-                        "type": "string"
-                    },
-                    "proxy_url": {
-                        "type": "string"
+                            "spectate": {
+                                "type": "string"
+                            },
+                            "match": {
+                                "type": "string"
+                            }
+                        },
+                        "additionalProperties": false
                     },
-                    "height": {
-                        "type": "integer"
+                    "instance": {
+                        "type": "boolean"
                     },
-                    "width": {
-                        "type": "integer"
+                    "flags": {
+                        "type": "string"
                     }
                 },
-                "additionalProperties": false
+                "additionalProperties": false,
+                "required": [
+                    "flags",
+                    "name",
+                    "type"
+                ]
+            },
+            "ActivityType": {
+                "enum": [
+                    0,
+                    1,
+                    2,
+                    4,
+                    5
+                ],
+                "type": "number"
             }
         },
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "RouteResponse": {
+    "BanCreateSchema": {
         "type": "object",
         "properties": {
-            "status": {
-                "type": "integer"
-            },
-            "body": {
-                "type": "array",
-                "items": {
-                    "type": "string"
-                }
+            "delete_message_days": {
+                "type": "string"
             },
-            "headers": {
-                "$ref": "#/definitions/Record<string,string>"
+            "reason": {
+                "type": "string"
             }
         },
         "additionalProperties": false,
-        "definitions": {
-            "Record<string,string>": {
-                "type": "object",
-                "additionalProperties": false
-            }
-        },
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "LoginSchema": {
+    "BanModeratorSchema": {
         "type": "object",
         "properties": {
-            "login": {
+            "id": {
                 "type": "string"
             },
-            "password": {
+            "user_id": {
                 "type": "string"
             },
-            "undelete": {
-                "type": "boolean"
-            },
-            "captcha_key": {
+            "guild_id": {
                 "type": "string"
             },
-            "login_source": {
+            "executor_id": {
                 "type": "string"
             },
-            "gift_code_sku_id": {
+            "reason": {
                 "type": "string"
             }
         },
         "additionalProperties": false,
         "required": [
-            "login",
-            "password"
+            "executor_id",
+            "guild_id",
+            "id",
+            "user_id"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "TotpSchema": {
+    "BanRegistrySchema": {
         "type": "object",
         "properties": {
-            "code": {
+            "id": {
                 "type": "string"
             },
-            "ticket": {
+            "user_id": {
                 "type": "string"
             },
-            "gift_code_sku_id": {
-                "type": [
-                    "null",
-                    "string"
-                ]
+            "guild_id": {
+                "type": "string"
             },
-            "login_source": {
-                "type": [
-                    "null",
-                    "string"
-                ]
+            "executor_id": {
+                "type": "string"
+            },
+            "ip": {
+                "type": "string"
+            },
+            "reason": {
+                "type": "string"
             }
         },
         "additionalProperties": false,
         "required": [
-            "code",
-            "ticket"
+            "executor_id",
+            "guild_id",
+            "id",
+            "user_id"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "RegisterSchema": {
+    "BulkDeleteSchema": {
         "type": "object",
         "properties": {
-            "username": {
-                "minLength": 2,
-                "maxLength": 32,
-                "type": "string"
-            },
-            "password": {
-                "minLength": 1,
-                "maxLength": 72,
-                "type": "string"
-            },
-            "consent": {
-                "type": "boolean"
-            },
-            "email": {
-                "format": "email",
-                "type": "string"
-            },
-            "fingerprint": {
-                "type": "string"
-            },
-            "invite": {
-                "type": "string"
-            },
-            "date_of_birth": {
-                "type": "string"
-            },
-            "gift_code_sku_id": {
-                "type": "string"
-            },
-            "captcha_key": {
-                "type": "string"
-            },
-            "promotional_email_opt_in": {
-                "type": "boolean"
+            "messages": {
+                "type": "array",
+                "items": {
+                    "type": "string"
+                }
             }
         },
         "additionalProperties": false,
         "required": [
-            "consent",
-            "username"
+            "messages"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
@@ -573,69 +475,6 @@
         },
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "InviteCreateSchema": {
-        "type": "object",
-        "properties": {
-            "target_user_id": {
-                "type": "string"
-            },
-            "target_type": {
-                "type": "string"
-            },
-            "validate": {
-                "type": "string"
-            },
-            "max_age": {
-                "type": "integer"
-            },
-            "max_uses": {
-                "type": "integer"
-            },
-            "temporary": {
-                "type": "boolean"
-            },
-            "unique": {
-                "type": "boolean"
-            },
-            "target_user": {
-                "type": "string"
-            },
-            "target_user_type": {
-                "type": "integer"
-            }
-        },
-        "additionalProperties": false,
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "MessageAcknowledgeSchema": {
-        "type": "object",
-        "properties": {
-            "manual": {
-                "type": "boolean"
-            },
-            "mention_count": {
-                "type": "integer"
-            }
-        },
-        "additionalProperties": false,
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "BulkDeleteSchema": {
-        "type": "object",
-        "properties": {
-            "messages": {
-                "type": "array",
-                "items": {
-                    "type": "string"
-                }
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "messages"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
     "ChannelPermissionOverwriteSchema": {
         "type": "object",
         "properties": {
@@ -671,192 +510,25 @@
         },
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "PurgeSchema": {
-        "type": "object",
-        "properties": {
-            "before": {
-                "type": "string"
-            },
-            "after": {
-                "type": "string"
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "after",
-            "before"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "WebhookCreateSchema": {
+    "DmChannelCreateSchema": {
         "type": "object",
         "properties": {
             "name": {
-                "maxLength": 80,
                 "type": "string"
             },
-            "avatar": {
-                "type": "string"
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "name"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "GatewayBotResponse": {
-        "type": "object",
-        "properties": {
-            "url": {
-                "type": "string"
-            },
-            "shards": {
-                "type": "integer"
-            },
-            "session_start_limit": {
-                "type": "object",
-                "properties": {
-                    "total": {
-                        "type": "integer"
-                    },
-                    "remaining": {
-                        "type": "integer"
-                    },
-                    "reset_after": {
-                        "type": "integer"
-                    },
-                    "max_concurrency": {
-                        "type": "integer"
-                    }
-                },
-                "additionalProperties": false,
-                "required": [
-                    "max_concurrency",
-                    "remaining",
-                    "reset_after",
-                    "total"
-                ]
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "session_start_limit",
-            "shards",
-            "url"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "GatewayResponse": {
-        "type": "object",
-        "properties": {
-            "url": {
-                "type": "string"
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "url"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "BanCreateSchema": {
-        "type": "object",
-        "properties": {
-            "delete_message_days": {
-                "type": "string"
-            },
-            "reason": {
-                "type": "string"
-            }
-        },
-        "additionalProperties": false,
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "BanRegistrySchema": {
-        "type": "object",
-        "properties": {
-            "id": {
-                "type": "string"
-            },
-            "user_id": {
-                "type": "string"
-            },
-            "guild_id": {
-                "type": "string"
-            },
-            "executor_id": {
-                "type": "string"
-            },
-            "ip": {
-                "type": "string"
-            },
-            "reason": {
-                "type": "string"
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "executor_id",
-            "guild_id",
-            "id",
-            "user_id"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "BanModeratorSchema": {
-        "type": "object",
-        "properties": {
-            "id": {
-                "type": "string"
-            },
-            "user_id": {
-                "type": "string"
-            },
-            "guild_id": {
-                "type": "string"
-            },
-            "executor_id": {
-                "type": "string"
-            },
-            "reason": {
-                "type": "string"
+            "recipients": {
+                "type": "array",
+                "items": {
+                    "type": "string"
+                }
             }
         },
         "additionalProperties": false,
         "required": [
-            "executor_id",
-            "guild_id",
-            "id",
-            "user_id"
+            "recipients"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "ChannelReorderSchema": {
-        "type": "array",
-        "items": {
-            "type": "object",
-            "properties": {
-                "id": {
-                    "type": "string"
-                },
-                "position": {
-                    "type": "integer"
-                },
-                "lock_permissions": {
-                    "type": "boolean"
-                },
-                "parent_id": {
-                    "type": "string"
-                }
-            },
-            "additionalProperties": false,
-            "required": [
-                "id"
-            ]
-        },
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
     "EmojiCreateSchema": {
         "type": "object",
         "properties": {
@@ -1054,6 +726,25 @@
         },
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
+    "GuildTemplateCreateSchema": {
+        "type": "object",
+        "properties": {
+            "name": {
+                "type": "string"
+            },
+            "avatar": {
+                "type": [
+                    "null",
+                    "string"
+                ]
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "name"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
     "GuildUpdateSchema": {
         "type": "object",
         "properties": {
@@ -1130,470 +821,892 @@
         "additionalProperties": false,
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "MemberChangeSchema": {
+    "GuildUpdateWelcomeScreenSchema": {
         "type": "object",
         "properties": {
-            "roles": {
+            "welcome_channels": {
                 "type": "array",
                 "items": {
-                    "type": "string"
+                    "type": "object",
+                    "properties": {
+                        "channel_id": {
+                            "type": "string"
+                        },
+                        "description": {
+                            "type": "string"
+                        },
+                        "emoji_id": {
+                            "type": "string"
+                        },
+                        "emoji_name": {
+                            "type": "string"
+                        }
+                    },
+                    "additionalProperties": false,
+                    "required": [
+                        "channel_id",
+                        "description",
+                        "emoji_name"
+                    ]
                 }
-            }
-        },
-        "additionalProperties": false,
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "MemberNickChangeSchema": {
-        "type": "object",
-        "properties": {
-            "nick": {
+            },
+            "enabled": {
+                "type": "boolean"
+            },
+            "description": {
                 "type": "string"
             }
         },
         "additionalProperties": false,
-        "required": [
-            "nick"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "PruneSchema": {
-        "type": "object",
-        "properties": {
-            "days": {
-                "type": "integer"
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "days"
-        ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "RoleModifySchema": {
+    "IdentifySchema": {
         "type": "object",
         "properties": {
-            "name": {
+            "token": {
                 "type": "string"
             },
-            "permissions": {
-                "type": "string"
+            "properties": {
+                "type": "object",
+                "properties": {
+                    "os": {
+                        "type": "string"
+                    },
+                    "os_atch": {
+                        "type": "string"
+                    },
+                    "browser": {
+                        "type": "string"
+                    },
+                    "device": {
+                        "type": "string"
+                    },
+                    "$os": {
+                        "type": "string"
+                    },
+                    "$browser": {
+                        "type": "string"
+                    },
+                    "$device": {
+                        "type": "string"
+                    },
+                    "browser_user_agent": {
+                        "type": "string"
+                    },
+                    "browser_version": {
+                        "type": "string"
+                    },
+                    "os_version": {
+                        "type": "string"
+                    },
+                    "referrer": {
+                        "type": "string"
+                    },
+                    "referring_domain": {
+                        "type": "string"
+                    },
+                    "referrer_current": {
+                        "type": "string"
+                    },
+                    "referring_domain_current": {
+                        "type": "string"
+                    },
+                    "release_channel": {
+                        "enum": [
+                            "canary",
+                            "dev",
+                            "ptb",
+                            "stable"
+                        ],
+                        "type": "string"
+                    },
+                    "client_build_number": {
+                        "type": "integer"
+                    },
+                    "client_event_source": {},
+                    "client_version": {
+                        "type": "string"
+                    },
+                    "system_locale": {
+                        "type": "string"
+                    }
+                },
+                "additionalProperties": false
             },
-            "color": {
-                "type": "integer"
+            "intents": {
+                "type": "bigint"
             },
-            "hoist": {
+            "presence": {
+                "$ref": "#/definitions/ActivitySchema"
+            },
+            "compress": {
                 "type": "boolean"
             },
-            "mentionable": {
+            "large_threshold": {
+                "type": "integer"
+            },
+            "shard": {
+                "type": "array",
+                "items": [
+                    {
+                        "type": "bigint"
+                    },
+                    {
+                        "type": "bigint"
+                    }
+                ],
+                "minItems": 2,
+                "maxItems": 2
+            },
+            "guild_subscriptions": {
                 "type": "boolean"
             },
-            "position": {
+            "capabilities": {
                 "type": "integer"
             },
-            "icon": {
-                "type": "string"
+            "client_state": {
+                "type": "object",
+                "properties": {
+                    "guild_hashes": {},
+                    "highest_last_message_id": {
+                        "type": "string"
+                    },
+                    "read_state_version": {
+                        "type": "integer"
+                    },
+                    "user_guild_settings_version": {
+                        "type": "integer"
+                    },
+                    "user_settings_version": {
+                        "type": "integer"
+                    }
+                },
+                "additionalProperties": false
             },
-            "unicode_emoji": {
-                "type": "string"
+            "v": {
+                "type": "integer"
             }
         },
         "additionalProperties": false,
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "RolePositionUpdateSchema": {
-        "type": "array",
-        "items": {
-            "type": "object",
-            "properties": {
-                "id": {
-                    "type": "string"
+        "required": [
+            "properties",
+            "token"
+        ],
+        "definitions": {
+            "ActivitySchema": {
+                "type": "object",
+                "properties": {
+                    "afk": {
+                        "type": "boolean"
+                    },
+                    "status": {
+                        "$ref": "#/definitions/Status"
+                    },
+                    "activities": {
+                        "type": "array",
+                        "items": {
+                            "$ref": "#/definitions/Activity"
+                        }
+                    },
+                    "since": {
+                        "type": "integer"
+                    }
                 },
-                "position": {
-                    "type": "integer"
-                }
+                "additionalProperties": false,
+                "required": [
+                    "afk",
+                    "status"
+                ]
             },
-            "additionalProperties": false,
-            "required": [
-                "id",
-                "position"
-            ]
-        },
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "ModifyGuildStickerSchema": {
-        "type": "object",
-        "properties": {
-            "name": {
-                "minLength": 2,
-                "maxLength": 30,
+            "Status": {
+                "enum": [
+                    "dnd",
+                    "idle",
+                    "invisible",
+                    "offline",
+                    "online"
+                ],
                 "type": "string"
             },
-            "description": {
-                "maxLength": 100,
-                "type": "string"
+            "Activity": {
+                "type": "object",
+                "properties": {
+                    "name": {
+                        "type": "string"
+                    },
+                    "type": {
+                        "$ref": "#/definitions/ActivityType"
+                    },
+                    "url": {
+                        "type": "string"
+                    },
+                    "created_at": {
+                        "type": "integer"
+                    },
+                    "timestamps": {
+                        "type": "object",
+                        "properties": {
+                            "start": {
+                                "type": "integer"
+                            },
+                            "end": {
+                                "type": "integer"
+                            }
+                        },
+                        "additionalProperties": false,
+                        "required": [
+                            "end",
+                            "start"
+                        ]
+                    },
+                    "application_id": {
+                        "type": "string"
+                    },
+                    "details": {
+                        "type": "string"
+                    },
+                    "state": {
+                        "type": "string"
+                    },
+                    "emoji": {
+                        "type": "object",
+                        "properties": {
+                            "name": {
+                                "type": "string"
+                            },
+                            "id": {
+                                "type": "string"
+                            },
+                            "animated": {
+                                "type": "boolean"
+                            }
+                        },
+                        "additionalProperties": false,
+                        "required": [
+                            "animated",
+                            "name"
+                        ]
+                    },
+                    "party": {
+                        "type": "object",
+                        "properties": {
+                            "id": {
+                                "type": "string"
+                            },
+                            "size": {
+                                "type": "array",
+                                "items": [
+                                    {
+                                        "type": "integer"
+                                    }
+                                ],
+                                "minItems": 1,
+                                "maxItems": 1
+                            }
+                        },
+                        "additionalProperties": false
+                    },
+                    "assets": {
+                        "type": "object",
+                        "properties": {
+                            "large_image": {
+                                "type": "string"
+                            },
+                            "large_text": {
+                                "type": "string"
+                            },
+                            "small_image": {
+                                "type": "string"
+                            },
+                            "small_text": {
+                                "type": "string"
+                            }
+                        },
+                        "additionalProperties": false
+                    },
+                    "secrets": {
+                        "type": "object",
+                        "properties": {
+                            "join": {
+                                "type": "string"
+                            },
+                            "spectate": {
+                                "type": "string"
+                            },
+                            "match": {
+                                "type": "string"
+                            }
+                        },
+                        "additionalProperties": false
+                    },
+                    "instance": {
+                        "type": "boolean"
+                    },
+                    "flags": {
+                        "type": "string"
+                    }
+                },
+                "additionalProperties": false,
+                "required": [
+                    "flags",
+                    "name",
+                    "type"
+                ]
             },
-            "tags": {
-                "maxLength": 200,
-                "type": "string"
+            "ActivityType": {
+                "enum": [
+                    0,
+                    1,
+                    2,
+                    4,
+                    5
+                ],
+                "type": "number"
             }
         },
-        "additionalProperties": false,
-        "required": [
-            "name",
-            "tags"
-        ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "TemplateCreateSchema": {
+    "InviteCreateSchema": {
         "type": "object",
         "properties": {
-            "name": {
+            "target_user_id": {
                 "type": "string"
             },
-            "description": {
-                "type": "string"
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "name"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "TemplateModifySchema": {
-        "type": "object",
-        "properties": {
-            "name": {
+            "target_type": {
                 "type": "string"
             },
-            "description": {
+            "validate": {
                 "type": "string"
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "name"
-        ],
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "VanityUrlSchema": {
-        "type": "object",
-        "properties": {
-            "code": {
-                "minLength": 1,
-                "maxLength": 20,
+            },
+            "max_age": {
+                "type": "integer"
+            },
+            "max_uses": {
+                "type": "integer"
+            },
+            "temporary": {
+                "type": "boolean"
+            },
+            "unique": {
+                "type": "boolean"
+            },
+            "target_user": {
                 "type": "string"
+            },
+            "target_user_type": {
+                "type": "integer"
             }
         },
         "additionalProperties": false,
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "VoiceStateUpdateSchema": {
+    "LoginSchema": {
         "type": "object",
         "properties": {
-            "channel_id": {
+            "login": {
                 "type": "string"
             },
-            "guild_id": {
+            "password": {
                 "type": "string"
             },
-            "suppress": {
+            "undelete": {
                 "type": "boolean"
             },
-            "request_to_speak_timestamp": {
-                "type": "string",
-                "format": "date-time"
-            },
-            "self_mute": {
-                "type": "boolean"
+            "captcha_key": {
+                "type": "string"
             },
-            "self_deaf": {
-                "type": "boolean"
+            "login_source": {
+                "type": "string"
             },
-            "self_video": {
-                "type": "boolean"
+            "gift_code_sku_id": {
+                "type": "string"
             }
         },
         "additionalProperties": false,
         "required": [
-            "channel_id"
+            "login",
+            "password"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "GuildUpdateWelcomeScreenSchema": {
+    "MemberChangeSchema": {
         "type": "object",
         "properties": {
-            "welcome_channels": {
+            "roles": {
                 "type": "array",
                 "items": {
-                    "type": "object",
-                    "properties": {
-                        "channel_id": {
-                            "type": "string"
-                        },
-                        "description": {
-                            "type": "string"
-                        },
-                        "emoji_id": {
-                            "type": "string"
-                        },
-                        "emoji_name": {
-                            "type": "string"
-                        }
-                    },
-                    "additionalProperties": false,
-                    "required": [
-                        "channel_id",
-                        "description",
-                        "emoji_name"
-                    ]
+                    "type": "string"
                 }
-            },
-            "enabled": {
-                "type": "boolean"
-            },
-            "description": {
-                "type": "string"
             }
         },
         "additionalProperties": false,
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "WidgetModifySchema": {
+    "MemberNickChangeSchema": {
         "type": "object",
         "properties": {
-            "enabled": {
-                "type": "boolean"
-            },
-            "channel_id": {
+            "nick": {
                 "type": "string"
             }
         },
         "additionalProperties": false,
         "required": [
-            "channel_id",
-            "enabled"
+            "nick"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "GuildTemplateCreateSchema": {
+    "MessageAcknowledgeSchema": {
         "type": "object",
         "properties": {
-            "name": {
-                "type": "string"
+            "manual": {
+                "type": "boolean"
             },
-            "avatar": {
-                "type": [
-                    "null",
-                    "string"
-                ]
+            "mention_count": {
+                "type": "integer"
             }
         },
         "additionalProperties": false,
-        "required": [
-            "name"
-        ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "UserProfileResponse": {
+    "MessageCreateSchema": {
         "type": "object",
         "properties": {
-            "user": {
-                "$ref": "#/definitions/UserPublic"
+            "type": {
+                "type": "integer"
             },
-            "connected_accounts": {
-                "$ref": "#/definitions/PublicConnectedAccount"
+            "content": {
+                "type": "string"
             },
-            "premium_guild_since": {
-                "type": "string",
-                "format": "date-time"
+            "nonce": {
+                "type": "string"
             },
-            "premium_since": {
-                "type": "string",
-                "format": "date-time"
-            }
-        },
-        "additionalProperties": false,
-        "required": [
-            "connected_accounts",
-            "user"
-        ],
-        "definitions": {
-            "UserPublic": {
+            "channel_id": {
+                "type": "string"
+            },
+            "tts": {
+                "type": "boolean"
+            },
+            "flags": {
+                "type": "string"
+            },
+            "embeds": {
+                "type": "array",
+                "items": {
+                    "$ref": "#/definitions/Embed"
+                }
+            },
+            "embed": {
+                "$ref": "#/definitions/Embed"
+            },
+            "allowed_mentions": {
                 "type": "object",
                 "properties": {
-                    "username": {
-                        "type": "string"
-                    },
-                    "discriminator": {
-                        "type": "string"
+                    "parse": {
+                        "type": "array",
+                        "items": {
+                            "type": "string"
+                        }
                     },
-                    "id": {
-                        "type": "string"
+                    "roles": {
+                        "type": "array",
+                        "items": {
+                            "type": "string"
+                        }
                     },
-                    "public_flags": {
-                        "type": "integer"
+                    "users": {
+                        "type": "array",
+                        "items": {
+                            "type": "string"
+                        }
                     },
-                    "avatar": {
+                    "replied_user": {
+                        "type": "boolean"
+                    }
+                },
+                "additionalProperties": false
+            },
+            "message_reference": {
+                "type": "object",
+                "properties": {
+                    "message_id": {
                         "type": "string"
                     },
-                    "accent_color": {
-                        "type": "integer"
-                    },
-                    "banner": {
+                    "channel_id": {
                         "type": "string"
                     },
-                    "bio": {
+                    "guild_id": {
                         "type": "string"
                     },
-                    "bot": {
+                    "fail_if_not_exists": {
                         "type": "boolean"
-                    },
-                    "premium_since": {
-                        "type": "string",
-                        "format": "date-time"
                     }
                 },
                 "additionalProperties": false,
                 "required": [
-                    "bio",
-                    "bot",
-                    "discriminator",
-                    "id",
-                    "premium_since",
-                    "public_flags",
-                    "username"
+                    "channel_id",
+                    "message_id"
                 ]
             },
-            "PublicConnectedAccount": {
+            "payload_json": {
+                "type": "string"
+            },
+            "file": {},
+            "attachments": {
+                "description": "TODO: we should create an interface for attachments\nTODO: OpenWAAO<-->attachment-style metadata conversion",
+                "type": "array",
+                "items": {}
+            },
+            "sticker_ids": {
+                "type": "array",
+                "items": {
+                    "type": "string"
+                }
+            }
+        },
+        "additionalProperties": false,
+        "definitions": {
+            "Embed": {
                 "type": "object",
                 "properties": {
-                    "name": {
+                    "title": {
                         "type": "string"
                     },
                     "type": {
+                        "enum": [
+                            "article",
+                            "gifv",
+                            "image",
+                            "link",
+                            "rich",
+                            "video"
+                        ],
                         "type": "string"
                     },
-                    "verified": {
-                        "type": "boolean"
+                    "description": {
+                        "type": "string"
+                    },
+                    "url": {
+                        "type": "string"
+                    },
+                    "timestamp": {
+                        "type": "string",
+                        "format": "date-time"
+                    },
+                    "color": {
+                        "type": "integer"
+                    },
+                    "footer": {
+                        "type": "object",
+                        "properties": {
+                            "text": {
+                                "type": "string"
+                            },
+                            "icon_url": {
+                                "type": "string"
+                            },
+                            "proxy_icon_url": {
+                                "type": "string"
+                            }
+                        },
+                        "additionalProperties": false,
+                        "required": [
+                            "text"
+                        ]
+                    },
+                    "image": {
+                        "$ref": "#/definitions/EmbedImage"
+                    },
+                    "thumbnail": {
+                        "$ref": "#/definitions/EmbedImage"
+                    },
+                    "video": {
+                        "$ref": "#/definitions/EmbedImage"
+                    },
+                    "provider": {
+                        "type": "object",
+                        "properties": {
+                            "name": {
+                                "type": "string"
+                            },
+                            "url": {
+                                "type": "string"
+                            }
+                        },
+                        "additionalProperties": false
+                    },
+                    "author": {
+                        "type": "object",
+                        "properties": {
+                            "name": {
+                                "type": "string"
+                            },
+                            "url": {
+                                "type": "string"
+                            },
+                            "icon_url": {
+                                "type": "string"
+                            },
+                            "proxy_icon_url": {
+                                "type": "string"
+                            }
+                        },
+                        "additionalProperties": false
+                    },
+                    "fields": {
+                        "type": "array",
+                        "items": {
+                            "type": "object",
+                            "properties": {
+                                "name": {
+                                    "type": "string"
+                                },
+                                "value": {
+                                    "type": "string"
+                                },
+                                "inline": {
+                                    "type": "boolean"
+                                }
+                            },
+                            "additionalProperties": false,
+                            "required": [
+                                "name",
+                                "value"
+                            ]
+                        }
                     }
                 },
-                "additionalProperties": false,
-                "required": [
-                    "name",
-                    "type",
-                    "verified"
-                ]
-            }
-        },
-        "$schema": "http://json-schema.org/draft-07/schema#"
-    },
-    "UserRelationsResponse": {
-        "type": "object",
-        "properties": {
-            "object": {
+                "additionalProperties": false
+            },
+            "EmbedImage": {
                 "type": "object",
                 "properties": {
-                    "id": {
-                        "type": "string"
-                    },
-                    "username": {
+                    "url": {
                         "type": "string"
                     },
-                    "avatar": {
+                    "proxy_url": {
                         "type": "string"
                     },
-                    "discriminator": {
-                        "type": "string"
+                    "height": {
+                        "type": "integer"
                     },
-                    "public_flags": {
+                    "width": {
                         "type": "integer"
                     }
                 },
                 "additionalProperties": false
             }
         },
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "MfaCodesSchema": {
+        "type": "object",
+        "properties": {
+            "password": {
+                "type": "string"
+            },
+            "regenerate": {
+                "type": "boolean"
+            }
+        },
         "additionalProperties": false,
         "required": [
-            "object"
+            "password"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "DmChannelCreateSchema": {
+    "ModifyGuildStickerSchema": {
         "type": "object",
         "properties": {
             "name": {
+                "minLength": 2,
+                "maxLength": 30,
                 "type": "string"
             },
-            "recipients": {
-                "type": "array",
-                "items": {
-                    "type": "string"
-                }
+            "description": {
+                "maxLength": 100,
+                "type": "string"
+            },
+            "tags": {
+                "maxLength": 200,
+                "type": "string"
             }
         },
         "additionalProperties": false,
         "required": [
-            "recipients"
+            "name",
+            "tags"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "UserModifySchema": {
+    "PruneSchema": {
+        "type": "object",
+        "properties": {
+            "days": {
+                "type": "integer"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "days"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "PurgeSchema": {
+        "type": "object",
+        "properties": {
+            "before": {
+                "type": "string"
+            },
+            "after": {
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "after",
+            "before"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "RegisterSchema": {
         "type": "object",
         "properties": {
             "username": {
+                "minLength": 2,
+                "maxLength": 32,
+                "type": "string"
+            },
+            "password": {
                 "minLength": 1,
-                "maxLength": 100,
+                "maxLength": 72,
+                "type": "string"
+            },
+            "consent": {
+                "type": "boolean"
+            },
+            "email": {
+                "format": "email",
+                "type": "string"
+            },
+            "fingerprint": {
+                "type": "string"
+            },
+            "invite": {
+                "type": "string"
+            },
+            "date_of_birth": {
+                "type": "string"
+            },
+            "gift_code_sku_id": {
+                "type": "string"
+            },
+            "captcha_key": {
                 "type": "string"
             },
+            "promotional_email_opt_in": {
+                "type": "boolean"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "consent",
+            "username"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "RelationshipPostSchema": {
+        "type": "object",
+        "properties": {
             "discriminator": {
                 "type": "string"
             },
-            "avatar": {
-                "type": [
-                    "null",
-                    "string"
-                ]
+            "username": {
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "discriminator",
+            "username"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "RelationshipPutSchema": {
+        "type": "object",
+        "properties": {
+            "type": {
+                "enum": [
+                    1,
+                    2,
+                    3,
+                    4
+                ],
+                "type": "number"
+            }
+        },
+        "additionalProperties": false,
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "RoleModifySchema": {
+        "type": "object",
+        "properties": {
+            "name": {
+                "type": "string"
             },
-            "bio": {
-                "maxLength": 1024,
+            "permissions": {
                 "type": "string"
             },
-            "accent_color": {
+            "color": {
                 "type": "integer"
             },
-            "banner": {
-                "type": [
-                    "null",
-                    "string"
-                ]
+            "hoist": {
+                "type": "boolean"
             },
-            "password": {
+            "mentionable": {
+                "type": "boolean"
+            },
+            "position": {
+                "type": "integer"
+            },
+            "icon": {
                 "type": "string"
             },
-            "new_password": {
+            "unicode_emoji": {
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "TemplateCreateSchema": {
+        "type": "object",
+        "properties": {
+            "name": {
                 "type": "string"
             },
-            "code": {
+            "description": {
                 "type": "string"
             }
         },
         "additionalProperties": false,
+        "required": [
+            "name"
+        ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "MfaCodesSchema": {
+    "TemplateModifySchema": {
         "type": "object",
         "properties": {
-            "password": {
+            "name": {
                 "type": "string"
             },
-            "regenerate": {
-                "type": "boolean"
+            "description": {
+                "type": "string"
             }
         },
         "additionalProperties": false,
         "required": [
-            "password"
+            "name"
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
@@ -1629,37 +1742,76 @@
         ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "RelationshipPutSchema": {
+    "TotpSchema": {
         "type": "object",
         "properties": {
-            "type": {
-                "enum": [
-                    1,
-                    2,
-                    3,
-                    4
-                ],
-                "type": "number"
+            "code": {
+                "type": "string"
+            },
+            "ticket": {
+                "type": "string"
+            },
+            "gift_code_sku_id": {
+                "type": [
+                    "null",
+                    "string"
+                ]
+            },
+            "login_source": {
+                "type": [
+                    "null",
+                    "string"
+                ]
             }
         },
         "additionalProperties": false,
+        "required": [
+            "code",
+            "ticket"
+        ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
-    "RelationshipPostSchema": {
+    "UserModifySchema": {
         "type": "object",
         "properties": {
+            "username": {
+                "minLength": 1,
+                "maxLength": 100,
+                "type": "string"
+            },
             "discriminator": {
                 "type": "string"
             },
-            "username": {
+            "avatar": {
+                "type": [
+                    "null",
+                    "string"
+                ]
+            },
+            "bio": {
+                "maxLength": 1024,
+                "type": "string"
+            },
+            "accent_color": {
+                "type": "integer"
+            },
+            "banner": {
+                "type": [
+                    "null",
+                    "string"
+                ]
+            },
+            "password": {
+                "type": "string"
+            },
+            "new_password": {
+                "type": "string"
+            },
+            "code": {
                 "type": "string"
             }
         },
         "additionalProperties": false,
-        "required": [
-            "discriminator",
-            "username"
-        ],
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
     "UserSettingsSchema": {
@@ -1880,5 +2032,332 @@
             }
         },
         "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "VanityUrlSchema": {
+        "type": "object",
+        "properties": {
+            "code": {
+                "minLength": 1,
+                "maxLength": 20,
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "VoiceStateUpdateSchema": {
+        "type": "object",
+        "properties": {
+            "channel_id": {
+                "type": "string"
+            },
+            "guild_id": {
+                "type": "string"
+            },
+            "suppress": {
+                "type": "boolean"
+            },
+            "request_to_speak_timestamp": {
+                "type": "string",
+                "format": "date-time"
+            },
+            "self_mute": {
+                "type": "boolean"
+            },
+            "self_deaf": {
+                "type": "boolean"
+            },
+            "self_video": {
+                "type": "boolean"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "channel_id"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "WebhookCreateSchema": {
+        "type": "object",
+        "properties": {
+            "name": {
+                "maxLength": 80,
+                "type": "string"
+            },
+            "avatar": {
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "name"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "WidgetModifySchema": {
+        "type": "object",
+        "properties": {
+            "enabled": {
+                "type": "boolean"
+            },
+            "channel_id": {
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "channel_id",
+            "enabled"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "RouteResponse": {
+        "type": "object",
+        "properties": {
+            "status": {
+                "type": "integer"
+            },
+            "body": {
+                "type": "array",
+                "items": {
+                    "type": "string"
+                }
+            },
+            "headers": {
+                "$ref": "#/definitions/Record<string,string>"
+            }
+        },
+        "additionalProperties": false,
+        "definitions": {
+            "Record<string,string>": {
+                "type": "object",
+                "additionalProperties": false
+            }
+        },
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "GatewayBotResponse": {
+        "type": "object",
+        "properties": {
+            "url": {
+                "type": "string"
+            },
+            "shards": {
+                "type": "integer"
+            },
+            "session_start_limit": {
+                "type": "object",
+                "properties": {
+                    "total": {
+                        "type": "integer"
+                    },
+                    "remaining": {
+                        "type": "integer"
+                    },
+                    "reset_after": {
+                        "type": "integer"
+                    },
+                    "max_concurrency": {
+                        "type": "integer"
+                    }
+                },
+                "additionalProperties": false,
+                "required": [
+                    "max_concurrency",
+                    "remaining",
+                    "reset_after",
+                    "total"
+                ]
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "session_start_limit",
+            "shards",
+            "url"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "GatewayResponse": {
+        "type": "object",
+        "properties": {
+            "url": {
+                "type": "string"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "url"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "ChannelReorderSchema": {
+        "type": "array",
+        "items": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "string"
+                },
+                "position": {
+                    "type": "integer"
+                },
+                "lock_permissions": {
+                    "type": "boolean"
+                },
+                "parent_id": {
+                    "type": "string"
+                }
+            },
+            "additionalProperties": false,
+            "required": [
+                "id"
+            ]
+        },
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "RolePositionUpdateSchema": {
+        "type": "array",
+        "items": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "string"
+                },
+                "position": {
+                    "type": "integer"
+                }
+            },
+            "additionalProperties": false,
+            "required": [
+                "id",
+                "position"
+            ]
+        },
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "UserProfileResponse": {
+        "type": "object",
+        "properties": {
+            "user": {
+                "$ref": "#/definitions/UserPublic"
+            },
+            "connected_accounts": {
+                "$ref": "#/definitions/PublicConnectedAccount"
+            },
+            "premium_guild_since": {
+                "type": "string",
+                "format": "date-time"
+            },
+            "premium_since": {
+                "type": "string",
+                "format": "date-time"
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "connected_accounts",
+            "user"
+        ],
+        "definitions": {
+            "UserPublic": {
+                "type": "object",
+                "properties": {
+                    "username": {
+                        "type": "string"
+                    },
+                    "discriminator": {
+                        "type": "string"
+                    },
+                    "id": {
+                        "type": "string"
+                    },
+                    "public_flags": {
+                        "type": "integer"
+                    },
+                    "avatar": {
+                        "type": "string"
+                    },
+                    "accent_color": {
+                        "type": "integer"
+                    },
+                    "banner": {
+                        "type": "string"
+                    },
+                    "bio": {
+                        "type": "string"
+                    },
+                    "bot": {
+                        "type": "boolean"
+                    },
+                    "premium_since": {
+                        "type": "string",
+                        "format": "date-time"
+                    }
+                },
+                "additionalProperties": false,
+                "required": [
+                    "bio",
+                    "bot",
+                    "discriminator",
+                    "id",
+                    "premium_since",
+                    "public_flags",
+                    "username"
+                ]
+            },
+            "PublicConnectedAccount": {
+                "type": "object",
+                "properties": {
+                    "name": {
+                        "type": "string"
+                    },
+                    "type": {
+                        "type": "string"
+                    },
+                    "verified": {
+                        "type": "boolean"
+                    }
+                },
+                "additionalProperties": false,
+                "required": [
+                    "name",
+                    "type",
+                    "verified"
+                ]
+            }
+        },
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
+    "UserRelationsResponse": {
+        "type": "object",
+        "properties": {
+            "object": {
+                "type": "object",
+                "properties": {
+                    "id": {
+                        "type": "string"
+                    },
+                    "username": {
+                        "type": "string"
+                    },
+                    "avatar": {
+                        "type": "string"
+                    },
+                    "discriminator": {
+                        "type": "string"
+                    },
+                    "public_flags": {
+                        "type": "integer"
+                    }
+                },
+                "additionalProperties": false
+            }
+        },
+        "additionalProperties": false,
+        "required": [
+            "object"
+        ],
+        "$schema": "http://json-schema.org/draft-07/schema#"
     }
 }
\ No newline at end of file
diff --git a/api/src/routes/auth/login.ts b/api/src/routes/auth/login.ts
index daef6056..9fc5924d 100644
--- a/api/src/routes/auth/login.ts
+++ b/api/src/routes/auth/login.ts
@@ -1,21 +1,12 @@
 import { Request, Response, Router } from "express";
 import { route } from "@fosscord/api";
 import bcrypt from "bcrypt";
-import { Config, User, generateToken, adjustEmail, FieldErrors } from "@fosscord/util";
+import { Config, User, generateToken, adjustEmail, FieldErrors, LoginSchema } from "@fosscord/util";
 import crypto from "crypto";
 
 const router: Router = Router();
 export default router;
 
-export interface LoginSchema {
-	login: string;
-	password: string;
-	undelete?: boolean;
-	captcha_key?: string;
-	login_source?: string;
-	gift_code_sku_id?: string;
-}
-
 router.post("/", route({ body: "LoginSchema" }), async (req: Request, res: Response) => {
 	const { login, password, captcha_key, undelete } = req.body as LoginSchema;
 	const email = adjustEmail(login);
diff --git a/api/src/routes/auth/mfa/totp.ts b/api/src/routes/auth/mfa/totp.ts
index 255cf889..421dbafa 100644
--- a/api/src/routes/auth/mfa/totp.ts
+++ b/api/src/routes/auth/mfa/totp.ts
@@ -1,17 +1,10 @@
 import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
-import { BackupCode, FieldErrors, generateToken, User } from "@fosscord/util";
+import { BackupCode, FieldErrors, generateToken, TotpSchema, User } from "@fosscord/util";
 import { verifyToken } from "node-2fa";
 import { HTTPError } from "lambert-server";
 const router = Router();
 
-export interface TotpSchema {
-	code: string,
-	ticket: string,
-	gift_code_sku_id?: string | null,
-	login_source?: string | null,
-}
-
 router.post("/", route({ body: "TotpSchema" }), async (req: Request, res: Response) => {
 	const { code, ticket, gift_code_sku_id, login_source } = req.body as TotpSchema;
 
diff --git a/api/src/routes/auth/register.ts b/api/src/routes/auth/register.ts
index 5a3d27e9..09366a12 100644
--- a/api/src/routes/auth/register.ts
+++ b/api/src/routes/auth/register.ts
@@ -1,38 +1,11 @@
 import { Request, Response, Router } from "express";
-import { Config, generateToken, Invite, FieldErrors, User, adjustEmail, trimSpecial } from "@fosscord/util";
+import { Config, generateToken, Invite, FieldErrors, User, adjustEmail, trimSpecial, RegisterSchema } from "@fosscord/util";
 import { route, getIpAdress, IPAnalysis, isProxy } from "@fosscord/api";
 import bcrypt from "bcrypt";
 import { HTTPError } from "@fosscord/util";
 
 const router: Router = Router();
 
-export interface RegisterSchema {
-	/**
-	 * @minLength 2
-	 * @maxLength 32
-	 */
-	username: string;
-	/**
-	 * @minLength 1
-	 * @maxLength 72
-	 */
-	password?: string;
-	consent: boolean;
-	/**
-	 * @TJS-format email
-	 */
-	email?: string;
-	fingerprint?: string;
-	invite?: string;
-	/**
-	 * @TJS-type string
-	 */
-	date_of_birth?: Date; // "2000-04-03"
-	gift_code_sku_id?: string;
-	captcha_key?: string;
-	promotional_email_opt_in?: boolean;
-}
-
 router.post("/", route({ body: "RegisterSchema" }), async (req: Request, res: Response) => {
 	const body = req.body as RegisterSchema;
 	const { register, security } = Config.get();
diff --git a/api/src/routes/channels/#channel_id/index.ts b/api/src/routes/channels/#channel_id/index.ts
index 70c34f05..bb8b868b 100644
--- a/api/src/routes/channels/#channel_id/index.ts
+++ b/api/src/routes/channels/#channel_id/index.ts
@@ -6,7 +6,8 @@ import {
 	ChannelUpdateEvent,
 	emitEvent,
 	Recipient,
-	handleFile
+	handleFile,
+	ChannelModifySchema
 } from "@fosscord/util";
 import { Request, Response, Router } from "express";
 import { route } from "@fosscord/api";
@@ -48,33 +49,6 @@ router.delete("/", route({ permission: "MANAGE_CHANNELS" }), async (req: Request
 	res.send(channel);
 });
 
-export interface ChannelModifySchema {
-	/**
-	 * @maxLength 100
-	 */
-	name?: string;
-	type?: ChannelType;
-	topic?: string;
-	icon?: string | null;
-	bitrate?: number;
-	user_limit?: number;
-	rate_limit_per_user?: number;
-	position?: number;
-	permission_overwrites?: {
-		id: string;
-		type: ChannelPermissionOverwriteType;
-		allow: string;
-		deny: string;
-	}[];
-	parent_id?: string;
-	id?: string; // is not used (only for guild create)
-	nsfw?: boolean;
-	rtc_region?: string;
-	default_auto_archive_duration?: number;
-	flags?: number;
-	default_thread_rate_limit_per_user?: number;
-}
-
 router.patch("/", route({ body: "ChannelModifySchema", permission: "MANAGE_CHANNELS" }), async (req: Request, res: Response) => {
 	let payload = req.body as ChannelModifySchema;
 	const { channel_id } = req.params;
diff --git a/api/src/routes/channels/#channel_id/invites.ts b/api/src/routes/channels/#channel_id/invites.ts
index f111cf54..b5c65c0d 100644
--- a/api/src/routes/channels/#channel_id/invites.ts
+++ b/api/src/routes/channels/#channel_id/invites.ts
@@ -8,18 +8,6 @@ import { OrmUtils } from "@fosscord/util";
 
 const router: Router = Router();
 
-export interface InviteCreateSchema {
-	target_user_id?: string;
-	target_type?: string;
-	validate?: string; // ? what is this
-	max_age?: number;
-	max_uses?: number;
-	temporary?: boolean;
-	unique?: boolean;
-	target_user?: string;
-	target_user_type?: number;
-}
-
 router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE", right: "CREATE_INVITES" }),
 			async (req: Request, res: Response) => {
 	const { user_id } = req;
diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts b/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts
index c1b8d20f..041f4d5e 100644
--- a/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts
+++ b/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts
@@ -5,15 +5,6 @@ import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
 
-// TODO: public read receipts & privacy scoping
-// TODO: send read state event to all channel members
-// TODO: advance-only notification cursor
-
-export interface MessageAcknowledgeSchema {
-	manual?: boolean;
-	mention_count?: number;
-}
-
 router.post("/", route({ body: "MessageAcknowledgeSchema" }), async (req: Request, res: Response) => {
 	const { channel_id, message_id } = req.params;
 
diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts b/api/src/routes/channels/#channel_id/messages/#message_id/index.ts
index b3b310d3..d7e27062 100644
--- a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts
+++ b/api/src/routes/channels/#channel_id/messages/#message_id/index.ts
@@ -12,13 +12,13 @@ import {
 	MessageDeleteEvent,
 	MessageUpdateEvent,
 	Snowflake,
-	uploadFile 
+	uploadFile, 
+	MessageCreateSchema
 } from "@fosscord/util";
 import { Router, Response, Request } from "express";
 import multer from "multer";
 import { route } from "@fosscord/api";
 import { handleMessage, postHandleMessage } from "@fosscord/api";
-import { MessageCreateSchema } from "../index";
 import { HTTPError } from "@fosscord/util";
 
 const router = Router();
diff --git a/api/src/routes/channels/#channel_id/messages/bulk-delete.ts b/api/src/routes/channels/#channel_id/messages/bulk-delete.ts
index 2e40f110..24a33d2d 100644
--- a/api/src/routes/channels/#channel_id/messages/bulk-delete.ts
+++ b/api/src/routes/channels/#channel_id/messages/bulk-delete.ts
@@ -8,10 +8,6 @@ const router: Router = Router();
 
 export default router;
 
-export interface BulkDeleteSchema {
-	messages: string[];
-}
-
 // should users be able to bulk delete messages or only bots? ANSWER: all users
 // should this request fail, if you provide messages older than 14 days/invalid ids? ANSWER: NO
 // https://discord.com/developers/docs/resources/channel#bulk-delete-messages
diff --git a/api/src/routes/channels/#channel_id/messages/index.ts b/api/src/routes/channels/#channel_id/messages/index.ts
index c2057422..9ab0d97d 100644
--- a/api/src/routes/channels/#channel_id/messages/index.ts
+++ b/api/src/routes/channels/#channel_id/messages/index.ts
@@ -5,7 +5,6 @@ import {
 	ChannelType,
 	Config,
 	DmChannelDTO,
-	Embed,
 	emitEvent,
 	getPermission,
 	getRights,
@@ -13,7 +12,8 @@ import {
 	MessageCreateEvent,
 	Snowflake,
 	uploadFile,
-	Member
+	Member,
+	MessageCreateSchema
 } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { handleMessage, postHandleMessage, route } from "@fosscord/api";
@@ -49,38 +49,6 @@ export function isTextChannel(type: ChannelType): boolean {
 	}
 }
 
-export interface MessageCreateSchema {
-	type?: number;
-	content?: string;
-	nonce?: string;
-	channel_id?: string;
-	tts?: boolean;
-	flags?: string;
-	embeds?: Embed[];
-	embed?: Embed;
-	// TODO: ^ embed is deprecated in favor of embeds (https://discord.com/developers/docs/resources/channel#message-object)
-	allowed_mentions?: {
-		parse?: string[];
-		roles?: string[];
-		users?: string[];
-		replied_user?: boolean;
-	};
-	message_reference?: {
-		message_id: string;
-		channel_id: string;
-		guild_id?: string;
-		fail_if_not_exists?: boolean;
-	};
-	payload_json?: string;
-	file?: any;
-	/**
-	TODO: we should create an interface for attachments
-	TODO: OpenWAAO<-->attachment-style metadata conversion
-	**/
-	attachments?: any[];
-	sticker_ids?: string[];
-}
-
 // https://discord.com/developers/docs/resources/channel#create-message
 // get messages
 router.get("/", async (req: Request, res: Response) => {
diff --git a/api/src/routes/channels/#channel_id/permissions.ts b/api/src/routes/channels/#channel_id/permissions.ts
index 06a124bb..34052fe5 100644
--- a/api/src/routes/channels/#channel_id/permissions.ts
+++ b/api/src/routes/channels/#channel_id/permissions.ts
@@ -1,6 +1,7 @@
 import {
 	Channel,
 	ChannelPermissionOverwrite,
+	ChannelPermissionOverwriteSchema,
 	ChannelPermissionOverwriteType,
 	ChannelUpdateEvent,
 	emitEvent,
@@ -10,13 +11,9 @@ import {
 } from "@fosscord/util";
 import { Router, Response, Request } from "express";
 import { HTTPError } from "@fosscord/util";
-
 import { route } from "@fosscord/api";
-const router: Router = Router();
 
-// TODO: Only permissions your bot has in the guild or channel can be allowed/denied (unless your bot has a MANAGE_ROLES overwrite in the channel)
-
-export interface ChannelPermissionOverwriteSchema extends ChannelPermissionOverwrite {}
+const router: Router = Router();
 
 router.put(
 	"/:overwrite_id",
diff --git a/api/src/routes/channels/#channel_id/purge.ts b/api/src/routes/channels/#channel_id/purge.ts
index 7ab4ad9a..1ef6e1d7 100644
--- a/api/src/routes/channels/#channel_id/purge.ts
+++ b/api/src/routes/channels/#channel_id/purge.ts
@@ -1,4 +1,4 @@
-import { HTTPError } from "@fosscord/util";
+import { HTTPError, PurgeSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { isTextChannel } from "./messages";
 import { FindManyOptions, Between, Not } from "typeorm";
@@ -10,11 +10,6 @@ const router: Router = Router();
 
 export default router;
 
-export interface PurgeSchema {
-	before: string;
-	after: string;
-}
-
 /**
 TODO: apply the delete bit by bit to prevent client and database stress
 **/
diff --git a/api/src/routes/channels/#channel_id/webhooks.ts b/api/src/routes/channels/#channel_id/webhooks.ts
index 00bf4619..b11c8eb9 100644
--- a/api/src/routes/channels/#channel_id/webhooks.ts
+++ b/api/src/routes/channels/#channel_id/webhooks.ts
@@ -6,14 +6,6 @@ import { isTextChannel } from "./messages/index";
 import { DiscordApiErrors } from "@fosscord/util";
 
 const router: Router = Router();
-// TODO: webhooks
-export interface WebhookCreateSchema {
-	/**
-	 * @maxLength 80
-	 */
-	name: string;
-	avatar?: string;
-}
 //TODO: implement webhooks
 router.get("/", route({}), async (req: Request, res: Response) => {
 	res.json([]);
diff --git a/api/src/routes/guilds/#guild_id/audit-logs.ts b/api/src/routes/guilds/#guild_id/audit-logs.ts
index 7b1d0062..b54835fc 100644
--- a/api/src/routes/guilds/#guild_id/audit-logs.ts
+++ b/api/src/routes/guilds/#guild_id/audit-logs.ts
@@ -1,8 +1,5 @@
 import { Router, Response, Request } from "express";
-import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
-import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { ChannelModifySchema } from "../../channels/#channel_id";
 const router = Router();
 
 //TODO: implement audit logs
diff --git a/api/src/routes/guilds/#guild_id/bans.ts b/api/src/routes/guilds/#guild_id/bans.ts
index 0743687d..3d405344 100644
--- a/api/src/routes/guilds/#guild_id/bans.ts
+++ b/api/src/routes/guilds/#guild_id/bans.ts
@@ -1,31 +1,9 @@
 import { Request, Response, Router } from "express";
-import { DiscordApiErrors, emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member } from "@fosscord/util";
+import { DiscordApiErrors, emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member, BanRegistrySchema, BanModeratorSchema } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { getIpAdress, route } from "@fosscord/api";
 import { OrmUtils } from "@fosscord/util";
 
-export interface BanCreateSchema {
-	delete_message_days?: string;
-	reason?: string;
-};
-
-export interface BanRegistrySchema {
-	id: string;
-	user_id: string;
-	guild_id: string;
-	executor_id: string;
-	ip?: string;
-	reason?: string | undefined;
-};
-
-export interface BanModeratorSchema {
-	id: string;
-	user_id: string;
-	guild_id: string;
-	executor_id: string;
-	reason?: string | undefined;
-};
-
 const router: Router = Router();
 
 /* TODO: Deleting the secrets is just a temporary go-around. Views should be implemented for both safety and better handling. */
diff --git a/api/src/routes/guilds/#guild_id/channels.ts b/api/src/routes/guilds/#guild_id/channels.ts
index b952b474..df1b7924 100644
--- a/api/src/routes/guilds/#guild_id/channels.ts
+++ b/api/src/routes/guilds/#guild_id/channels.ts
@@ -1,8 +1,7 @@
 import { Router, Response, Request } from "express";
-import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
+import { Channel, ChannelUpdateEvent, getPermission, emitEvent, ChannelModifySchema } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { ChannelModifySchema } from "../../channels/#channel_id";
 const router = Router();
 
 router.get("/", route({}), async (req: Request, res: Response) => {
diff --git a/api/src/routes/guilds/#guild_id/emojis.ts b/api/src/routes/guilds/#guild_id/emojis.ts
index 53a44ec3..4bf4bdcd 100644
--- a/api/src/routes/guilds/#guild_id/emojis.ts
+++ b/api/src/routes/guilds/#guild_id/emojis.ts
@@ -1,22 +1,10 @@
 import { Router, Request, Response } from "express";
-import { Config, DiscordApiErrors, emitEvent, Emoji, GuildEmojisUpdateEvent, handleFile, Member, Snowflake, User } from "@fosscord/util";
+import { Config, DiscordApiErrors, emitEvent, Emoji, EmojiCreateSchema, EmojiModifySchema, GuildEmojisUpdateEvent, handleFile, Member, Snowflake, User } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
 
-export interface EmojiCreateSchema {
-	name?: string;
-	image: string;
-	require_colons?: boolean | null;
-	roles?: string[];
-}
-
-export interface EmojiModifySchema {
-	name?: string;
-	roles?: string[];
-}
-
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id } = req.params;
 
diff --git a/api/src/routes/guilds/#guild_id/index.ts b/api/src/routes/guilds/#guild_id/index.ts
index 8d61f753..a9712c71 100644
--- a/api/src/routes/guilds/#guild_id/index.ts
+++ b/api/src/routes/guilds/#guild_id/index.ts
@@ -1,29 +1,11 @@
 import { Request, Response, Router } from "express";
-import { DiscordApiErrors, emitEvent, getPermission, getRights, Guild, GuildUpdateEvent, handleFile, Member } from "@fosscord/util";
+import { DiscordApiErrors, emitEvent, getPermission, getRights, Guild, GuildUpdateEvent, GuildUpdateSchema, handleFile, Member } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { GuildCreateSchema } from "../index";
 import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
 
-export interface GuildUpdateSchema extends Omit<GuildCreateSchema, "channels" | "name"> {
-	name?: string;
-	banner?: string | null;
-	splash?: string | null;
-	description?: string;
-	features?: string[];
-	verification_level?: number;
-	default_message_notifications?: number;
-	system_channel_flags?: number;
-	explicit_content_filter?: number;
-	public_updates_channel_id?: string;
-	afk_timeout?: number;
-	afk_channel_id?: string;
-	preferred_locale?: string;
-	premium_progress_bar_enabled?: boolean;
-}
-
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id } = req.params;
 
diff --git a/api/src/routes/guilds/#guild_id/integrations.ts b/api/src/routes/guilds/#guild_id/integrations.ts
index 19f68563..90650111 100644
--- a/api/src/routes/guilds/#guild_id/integrations.ts
+++ b/api/src/routes/guilds/#guild_id/integrations.ts
@@ -2,7 +2,6 @@ import { Router, Response, Request } from "express";
 import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { ChannelModifySchema } from "../../channels/#channel_id";
 const router = Router();
 
 //TODO: implement integrations list
diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/index.ts b/api/src/routes/guilds/#guild_id/members/#member_id/index.ts
index 824e34a4..794369d8 100644
--- a/api/src/routes/guilds/#guild_id/members/#member_id/index.ts
+++ b/api/src/routes/guilds/#guild_id/members/#member_id/index.ts
@@ -1,15 +1,11 @@
 import { Request, Response, Router } from "express";
-import { Member, getPermission, getRights, Role, GuildMemberUpdateEvent, emitEvent, Sticker, Emoji, Rights, Guild } from "@fosscord/util";
+import { Member, getPermission, getRights, Role, GuildMemberUpdateEvent, emitEvent, Sticker, Emoji, Rights, Guild, MemberChangeSchema } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
 
-export interface MemberChangeSchema {
-	roles?: string[];
-}
-
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id, member_id } = req.params;
 	await Member.IsInGuildOrFail(req.user_id, guild_id);
diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts b/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts
index 4dfae8da..a6c71333 100644
--- a/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts
+++ b/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts
@@ -4,10 +4,6 @@ import { Request, Response, Router } from "express";
 
 const router = Router();
 
-export interface MemberNickChangeSchema {
-	nick: string;
-}
-
 router.patch("/", route({ body: "MemberNickChangeSchema" }), async (req: Request, res: Response) => {
 	let { guild_id, member_id } = req.params;
 	let permissionString: PermissionResolvable = "MANAGE_NICKNAMES";
diff --git a/api/src/routes/guilds/#guild_id/prune.ts b/api/src/routes/guilds/#guild_id/prune.ts
index 01f18ce4..673f022f 100644
--- a/api/src/routes/guilds/#guild_id/prune.ts
+++ b/api/src/routes/guilds/#guild_id/prune.ts
@@ -62,13 +62,6 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	res.send({ pruned: members.length });
 });
 
-export interface PruneSchema {
-	/**
-	 * @min 0
-	 */
-	days: number;
-}
-
 router.post("/", route({ permission: "KICK_MEMBERS", right: "KICK_BAN_MEMBERS" }), async (req: Request, res: Response) => {
 	const days = parseInt(req.body.days);
 
diff --git a/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts b/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts
index 0482b9ca..d4422a9c 100644
--- a/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts
+++ b/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts
@@ -1,8 +1,7 @@
 import { Router, Request, Response } from "express";
-import { Role, Member, GuildRoleUpdateEvent, GuildRoleDeleteEvent, emitEvent, handleFile } from "@fosscord/util";
+import { Role, Member, GuildRoleUpdateEvent, GuildRoleDeleteEvent, emitEvent, handleFile, RoleModifySchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { HTTPError } from "@fosscord/util";
-import { RoleModifySchema } from "../";
 import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
diff --git a/api/src/routes/guilds/#guild_id/roles/index.ts b/api/src/routes/guilds/#guild_id/roles/index.ts
index 6fbb8702..effa4fcd 100644
--- a/api/src/routes/guilds/#guild_id/roles/index.ts
+++ b/api/src/routes/guilds/#guild_id/roles/index.ts
@@ -9,7 +9,8 @@ import {
 	emitEvent,
 	Config,
 	DiscordApiErrors,
-	handleFile
+	handleFile,
+	RoleModifySchema
 } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
@@ -17,17 +18,6 @@ import { OrmUtils } from "@fosscord/util";
 
 const router: Router = Router();
 
-export interface RoleModifySchema {
-	name?: string;
-	permissions?: string;
-	color?: number;
-	hoist?: boolean; // whether the role should be displayed separately in the sidebar
-	mentionable?: boolean; // whether the role should be mentionable
-	position?: number;
-	icon?: string;
-	unicode_emoji?: string;
-}
-
 export type RolePositionUpdateSchema = {
 	id: string;
 	position: number;
diff --git a/api/src/routes/guilds/#guild_id/stickers.ts b/api/src/routes/guilds/#guild_id/stickers.ts
index 157ccff4..71c9dfcd 100644
--- a/api/src/routes/guilds/#guild_id/stickers.ts
+++ b/api/src/routes/guilds/#guild_id/stickers.ts
@@ -3,6 +3,7 @@ import {
 	GuildStickersUpdateEvent,
 	handleFile,
 	Member,
+	ModifyGuildStickerSchema,
 	Snowflake,
 	Sticker,
 	StickerFormatType,
@@ -83,22 +84,6 @@ router.get("/:sticker_id", route({}), async (req: Request, res: Response) => {
 	res.json(await Sticker.findOneOrFail({ where: { guild_id, id: sticker_id } }));
 });
 
-export interface ModifyGuildStickerSchema {
-	/**
-	 * @minLength 2
-	 * @maxLength 30
-	 */
-	name: string;
-	/**
-	 * @maxLength 100
-	 */
-	description?: string;
-	/**
-	 * @maxLength 200
-	 */
-	tags: string;
-}
-
 router.patch(
 	"/:sticker_id",
 	route({ body: "ModifyGuildStickerSchema", permission: "MANAGE_EMOJIS_AND_STICKERS" }),
diff --git a/api/src/routes/guilds/#guild_id/templates.ts b/api/src/routes/guilds/#guild_id/templates.ts
index 3d14de41..9c79692d 100644
--- a/api/src/routes/guilds/#guild_id/templates.ts
+++ b/api/src/routes/guilds/#guild_id/templates.ts
@@ -24,16 +24,6 @@ const TemplateGuildProjection: (keyof Guild)[] = [
 	"icon"
 ];
 
-export interface TemplateCreateSchema {
-	name: string;
-	description?: string;
-}
-
-export interface TemplateModifySchema {
-	name: string;
-	description?: string;
-}
-
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id } = req.params;
 
diff --git a/api/src/routes/guilds/#guild_id/vanity-url.ts b/api/src/routes/guilds/#guild_id/vanity-url.ts
index ac46e18a..ff92ce8d 100644
--- a/api/src/routes/guilds/#guild_id/vanity-url.ts
+++ b/api/src/routes/guilds/#guild_id/vanity-url.ts
@@ -1,4 +1,4 @@
-import { Channel, ChannelType, getPermission, Guild, Invite, trimSpecial } from "@fosscord/util";
+import { Channel, ChannelType, getPermission, Guild, Invite, trimSpecial, VanityUrlSchema } from "@fosscord/util";
 import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
 import { HTTPError } from "@fosscord/util";
@@ -25,14 +25,6 @@ router.get("/", route({ permission: "MANAGE_GUILD" }), async (req: Request, res:
 	}
 });
 
-export interface VanityUrlSchema {
-	/**
-	 * @minLength 1
-	 * @maxLength 20
-	 */
-	code?: string;
-}
-
 router.patch("/", route({ body: "VanityUrlSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
 	const { guild_id } = req.params;
 	const body = req.body as VanityUrlSchema;
diff --git a/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts b/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts
index 32d1aadf..28a9e8c1 100644
--- a/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts
+++ b/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts
@@ -1,21 +1,9 @@
-import { Channel, ChannelType, DiscordApiErrors, emitEvent, getPermission, VoiceState, VoiceStateUpdateEvent } from "@fosscord/util";
+import { Channel, ChannelType, DiscordApiErrors, emitEvent, getPermission, VoiceState, VoiceStateUpdateEvent, VoiceStateUpdateSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { Request, Response, Router } from "express";
 import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
-//TODO need more testing when community guild and voice stage channel are working
-
-export interface VoiceStateUpdateSchema {
-	channel_id: string;
-	guild_id?: string;
-	suppress?: boolean;
-	request_to_speak_timestamp?: Date;
-	self_mute?: boolean;
-	self_deaf?: boolean;
-	self_video?: boolean;
-}
-
 router.patch("/", route({ body: "VoiceStateUpdateSchema" }), async (req: Request, res: Response) => {
 	const body = req.body as VoiceStateUpdateSchema;
 	let { guild_id, user_id } = req.params;
diff --git a/api/src/routes/guilds/#guild_id/webhooks.ts b/api/src/routes/guilds/#guild_id/webhooks.ts
index 7f5b9592..c8c1eb5c 100644
--- a/api/src/routes/guilds/#guild_id/webhooks.ts
+++ b/api/src/routes/guilds/#guild_id/webhooks.ts
@@ -2,7 +2,6 @@ import { Router, Response, Request } from "express";
 import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { ChannelModifySchema } from "../../channels/#channel_id";
 const router = Router();
 
 //TODO: implement webhooks
diff --git a/api/src/routes/guilds/#guild_id/welcome_screen.ts b/api/src/routes/guilds/#guild_id/welcome_screen.ts
index 4093ec1d..d08300ba 100644
--- a/api/src/routes/guilds/#guild_id/welcome_screen.ts
+++ b/api/src/routes/guilds/#guild_id/welcome_screen.ts
@@ -1,21 +1,10 @@
 import { Request, Response, Router } from "express";
-import { Guild, getPermission, Snowflake, Member } from "@fosscord/util";
+import { Guild, getPermission, Snowflake, Member, GuildUpdateWelcomeScreenSchema } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
 
 const router: Router = Router();
 
-export interface GuildUpdateWelcomeScreenSchema {
-	welcome_channels?: {
-		channel_id: string;
-		description: string;
-		emoji_id?: string;
-		emoji_name: string;
-	}[];
-	enabled?: boolean;
-	description?: string;
-}
-
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const guild_id = req.params.guild_id;
 
diff --git a/api/src/routes/guilds/#guild_id/widget.ts b/api/src/routes/guilds/#guild_id/widget.ts
index 103f84a3..dbb4cc0c 100644
--- a/api/src/routes/guilds/#guild_id/widget.ts
+++ b/api/src/routes/guilds/#guild_id/widget.ts
@@ -1,12 +1,7 @@
 import { Request, Response, Router } from "express";
-import { Guild } from "@fosscord/util";
+import { Guild, WidgetModifySchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 
-export interface WidgetModifySchema {
-	enabled: boolean; // whether the widget is enabled
-	channel_id: string; // the widget channel id
-}
-
 const router: Router = Router();
 
 // https://discord.com/developers/docs/resources/guild#get-guild-widget-settings
diff --git a/api/src/routes/guilds/index.ts b/api/src/routes/guilds/index.ts
index 64b9454b..e4d66192 100644
--- a/api/src/routes/guilds/index.ts
+++ b/api/src/routes/guilds/index.ts
@@ -1,23 +1,9 @@
 import { Router, Request, Response } from "express";
-import { Role, Guild, Snowflake, Config, getRights, Member, Channel, DiscordApiErrors, handleFile } from "@fosscord/util";
+import { Role, Guild, Snowflake, Config, getRights, Member, Channel, DiscordApiErrors, handleFile, GuildCreateSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { ChannelModifySchema } from "../channels/#channel_id";
 
 const router: Router = Router();
 
-export interface GuildCreateSchema {
-	/**
-	 * @maxLength 100
-	 */
-	name: string;
-	region?: string;
-	icon?: string | null;
-	channels?: ChannelModifySchema[];
-	guild_template_code?: string;
-	system_channel_id?: string;
-	rules_channel_id?: string;
-}
-
 //TODO: create default channel
 
 router.post("/", route({ body: "GuildCreateSchema", right: "CREATE_GUILDS" }), async (req: Request, res: Response) => {
diff --git a/api/src/routes/guilds/templates/index.ts b/api/src/routes/guilds/templates/index.ts
index bac4eb8a..3a0de9e8 100644
--- a/api/src/routes/guilds/templates/index.ts
+++ b/api/src/routes/guilds/templates/index.ts
@@ -1,15 +1,8 @@
 import { Request, Response, Router } from "express";
-import { Template, Guild, Role, Snowflake, Config, User, Member } from "@fosscord/util";
+import { Template, Guild, Role, Snowflake, Config, User, Member, DiscordApiErrors, OrmUtils, GuildTemplateCreateSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { DiscordApiErrors } from "@fosscord/util";
 import fetch from "node-fetch";
 const router: Router = Router();
-import { OrmUtils } from "@fosscord/util";
-
-export interface GuildTemplateCreateSchema {
-	name: string;
-	avatar?: string | null;
-}
 
 router.get("/:code", route({}), async (req: Request, res: Response) => {
 	const { allowDiscordTemplates, allowRaws, enabled } = Config.get().templates;
diff --git a/api/src/routes/users/@me/channels.ts b/api/src/routes/users/@me/channels.ts
index 78f531e1..ad483529 100644
--- a/api/src/routes/users/@me/channels.ts
+++ b/api/src/routes/users/@me/channels.ts
@@ -1,5 +1,5 @@
 import { Request, Response, Router } from "express";
-import { Recipient, DmChannelDTO, Channel } from "@fosscord/util";
+import { Recipient, DmChannelDTO, Channel, DmChannelCreateSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 
 const router: Router = Router();
@@ -12,11 +12,6 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	res.json(await Promise.all(recipients.map((r) => DmChannelDTO.from(r.channel, [req.user_id]))));
 });
 
-export interface DmChannelCreateSchema {
-	name?: string;
-	recipients: string[];
-}
-
 router.post("/", route({ body: "DmChannelCreateSchema" }), async (req: Request, res: Response) => {
 	const body = req.body as DmChannelCreateSchema;
 	res.json(await Channel.createDMChannel(body.recipients, req.user_id, body.name));
diff --git a/api/src/routes/users/@me/index.ts b/api/src/routes/users/@me/index.ts
index 4cf96a8d..7d095451 100644
--- a/api/src/routes/users/@me/index.ts
+++ b/api/src/routes/users/@me/index.ts
@@ -1,30 +1,11 @@
 import { Router, Request, Response } from "express";
-import { User, PrivateUserProjection, emitEvent, UserUpdateEvent, handleFile, FieldErrors } from "@fosscord/util";
+import { User, PrivateUserProjection, emitEvent, UserUpdateEvent, handleFile, FieldErrors, UserModifySchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import bcrypt from "bcrypt";
 import { OrmUtils, generateToken } from "@fosscord/util";
 
 const router: Router = Router();
 
-export interface UserModifySchema {
-	/**
-	 * @minLength 1
-	 * @maxLength 100
-	 */
-	username?: string;
-	discriminator?: string;
-	avatar?: string | null;
-	/**
-	 * @maxLength 1024
-	 */
-	bio?: string;
-	accent_color?: number;
-	banner?: string | null;
-	password?: string;
-	new_password?: string;
-	code?: string;
-}
-
 router.get("/", route({}), async (req: Request, res: Response) => {
 	res.json(await User.findOne({ select: PrivateUserProjection, where: { id: req.user_id } }));
 });
diff --git a/api/src/routes/users/@me/mfa/codes.ts b/api/src/routes/users/@me/mfa/codes.ts
index 75e3e964..4224a1c0 100644
--- a/api/src/routes/users/@me/mfa/codes.ts
+++ b/api/src/routes/users/@me/mfa/codes.ts
@@ -1,15 +1,10 @@
 import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
-import { BackupCode, Config, FieldErrors, generateMfaBackupCodes, User } from "@fosscord/util";
+import { BackupCode, Config, FieldErrors, generateMfaBackupCodes, MfaCodesSchema, User } from "@fosscord/util";
 import bcrypt from "bcrypt";
 
 const router = Router();
 
-export interface MfaCodesSchema {
-	password: string;
-	regenerate?: boolean;
-}
-
 // TODO: This route is replaced with users/@me/mfa/codes-verification in newer clients
 
 router.post("/", route({ body: "MfaCodesSchema" }), async (req: Request, res: Response) => {
diff --git a/api/src/routes/users/@me/mfa/totp/disable.ts b/api/src/routes/users/@me/mfa/totp/disable.ts
index 2d385fda..2fe9355c 100644
--- a/api/src/routes/users/@me/mfa/totp/disable.ts
+++ b/api/src/routes/users/@me/mfa/totp/disable.ts
@@ -2,14 +2,10 @@ import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
 import { verifyToken } from 'node-2fa';
 import { HTTPError } from "lambert-server";
-import { User, generateToken, BackupCode } from "@fosscord/util";
+import { User, generateToken, BackupCode, TotpDisableSchema } from "@fosscord/util";
 
 const router = Router();
 
-export interface TotpDisableSchema {
-	code: string;
-}
-
 router.post("/", route({ body: "TotpDisableSchema" }), async (req: Request, res: Response) => {
 	const body = req.body as TotpDisableSchema;
 
diff --git a/api/src/routes/users/@me/mfa/totp/enable.ts b/api/src/routes/users/@me/mfa/totp/enable.ts
index 87f36d55..ac668d1d 100644
--- a/api/src/routes/users/@me/mfa/totp/enable.ts
+++ b/api/src/routes/users/@me/mfa/totp/enable.ts
@@ -1,5 +1,5 @@
 import { Router, Request, Response } from "express";
-import { User, generateToken, BackupCode, generateMfaBackupCodes, Config } from "@fosscord/util";
+import { User, generateToken, BackupCode, generateMfaBackupCodes, Config, TotpEnableSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import bcrypt from "bcrypt";
 import { HTTPError } from "lambert-server";
@@ -7,12 +7,6 @@ import { verifyToken } from 'node-2fa';
 
 const router = Router();
 
-export interface TotpEnableSchema {
-	password: string;
-	code?: string;
-	secret?: string;
-}
-
 router.post("/", route({ body: "TotpEnableSchema" }), async (req: Request, res: Response) => {
 	const body = req.body as TotpEnableSchema;
 
diff --git a/api/src/routes/users/@me/relationships.ts b/api/src/routes/users/@me/relationships.ts
index 6e22f4f3..f7464b99 100644
--- a/api/src/routes/users/@me/relationships.ts
+++ b/api/src/routes/users/@me/relationships.ts
@@ -38,10 +38,6 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	return res.json(related_users);
 });
 
-export interface RelationshipPutSchema {
-	type?: RelationshipType;
-}
-
 router.put("/:id", route({ body: "RelationshipPutSchema" }), async (req: Request, res: Response) => {
 	return await updateRelationship(
 		req,
@@ -51,11 +47,6 @@ router.put("/:id", route({ body: "RelationshipPutSchema" }), async (req: Request
 	);
 });
 
-export interface RelationshipPostSchema {
-	discriminator: string;
-	username: string;
-}
-
 router.post("/", route({ body: "RelationshipPostSchema" }), async (req: Request, res: Response) => {
 	return await updateRelationship(
 		req,
diff --git a/api/src/routes/users/@me/settings.ts b/api/src/routes/users/@me/settings.ts
index d832575f..7578d36e 100644
--- a/api/src/routes/users/@me/settings.ts
+++ b/api/src/routes/users/@me/settings.ts
@@ -4,8 +4,6 @@ import { route } from "@fosscord/api";
 
 const router = Router();
 
-export interface UserSettingsSchema extends Partial<UserSettings> {}
-
 router.patch("/", route({ body: "UserSettingsSchema" }), async (req: Request, res: Response) => {
 	const body = req.body as UserSettings;
 	if (body.locale === "en") body.locale = "en-US"; // fix discord client crash on unkown locale
diff --git a/api/src/util/handlers/Message.ts b/api/src/util/handlers/Message.ts
index 0f584c56..ff5ece75 100644
--- a/api/src/util/handlers/Message.ts
+++ b/api/src/util/handlers/Message.ts
@@ -21,12 +21,13 @@ import {
 	Webhook,
 	Attachment,
 	Config,
+	MessageCreateSchema,
 } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import fetch from "node-fetch";
 import cheerio from "cheerio";
-import { MessageCreateSchema } from "../../routes/channels/#channel_id/messages";
 import { OrmUtils } from "@fosscord/util";
+
 const allow_empty = false;
 // TODO: check webhook, application, system author, stickers
 // TODO: embed gifs/videos/images
diff --git a/gateway/src/opcodes/Identify.ts b/gateway/src/opcodes/Identify.ts
index ce4385a3..e62c1570 100644
--- a/gateway/src/opcodes/Identify.ts
+++ b/gateway/src/opcodes/Identify.ts
@@ -19,12 +19,12 @@ import {
 	MemberPrivateProjection,
 	PresenceUpdateEvent,
 	UserSettings,
+	IdentifySchema,
 } from "@fosscord/util";
 import { Send } from "../util/Send";
 import { CLOSECODES, OPCODES } from "../util/Constants";
 import { genSessionId } from "../util/SessionUtils";
 import { setupListener } from "../listener/listener";
-import { IdentifySchema } from "../schema/Identify";
 // import experiments from "./experiments.json";
 const experiments: any = [];
 import { check } from "./instanceOf";
diff --git a/gateway/src/opcodes/LazyRequest.ts b/gateway/src/opcodes/LazyRequest.ts
index 5ba65cdd..cd0586de 100644
--- a/gateway/src/opcodes/LazyRequest.ts
+++ b/gateway/src/opcodes/LazyRequest.ts
@@ -1,5 +1,4 @@
-import { getPermission, listenEvent, Member, Role, getOrInitialiseDatabase } from "@fosscord/util";
-import { LazyRequest } from "../schema/LazyRequest";
+import { getPermission, listenEvent, Member, Role, getOrInitialiseDatabase, LazyRequest } from "@fosscord/util";
 import { Send } from "../util/Send";
 import { OPCODES } from "../util/Constants";
 import { WebSocket, Payload, handlePresenceUpdate } from "@fosscord/gateway";
diff --git a/gateway/src/opcodes/PresenceUpdate.ts b/gateway/src/opcodes/PresenceUpdate.ts
index 415df6ee..f31c9161 100644
--- a/gateway/src/opcodes/PresenceUpdate.ts
+++ b/gateway/src/opcodes/PresenceUpdate.ts
@@ -1,6 +1,5 @@
 import { WebSocket, Payload } from "@fosscord/gateway";
-import { emitEvent, PresenceUpdateEvent, Session, User } from "@fosscord/util";
-import { ActivitySchema } from "../schema/Activity";
+import { ActivitySchema, emitEvent, PresenceUpdateEvent, Session, User } from "@fosscord/util";
 import { check } from "./instanceOf";
 
 export async function onPresenceUpdate(this: WebSocket, { d }: Payload) {
diff --git a/gateway/src/opcodes/VoiceStateUpdate.ts b/gateway/src/opcodes/VoiceStateUpdate.ts
index 845a75c0..73f73565 100644
--- a/gateway/src/opcodes/VoiceStateUpdate.ts
+++ b/gateway/src/opcodes/VoiceStateUpdate.ts
@@ -1,4 +1,3 @@
-import { VoiceStateUpdateSchema } from "../schema/VoiceStateUpdateSchema";
 import { Payload, WebSocket } from "@fosscord/gateway";
 import { genVoiceToken } from "../util/SessionUtils";
 import { check } from "./instanceOf";
@@ -10,6 +9,7 @@ import {
 	VoiceServerUpdateEvent,
 	VoiceState,
 	VoiceStateUpdateEvent,
+	VoiceStateUpdateSchema,
 } from "@fosscord/util";
 import { OrmUtils } from "@fosscord/util";
 import { Region } from "@fosscord/util/src/config";
diff --git a/gateway/src/schema/VoiceStateUpdateSchema.ts b/gateway/src/schema/VoiceStateUpdateSchema.ts
deleted file mode 100644
index 9efa191e..00000000
--- a/gateway/src/schema/VoiceStateUpdateSchema.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export const VoiceStateUpdateSchema = {
-	$guild_id: String,
-	$channel_id: String,
-	self_mute: Boolean,
-	self_deaf: Boolean,
-	self_video: Boolean,
-};
-
-export interface VoiceStateUpdateSchema {
-	guild_id?: string;
-	channel_id?: string;
-	self_mute: boolean;
-	self_deaf: boolean;
-	self_video: boolean;
-}
diff --git a/util/src/index.ts b/util/src/index.ts
index 259d1c97..daeffd69 100644
--- a/util/src/index.ts
+++ b/util/src/index.ts
@@ -4,4 +4,5 @@ export * from "./util/index";
 export * from "./interfaces/index";
 export * from "./entities/index";
 export * from "./dtos/index";
-export * from "./util/MFA";
\ No newline at end of file
+export * from "./util/MFA";
+export * from "./schemas";
\ No newline at end of file
diff --git a/gateway/src/schema/Activity.ts b/util/src/schemas/ActivitySchema.ts
index e18f66c8..e18f66c8 100644
--- a/gateway/src/schema/Activity.ts
+++ b/util/src/schemas/ActivitySchema.ts
diff --git a/util/src/schemas/BanCreateSchema.ts b/util/src/schemas/BanCreateSchema.ts
new file mode 100644
index 00000000..64b02943
--- /dev/null
+++ b/util/src/schemas/BanCreateSchema.ts
@@ -0,0 +1,5 @@
+
+export interface BanCreateSchema {
+	delete_message_days?: string;
+	reason?: string;
+}
diff --git a/util/src/schemas/BanModeratorSchema.ts b/util/src/schemas/BanModeratorSchema.ts
new file mode 100644
index 00000000..b497d319
--- /dev/null
+++ b/util/src/schemas/BanModeratorSchema.ts
@@ -0,0 +1,8 @@
+
+export interface BanModeratorSchema {
+	id: string;
+	user_id: string;
+	guild_id: string;
+	executor_id: string;
+	reason?: string | undefined;
+}
diff --git a/util/src/schemas/BanRegistrySchema.ts b/util/src/schemas/BanRegistrySchema.ts
new file mode 100644
index 00000000..661f934f
--- /dev/null
+++ b/util/src/schemas/BanRegistrySchema.ts
@@ -0,0 +1,9 @@
+
+export interface BanRegistrySchema {
+	id: string;
+	user_id: string;
+	guild_id: string;
+	executor_id: string;
+	ip?: string;
+	reason?: string | undefined;
+}
diff --git a/util/src/schemas/BulkDeleteSchema.ts b/util/src/schemas/BulkDeleteSchema.ts
new file mode 100644
index 00000000..26f88374
--- /dev/null
+++ b/util/src/schemas/BulkDeleteSchema.ts
@@ -0,0 +1,4 @@
+
+export interface BulkDeleteSchema {
+	messages: string[];
+}
diff --git a/util/src/schemas/ChannelModifySchema.ts b/util/src/schemas/ChannelModifySchema.ts
new file mode 100644
index 00000000..3cfcf7d2
--- /dev/null
+++ b/util/src/schemas/ChannelModifySchema.ts
@@ -0,0 +1,29 @@
+import { ChannelPermissionOverwriteType, ChannelType } from "..";
+
+
+export interface ChannelModifySchema {
+	/**
+	 * @maxLength 100
+	 */
+	name?: string;
+	type?: ChannelType;
+	topic?: string;
+	icon?: string | null;
+	bitrate?: number;
+	user_limit?: number;
+	rate_limit_per_user?: number;
+	position?: number;
+	permission_overwrites?: {
+		id: string;
+		type: ChannelPermissionOverwriteType;
+		allow: string;
+		deny: string;
+	}[];
+	parent_id?: string;
+	id?: string; // is not used (only for guild create)
+	nsfw?: boolean;
+	rtc_region?: string;
+	default_auto_archive_duration?: number;
+	flags?: number;
+	default_thread_rate_limit_per_user?: number;
+}
\ No newline at end of file
diff --git a/util/src/schemas/ChannelPermissionOverwriteSchema.ts b/util/src/schemas/ChannelPermissionOverwriteSchema.ts
new file mode 100644
index 00000000..fe9ba860
--- /dev/null
+++ b/util/src/schemas/ChannelPermissionOverwriteSchema.ts
@@ -0,0 +1,5 @@
+import { ChannelPermissionOverwrite } from "@fosscord/util";
+
+// TODO: Only permissions your bot has in the guild or channel can be allowed/denied (unless your bot has a MANAGE_ROLES overwrite in the channel)
+
+export interface ChannelPermissionOverwriteSchema extends ChannelPermissionOverwrite { }
diff --git a/util/src/schemas/DmChannelCreateSchema.ts b/util/src/schemas/DmChannelCreateSchema.ts
new file mode 100644
index 00000000..d5afc6d7
--- /dev/null
+++ b/util/src/schemas/DmChannelCreateSchema.ts
@@ -0,0 +1,5 @@
+
+export interface DmChannelCreateSchema {
+	name?: string;
+	recipients: string[];
+}
diff --git a/util/src/schemas/EmojiCreateSchema.ts b/util/src/schemas/EmojiCreateSchema.ts
new file mode 100644
index 00000000..d50c419c
--- /dev/null
+++ b/util/src/schemas/EmojiCreateSchema.ts
@@ -0,0 +1,7 @@
+
+export interface EmojiCreateSchema {
+	name?: string;
+	image: string;
+	require_colons?: boolean | null;
+	roles?: string[];
+}
diff --git a/util/src/schemas/EmojiModifySchema.ts b/util/src/schemas/EmojiModifySchema.ts
new file mode 100644
index 00000000..5529dbd5
--- /dev/null
+++ b/util/src/schemas/EmojiModifySchema.ts
@@ -0,0 +1,5 @@
+
+export interface EmojiModifySchema {
+	name?: string;
+	roles?: string[];
+}
diff --git a/util/src/schemas/GuildCreateSchema.ts b/util/src/schemas/GuildCreateSchema.ts
new file mode 100644
index 00000000..e4855119
--- /dev/null
+++ b/util/src/schemas/GuildCreateSchema.ts
@@ -0,0 +1,14 @@
+import { ChannelModifySchema } from ".";
+
+export interface GuildCreateSchema {
+	/**
+	 * @maxLength 100
+	 */
+	name: string;
+	region?: string;
+	icon?: string | null;
+	channels?: ChannelModifySchema[];
+	guild_template_code?: string;
+	system_channel_id?: string;
+	rules_channel_id?: string;
+}
diff --git a/util/src/schemas/GuildTemplateCreateSchema.ts b/util/src/schemas/GuildTemplateCreateSchema.ts
new file mode 100644
index 00000000..1579001e
--- /dev/null
+++ b/util/src/schemas/GuildTemplateCreateSchema.ts
@@ -0,0 +1,5 @@
+
+export interface GuildTemplateCreateSchema {
+	name: string;
+	avatar?: string | null;
+}
diff --git a/util/src/schemas/GuildUpdateSchema.ts b/util/src/schemas/GuildUpdateSchema.ts
new file mode 100644
index 00000000..86527cf1
--- /dev/null
+++ b/util/src/schemas/GuildUpdateSchema.ts
@@ -0,0 +1,18 @@
+import { GuildCreateSchema } from ".";
+
+export interface GuildUpdateSchema extends Omit<GuildCreateSchema, "channels" | "name"> {
+	name?: string;
+	banner?: string | null;
+	splash?: string | null;
+	description?: string;
+	features?: string[];
+	verification_level?: number;
+	default_message_notifications?: number;
+	system_channel_flags?: number;
+	explicit_content_filter?: number;
+	public_updates_channel_id?: string;
+	afk_timeout?: number;
+	afk_channel_id?: string;
+	preferred_locale?: string;
+	premium_progress_bar_enabled?: boolean;
+}
diff --git a/util/src/schemas/GuildUpdateWelcomeScreenSchema.ts b/util/src/schemas/GuildUpdateWelcomeScreenSchema.ts
new file mode 100644
index 00000000..b1e36920
--- /dev/null
+++ b/util/src/schemas/GuildUpdateWelcomeScreenSchema.ts
@@ -0,0 +1,11 @@
+
+export interface GuildUpdateWelcomeScreenSchema {
+	welcome_channels?: {
+		channel_id: string;
+		description: string;
+		emoji_id?: string;
+		emoji_name: string;
+	}[];
+	enabled?: boolean;
+	description?: string;
+}
diff --git a/gateway/src/schema/Identify.ts b/util/src/schemas/IdentifySchema.ts
index 21141321..8f95c6a0 100644
--- a/gateway/src/schema/Identify.ts
+++ b/util/src/schemas/IdentifySchema.ts
@@ -1,4 +1,4 @@
-import { ActivitySchema } from "./Activity";
+import { ActivitySchema } from "./ActivitySchema";
 
 export const IdentifySchema = {
 	token: String,
diff --git a/util/src/schemas/InviteCreateSchema.ts b/util/src/schemas/InviteCreateSchema.ts
new file mode 100644
index 00000000..7f6af338
--- /dev/null
+++ b/util/src/schemas/InviteCreateSchema.ts
@@ -0,0 +1,12 @@
+
+export interface InviteCreateSchema {
+	target_user_id?: string;
+	target_type?: string;
+	validate?: string; // ? what is this
+	max_age?: number;
+	max_uses?: number;
+	temporary?: boolean;
+	unique?: boolean;
+	target_user?: string;
+	target_user_type?: number;
+}
diff --git a/gateway/src/schema/LazyRequest.ts b/util/src/schemas/LazyRequestSchema.ts
index 1fe658bb..1fe658bb 100644
--- a/gateway/src/schema/LazyRequest.ts
+++ b/util/src/schemas/LazyRequestSchema.ts
diff --git a/util/src/schemas/LoginSchema.ts b/util/src/schemas/LoginSchema.ts
new file mode 100644
index 00000000..358019a8
--- /dev/null
+++ b/util/src/schemas/LoginSchema.ts
@@ -0,0 +1,9 @@
+
+export interface LoginSchema {
+	login: string;
+	password: string;
+	undelete?: boolean;
+	captcha_key?: string;
+	login_source?: string;
+	gift_code_sku_id?: string;
+}
diff --git a/util/src/schemas/MemberChangeSchema.ts b/util/src/schemas/MemberChangeSchema.ts
new file mode 100644
index 00000000..a75c0ea0
--- /dev/null
+++ b/util/src/schemas/MemberChangeSchema.ts
@@ -0,0 +1,4 @@
+
+export interface MemberChangeSchema {
+	roles?: string[];
+}
diff --git a/util/src/schemas/MemberNickChangeSchema.ts b/util/src/schemas/MemberNickChangeSchema.ts
new file mode 100644
index 00000000..e6a6a007
--- /dev/null
+++ b/util/src/schemas/MemberNickChangeSchema.ts
@@ -0,0 +1,4 @@
+
+export interface MemberNickChangeSchema {
+	nick: string;
+}
diff --git a/util/src/schemas/MessageAcknowledgeSchema.ts b/util/src/schemas/MessageAcknowledgeSchema.ts
new file mode 100644
index 00000000..3f4eb2b6
--- /dev/null
+++ b/util/src/schemas/MessageAcknowledgeSchema.ts
@@ -0,0 +1,8 @@
+// TODO: public read receipts & privacy scoping
+// TODO: send read state event to all channel members
+// TODO: advance-only notification cursor
+
+export interface MessageAcknowledgeSchema {
+	manual?: boolean;
+	mention_count?: number;
+}
diff --git a/util/src/schemas/MessageCreateSchema.ts b/util/src/schemas/MessageCreateSchema.ts
new file mode 100644
index 00000000..7b1cc7b9
--- /dev/null
+++ b/util/src/schemas/MessageCreateSchema.ts
@@ -0,0 +1,34 @@
+import { Embed } from "@fosscord/util";
+
+
+export interface MessageCreateSchema {
+	type?: number;
+	content?: string;
+	nonce?: string;
+	channel_id?: string;
+	tts?: boolean;
+	flags?: string;
+	embeds?: Embed[];
+	embed?: Embed;
+	// TODO: ^ embed is deprecated in favor of embeds (https://discord.com/developers/docs/resources/channel#message-object)
+	allowed_mentions?: {
+		parse?: string[];
+		roles?: string[];
+		users?: string[];
+		replied_user?: boolean;
+	};
+	message_reference?: {
+		message_id: string;
+		channel_id: string;
+		guild_id?: string;
+		fail_if_not_exists?: boolean;
+	};
+	payload_json?: string;
+	file?: any;
+	/**
+	TODO: we should create an interface for attachments
+	TODO: OpenWAAO<-->attachment-style metadata conversion
+	**/
+	attachments?: any[];
+	sticker_ids?: string[];
+}
diff --git a/util/src/schemas/MfaCodesSchema.ts b/util/src/schemas/MfaCodesSchema.ts
new file mode 100644
index 00000000..53230841
--- /dev/null
+++ b/util/src/schemas/MfaCodesSchema.ts
@@ -0,0 +1,5 @@
+
+export interface MfaCodesSchema {
+	password: string;
+	regenerate?: boolean;
+}
diff --git a/util/src/schemas/ModifyGuildStickerSchema.ts b/util/src/schemas/ModifyGuildStickerSchema.ts
new file mode 100644
index 00000000..6f24e4ce
--- /dev/null
+++ b/util/src/schemas/ModifyGuildStickerSchema.ts
@@ -0,0 +1,16 @@
+
+export interface ModifyGuildStickerSchema {
+	/**
+	 * @minLength 2
+	 * @maxLength 30
+	 */
+	name: string;
+	/**
+	 * @maxLength 100
+	 */
+	description?: string;
+	/**
+	 * @maxLength 200
+	 */
+	tags: string;
+}
diff --git a/util/src/schemas/PruneSchema.ts b/util/src/schemas/PruneSchema.ts
new file mode 100644
index 00000000..eebac763
--- /dev/null
+++ b/util/src/schemas/PruneSchema.ts
@@ -0,0 +1,7 @@
+
+export interface PruneSchema {
+	/**
+	 * @min 0
+	 */
+	days: number;
+}
diff --git a/util/src/schemas/PurgeSchema.ts b/util/src/schemas/PurgeSchema.ts
new file mode 100644
index 00000000..0eeef6f2
--- /dev/null
+++ b/util/src/schemas/PurgeSchema.ts
@@ -0,0 +1,5 @@
+
+export interface PurgeSchema {
+	before: string;
+	after: string;
+}
diff --git a/util/src/schemas/RegisterSchema.ts b/util/src/schemas/RegisterSchema.ts
new file mode 100644
index 00000000..e53330d2
--- /dev/null
+++ b/util/src/schemas/RegisterSchema.ts
@@ -0,0 +1,27 @@
+
+export interface RegisterSchema {
+	/**
+	 * @minLength 2
+	 * @maxLength 32
+	 */
+	username: string;
+	/**
+	 * @minLength 1
+	 * @maxLength 72
+	 */
+	password?: string;
+	consent: boolean;
+	/**
+	 * @TJS-format email
+	 */
+	email?: string;
+	fingerprint?: string;
+	invite?: string;
+	/**
+	 * @TJS-type string
+	 */
+	date_of_birth?: Date; // "2000-04-03"
+	gift_code_sku_id?: string;
+	captcha_key?: string;
+	promotional_email_opt_in?: boolean;
+}
diff --git a/util/src/schemas/RelationshipPostSchema.ts b/util/src/schemas/RelationshipPostSchema.ts
new file mode 100644
index 00000000..40093700
--- /dev/null
+++ b/util/src/schemas/RelationshipPostSchema.ts
@@ -0,0 +1,5 @@
+
+export interface RelationshipPostSchema {
+	discriminator: string;
+	username: string;
+}
diff --git a/util/src/schemas/RelationshipPutSchema.ts b/util/src/schemas/RelationshipPutSchema.ts
new file mode 100644
index 00000000..f46966e0
--- /dev/null
+++ b/util/src/schemas/RelationshipPutSchema.ts
@@ -0,0 +1,6 @@
+import { RelationshipType } from "@fosscord/util";
+
+
+export interface RelationshipPutSchema {
+	type?: RelationshipType;
+}
diff --git a/util/src/schemas/RoleModifySchema.ts b/util/src/schemas/RoleModifySchema.ts
new file mode 100644
index 00000000..d08a5022
--- /dev/null
+++ b/util/src/schemas/RoleModifySchema.ts
@@ -0,0 +1,11 @@
+
+export interface RoleModifySchema {
+	name?: string;
+	permissions?: string;
+	color?: number;
+	hoist?: boolean; // whether the role should be displayed separately in the sidebar
+	mentionable?: boolean; // whether the role should be mentionable
+	position?: number;
+	icon?: string;
+	unicode_emoji?: string;
+}
diff --git a/util/src/schemas/TemplateCreateSchema.ts b/util/src/schemas/TemplateCreateSchema.ts
new file mode 100644
index 00000000..72c19f68
--- /dev/null
+++ b/util/src/schemas/TemplateCreateSchema.ts
@@ -0,0 +1,5 @@
+
+export interface TemplateCreateSchema {
+	name: string;
+	description?: string;
+}
diff --git a/util/src/schemas/TemplateModifySchema.ts b/util/src/schemas/TemplateModifySchema.ts
new file mode 100644
index 00000000..2231a1d2
--- /dev/null
+++ b/util/src/schemas/TemplateModifySchema.ts
@@ -0,0 +1,5 @@
+
+export interface TemplateModifySchema {
+	name: string;
+	description?: string;
+}
diff --git a/util/src/schemas/TotpDisableSchema.ts b/util/src/schemas/TotpDisableSchema.ts
new file mode 100644
index 00000000..b73db64e
--- /dev/null
+++ b/util/src/schemas/TotpDisableSchema.ts
@@ -0,0 +1,4 @@
+
+export interface TotpDisableSchema {
+	code: string;
+}
diff --git a/util/src/schemas/TotpEnableSchema.ts b/util/src/schemas/TotpEnableSchema.ts
new file mode 100644
index 00000000..44d9ebac
--- /dev/null
+++ b/util/src/schemas/TotpEnableSchema.ts
@@ -0,0 +1,6 @@
+
+export interface TotpEnableSchema {
+	password: string;
+	code?: string;
+	secret?: string;
+}
diff --git a/util/src/schemas/TotpSchema.ts b/util/src/schemas/TotpSchema.ts
new file mode 100644
index 00000000..fe54735e
--- /dev/null
+++ b/util/src/schemas/TotpSchema.ts
@@ -0,0 +1,7 @@
+
+export interface TotpSchema {
+	code: string;
+	ticket: string;
+	gift_code_sku_id?: string | null;
+	login_source?: string | null;
+}
diff --git a/util/src/schemas/UserModifySchema.ts b/util/src/schemas/UserModifySchema.ts
new file mode 100644
index 00000000..659f5841
--- /dev/null
+++ b/util/src/schemas/UserModifySchema.ts
@@ -0,0 +1,19 @@
+
+export interface UserModifySchema {
+	/**
+	 * @minLength 1
+	 * @maxLength 100
+	 */
+	username?: string;
+	discriminator?: string;
+	avatar?: string | null;
+	/**
+	 * @maxLength 1024
+	 */
+	bio?: string;
+	accent_color?: number;
+	banner?: string | null;
+	password?: string;
+	new_password?: string;
+	code?: string;
+}
diff --git a/util/src/schemas/UserSettingsSchema.ts b/util/src/schemas/UserSettingsSchema.ts
new file mode 100644
index 00000000..b497dff2
--- /dev/null
+++ b/util/src/schemas/UserSettingsSchema.ts
@@ -0,0 +1,4 @@
+import { UserSettings } from "@fosscord/util";
+
+
+export interface UserSettingsSchema extends Partial<UserSettings> { }
diff --git a/util/src/schemas/VanityUrlSchema.ts b/util/src/schemas/VanityUrlSchema.ts
new file mode 100644
index 00000000..de32695a
--- /dev/null
+++ b/util/src/schemas/VanityUrlSchema.ts
@@ -0,0 +1,8 @@
+
+export interface VanityUrlSchema {
+	/**
+	 * @minLength 1
+	 * @maxLength 20
+	 */
+	code?: string;
+}
diff --git a/util/src/schemas/VoiceStateUpdateSchema.ts b/util/src/schemas/VoiceStateUpdateSchema.ts
new file mode 100644
index 00000000..02bb141b
--- /dev/null
+++ b/util/src/schemas/VoiceStateUpdateSchema.ts
@@ -0,0 +1,18 @@
+export const VoiceStateUpdateSchema = {
+	$guild_id: String,
+	$channel_id: String,
+	self_mute: Boolean,
+	self_deaf: Boolean,
+	self_video: Boolean,
+};
+
+//TODO need more testing when community guild and voice stage channel are working
+export interface VoiceStateUpdateSchema {
+	channel_id: string;
+	guild_id?: string;
+	suppress?: boolean;
+	request_to_speak_timestamp?: Date;
+	self_mute?: boolean;
+	self_deaf?: boolean;
+	self_video?: boolean;
+}
\ No newline at end of file
diff --git a/util/src/schemas/WebhookCreateSchema.ts b/util/src/schemas/WebhookCreateSchema.ts
new file mode 100644
index 00000000..12ab1869
--- /dev/null
+++ b/util/src/schemas/WebhookCreateSchema.ts
@@ -0,0 +1,8 @@
+// TODO: webhooks
+export interface WebhookCreateSchema {
+	/**
+	 * @maxLength 80
+	 */
+	name: string;
+	avatar?: string;
+}
diff --git a/util/src/schemas/WidgetModifySchema.ts b/util/src/schemas/WidgetModifySchema.ts
new file mode 100644
index 00000000..390efc30
--- /dev/null
+++ b/util/src/schemas/WidgetModifySchema.ts
@@ -0,0 +1,5 @@
+
+export interface WidgetModifySchema {
+	enabled: boolean; // whether the widget is enabled
+	channel_id: string; // the widget channel id
+}
diff --git a/util/src/schemas/index.ts b/util/src/schemas/index.ts
new file mode 100644
index 00000000..f54ae840
--- /dev/null
+++ b/util/src/schemas/index.ts
@@ -0,0 +1,41 @@
+export * from "./ActivitySchema";
+export * from "./BanCreateSchema";
+export * from "./BanModeratorSchema";
+export * from "./BanRegistrySchema";
+export * from "./BulkDeleteSchema";
+export * from "./ChannelModifySchema";
+export * from "./ChannelPermissionOverwriteSchema";
+export * from "./DmChannelCreateSchema";
+export * from "./EmojiCreateSchema";
+export * from "./EmojiModifySchema";
+export * from "./GuildCreateSchema";
+export * from "./GuildTemplateCreateSchema";
+export * from "./GuildUpdateSchema";
+export * from "./GuildUpdateWelcomeScreenSchema";
+export * from "./IdentifySchema";
+export * from "./InviteCreateSchema";
+export * from "./LazyRequestSchema";
+export * from "./LoginSchema";
+export * from "./MemberChangeSchema";
+export * from "./MemberNickChangeSchema";
+export * from "./MessageAcknowledgeSchema";
+export * from "./MessageCreateSchema";
+export * from "./MfaCodesSchema";
+export * from "./ModifyGuildStickerSchema";
+export * from "./PruneSchema";
+export * from "./PurgeSchema";
+export * from "./RegisterSchema";
+export * from "./RelationshipPostSchema";
+export * from "./RelationshipPutSchema";
+export * from "./RoleModifySchema";
+export * from "./TemplateCreateSchema";
+export * from "./TemplateModifySchema";
+export * from "./TotpDisableSchema";
+export * from "./TotpEnableSchema";
+export * from "./TotpSchema";
+export * from "./UserModifySchema";
+export * from "./UserSettingsSchema";
+export * from "./VanityUrlSchema";
+export * from "./VoiceStateUpdateSchema";
+export * from "./WebhookCreateSchema";
+export * from "./WidgetModifySchema";
diff --git a/util/src/util/Config.ts b/util/src/util/Config.ts
index 0b55ca4b..e0fb2a81 100644
--- a/util/src/util/Config.ts
+++ b/util/src/util/Config.ts
@@ -60,8 +60,11 @@ function applyConfig(val: ConfigValue) {
 		pair.value = obj;
 		return pair.save();
 	}
-	if(process.env.CONFIG_PATH)
+	if(process.env.CONFIG_PATH) {
+		if(/--debug|--inspect/.test(process.execArgv.join(' ')))
+			console.log(`Writing config: ${process.env.CONFIG_PATH}`)
 		fs.writeFileSync(overridePath, JSON.stringify(val, null, 4));
+	}
 
 	return apply(val);
 }