summary refs log tree commit diff
path: root/api
diff options
context:
space:
mode:
authorFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-09-01 23:33:14 +0200
committerFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-09-01 23:33:14 +0200
commit0fbe9131adb8ef12f11362679c026ea285ea2e80 (patch)
tree0a98cbcb471aa4abe94d80c4aa7f57227e68f8e1 /api
parentMerge pull request #302 from sudenoh/master (diff)
downloadserver-0fbe9131adb8ef12f11362679c026ea285ea2e80.tar.xz
:sparkles: generate open api schema based on body and db entities
Diffstat (limited to 'api')
-rw-r--r--api/assets/openapi.json1625
-rw-r--r--api/assets/openapi.yaml136
-rw-r--r--api/assets/openapi.yml526
-rw-r--r--api/patches/typescript-json-schema+0.50.1.patch14
-rw-r--r--api/scripts/config_generator.js93
-rw-r--r--api/scripts/generate_openapi_schema.ts191
-rw-r--r--api/src/schema/Emoji.ts5
-rw-r--r--api/src/schema/Guild.ts2
-rw-r--r--api/src/schema/Invite.ts18
-rw-r--r--api/src/schema/index.ts11
10 files changed, 1853 insertions, 768 deletions
diff --git a/api/assets/openapi.json b/api/assets/openapi.json
new file mode 100644
index 00000000..60a40c8a
--- /dev/null
+++ b/api/assets/openapi.json
@@ -0,0 +1,1625 @@
+{
+	"openapi": "3.0.0",
+	"servers": [
+		{
+			"url": "https://api.fosscord.com/v{version}",
+			"description": "Official fosscord instance",
+			"variables": { "version": { "description": "", "default": "9", "enum": ["8", "9"] } }
+		}
+	],
+	"info": {
+		"description": "Fosscord is a free open source selfhostable chat, voice and video discord compatible platform",
+		"version": "1.0.0",
+		"title": "Swagger Petstore",
+		"termsOfService": "",
+		"contact": { "name": "Fosscord" },
+		"license": { "name": "AGPLV3", "url": "https://www.gnu.org/licenses/agpl-3.0.en.html" }
+	},
+	"tags": [],
+	"paths": {
+		"/users/{id}": {
+			"get": {
+				"summary": "",
+				"description": "",
+				"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "user id" }],
+				"operationId": "",
+				"responses": {
+					"200": {
+						"description": "user found",
+						"content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserPublic" } } }
+					},
+					"401": {
+						"description": "Unauthorized",
+						"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
+					},
+					"429": {
+						"description": "Rate limit exceeded",
+						"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } },
+						"headers": {
+							"X-RateLimit-Bucket": {
+								"description": "A unique string denoting the rate limit being encountered (non-inclusive of major parameters in the route path)",
+								"schema": { "type": "string" }
+							},
+							"X-Rate-Limit-Limit": {
+								"description": "The number of allowed requests in the current period",
+								"schema": { "type": "integer" }
+							},
+							"X-Rate-Limit-Remaining": {
+								"description": "The number of remaining requests in the current period",
+								"schema": { "type": "integer" }
+							},
+							"X-Rate-Limit-Reset": {
+								"description": "Date when current period is over in seconds since the Unix epoch",
+								"schema": { "type": "integer" }
+							},
+							"X-Rate-Limit-Reset-After": {
+								"description": "Number of seconds when current period will reset (can have decimal)",
+								"schema": { "type": "number" }
+							},
+							"Retry-After": {
+								"description": "Same as X-Rate-Limit-Reset-After but an integer",
+								"schema": { "type": "integer" }
+							},
+							"X-RateLimit-Global": {
+								"description": "Indicates whether or not all requests from your ip are rate limited",
+								"schema": { "type": "boolean" }
+							}
+						}
+					}
+				}
+			}
+		}
+	},
+	"externalDocs": { "description": "", "url": "http://docs.fosscord.com/" },
+	"components": {
+		"schemas": {
+			"Error": {
+				"type": "object",
+				"properties": { "code": { "type": "integer" }, "message": { "type": "string" } },
+				"required": ["code", "message"]
+			},
+			"RateLimit": {
+				"type": "object",
+				"properties": { "retry_after": { "type": "integer" }, "message": { "type": "string" }, "global": { "type": "boolean" } },
+				"required": ["code", "message", "globa"]
+			},
+			"User": {
+				"type": "object",
+				"properties": {
+					"username": { "type": "string" },
+					"discriminator": { "type": "string" },
+					"avatar": { "type": "string" },
+					"accent_color": { "type": "integer" },
+					"banner": { "type": "string" },
+					"phone": { "type": "string" },
+					"desktop": { "type": "boolean" },
+					"mobile": { "type": "boolean" },
+					"premium": { "type": "boolean" },
+					"premium_type": { "type": "integer" },
+					"bot": { "type": "boolean" },
+					"bio": { "type": "string" },
+					"system": { "type": "boolean" },
+					"nsfw_allowed": { "type": "boolean" },
+					"mfa_enabled": { "type": "boolean" },
+					"created_at": { "type": "string", "format": "date-time" },
+					"verified": { "type": "boolean" },
+					"disabled": { "type": "boolean" },
+					"deleted": { "type": "boolean" },
+					"email": { "type": "string" },
+					"flags": { "type": "string" },
+					"public_flags": { "type": "string" },
+					"relationships": { "type": "array", "items": { "$ref": "#/components/schemas/Relationship" } },
+					"connected_accounts": { "type": "array", "items": { "$ref": "#/components/schemas/ConnectedAccount" } },
+					"data": {
+						"type": "object",
+						"properties": { "valid_tokens_since": { "type": "string", "format": "date-time" }, "hash": { "type": "string" } },
+						"additionalProperties": false,
+						"required": ["valid_tokens_since"]
+					},
+					"fingerprints": { "type": "array", "items": { "type": "string" } },
+					"settings": { "$ref": "#/components/schemas/UserSettings" },
+					"id": { "type": "string" }
+				},
+				"required": [
+					"bio",
+					"bot",
+					"connected_accounts",
+					"created_at",
+					"data",
+					"deleted",
+					"desktop",
+					"disabled",
+					"discriminator",
+					"fingerprints",
+					"flags",
+					"id",
+					"mfa_enabled",
+					"mobile",
+					"nsfw_allowed",
+					"premium",
+					"premium_type",
+					"public_flags",
+					"relationships",
+					"settings",
+					"system",
+					"username",
+					"verified"
+				]
+			},
+			"Relationship": {
+				"type": "object",
+				"properties": {
+					"user_id": { "type": "string" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"nickname": { "type": "string" },
+					"type": { "$ref": "#/components/schemas/RelationshipType" },
+					"id": { "type": "string" }
+				},
+				"required": ["id", "type", "user", "user_id"]
+			},
+			"RelationshipType": { "enum": [1, 2, 3, 4], "type": "number" },
+			"ConnectedAccount": {
+				"type": "object",
+				"properties": {
+					"user_id": { "type": "string" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"access_token": { "type": "string" },
+					"friend_sync": { "type": "boolean" },
+					"name": { "type": "string" },
+					"revoked": { "type": "boolean" },
+					"show_activity": { "type": "boolean" },
+					"type": { "type": "string" },
+					"verifie": { "type": "boolean" },
+					"visibility": { "type": "integer" },
+					"id": { "type": "string" }
+				},
+				"required": [
+					"access_token",
+					"friend_sync",
+					"id",
+					"name",
+					"revoked",
+					"show_activity",
+					"type",
+					"user",
+					"user_id",
+					"verifie",
+					"visibility"
+				]
+			},
+			"UserSettings": {
+				"type": "object",
+				"properties": {
+					"afk_timeout": { "type": "integer" },
+					"allow_accessibility_detection": { "type": "boolean" },
+					"animate_emoji": { "type": "boolean" },
+					"animate_stickers": { "type": "integer" },
+					"contact_sync_enabled": { "type": "boolean" },
+					"convert_emoticons": { "type": "boolean" },
+					"custom_status": {
+						"type": "object",
+						"properties": {
+							"emoji_id": { "type": "string" },
+							"emoji_name": { "type": "string" },
+							"expires_at": { "type": "integer" },
+							"text": { "type": "string" }
+						},
+						"additionalProperties": false
+					},
+					"default_guilds_restricted": { "type": "boolean" },
+					"detect_platform_accounts": { "type": "boolean" },
+					"developer_mode": { "type": "boolean" },
+					"disable_games_tab": { "type": "boolean" },
+					"enable_tts_command": { "type": "boolean" },
+					"explicit_content_filter": { "type": "integer" },
+					"friend_source_flags": {
+						"type": "object",
+						"properties": { "all": { "type": "boolean" } },
+						"additionalProperties": false,
+						"required": ["all"]
+					},
+					"gateway_connected": { "type": "boolean" },
+					"gif_auto_play": { "type": "boolean" },
+					"guild_folders": {
+						"type": "array",
+						"items": {
+							"type": "object",
+							"properties": {
+								"color": { "type": "integer" },
+								"guild_ids": { "type": "array", "items": { "type": "string" } },
+								"id": { "type": "integer" },
+								"name": { "type": "string" }
+							},
+							"additionalProperties": false,
+							"required": ["color", "guild_ids", "id", "name"]
+						}
+					},
+					"guild_positions": { "type": "array", "items": { "type": "string" } },
+					"inline_attachment_media": { "type": "boolean" },
+					"inline_embed_media": { "type": "boolean" },
+					"locale": { "type": "string" },
+					"message_display_compact": { "type": "boolean" },
+					"native_phone_integration_enabled": { "type": "boolean" },
+					"render_embeds": { "type": "boolean" },
+					"render_reactions": { "type": "boolean" },
+					"restricted_guilds": { "type": "array", "items": { "type": "string" } },
+					"show_current_game": { "type": "boolean" },
+					"status": { "enum": ["dnd", "idle", "offline", "online"], "type": "string" },
+					"stream_notifications_enabled": { "type": "boolean" },
+					"theme": { "enum": ["dark", "white"], "type": "string" },
+					"timezone_offset": { "type": "integer" }
+				},
+				"required": [
+					"afk_timeout",
+					"allow_accessibility_detection",
+					"animate_emoji",
+					"animate_stickers",
+					"contact_sync_enabled",
+					"convert_emoticons",
+					"custom_status",
+					"default_guilds_restricted",
+					"detect_platform_accounts",
+					"developer_mode",
+					"disable_games_tab",
+					"enable_tts_command",
+					"explicit_content_filter",
+					"friend_source_flags",
+					"gateway_connected",
+					"gif_auto_play",
+					"guild_folders",
+					"guild_positions",
+					"inline_attachment_media",
+					"inline_embed_media",
+					"locale",
+					"message_display_compact",
+					"native_phone_integration_enabled",
+					"render_embeds",
+					"render_reactions",
+					"restricted_guilds",
+					"show_current_game",
+					"status",
+					"stream_notifications_enabled",
+					"theme",
+					"timezone_offset"
+				]
+			},
+			"Team": {
+				"type": "object",
+				"properties": {
+					"icon": { "type": "string" },
+					"members": { "type": "array", "items": { "$ref": "#/components/schemas/TeamMember" } },
+					"name": { "type": "string" },
+					"owner_user_id": { "type": "string" },
+					"owner_user": { "$ref": "#/components/schemas/User" },
+					"id": { "type": "string" }
+				},
+				"required": ["id", "members", "name", "owner_user", "owner_user_id"]
+			},
+			"TeamMember": {
+				"type": "object",
+				"properties": {
+					"membership_state": { "$ref": "#/components/schemas/TeamMemberState" },
+					"permissions": { "type": "array", "items": { "type": "string" } },
+					"team_id": { "type": "string" },
+					"team": { "$ref": "#/components/schemas/Team" },
+					"user_id": { "type": "string" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"id": { "type": "string" }
+				},
+				"required": ["id", "membership_state", "permissions", "team", "team_id", "user", "user_id"]
+			},
+			"TeamMemberState": { "enum": [1, 2], "type": "number" },
+			"Guild": {
+				"type": "object",
+				"properties": {
+					"afk_channel_id": { "type": "string" },
+					"afk_channel": { "$ref": "#/components/schemas/Channel" },
+					"afk_timeout": { "type": "integer" },
+					"bans": { "type": "array", "items": { "$ref": "#/components/schemas/Ban" } },
+					"banner": { "type": "string" },
+					"default_message_notifications": { "type": "integer" },
+					"description": { "type": "string" },
+					"discovery_splash": { "type": "string" },
+					"explicit_content_filter": { "type": "integer" },
+					"features": { "type": "array", "items": { "type": "string" } },
+					"icon": { "type": "string" },
+					"large": { "type": "boolean" },
+					"max_members": { "type": "integer" },
+					"max_presences": { "type": "integer" },
+					"max_video_channel_users": { "type": "integer" },
+					"member_count": { "type": "integer" },
+					"presence_count": { "type": "integer" },
+					"members": { "type": "array", "items": { "$ref": "#/components/schemas/Member" } },
+					"roles": { "type": "array", "items": { "$ref": "#/components/schemas/Role" } },
+					"channels": { "type": "array", "items": { "$ref": "#/components/schemas/Channel" } },
+					"template_id": { "type": "string" },
+					"template": { "$ref": "#/components/schemas/Template" },
+					"emojis": { "type": "array", "items": { "$ref": "#/components/schemas/Emoji" } },
+					"stickers": { "type": "array", "items": { "$ref": "#/components/schemas/Sticker" } },
+					"invites": { "type": "array", "items": { "$ref": "#/components/schemas/Invite" } },
+					"voice_states": { "type": "array", "items": { "$ref": "#/components/schemas/VoiceState" } },
+					"webhooks": { "type": "array", "items": { "$ref": "#/components/schemas/Webhook" } },
+					"mfa_level": { "type": "integer" },
+					"name": { "type": "string" },
+					"owner_id": { "type": "string" },
+					"owner": { "$ref": "#/components/schemas/User" },
+					"preferred_locale": { "type": "string" },
+					"premium_subscription_count": { "type": "integer" },
+					"premium_tier": { "type": "integer" },
+					"public_updates_channel_id": { "type": "string" },
+					"public_updates_channel": { "$ref": "#/components/schemas/Channel" },
+					"rules_channel_id": { "type": "string" },
+					"rules_channel": { "type": "string" },
+					"region": { "type": "string" },
+					"splash": { "type": "string" },
+					"system_channel_id": { "type": "string" },
+					"system_channel": { "$ref": "#/components/schemas/Channel" },
+					"system_channel_flags": { "type": "integer" },
+					"unavailable": { "type": "boolean" },
+					"vanity_url_code": { "type": "string" },
+					"vanity_url": { "$ref": "#/components/schemas/Invite" },
+					"verification_level": { "type": "integer" },
+					"welcome_screen": {
+						"type": "object",
+						"properties": {
+							"enabled": { "type": "boolean" },
+							"description": { "type": "string" },
+							"welcome_channels": {
+								"type": "array",
+								"items": {
+									"type": "object",
+									"properties": {
+										"description": { "type": "string" },
+										"emoji_id": { "type": "string" },
+										"emoji_name": { "type": "string" },
+										"channel_id": { "type": "string" }
+									},
+									"additionalProperties": false,
+									"required": ["channel_id", "description", "emoji_name"]
+								}
+							}
+						},
+						"additionalProperties": false,
+						"required": ["description", "enabled", "welcome_channels"]
+					},
+					"widget_channel_id": { "type": "string" },
+					"widget_channel": { "$ref": "#/components/schemas/Channel" },
+					"widget_enabled": { "type": "boolean" },
+					"id": { "type": "string" }
+				},
+				"required": [
+					"bans",
+					"channels",
+					"emojis",
+					"features",
+					"id",
+					"invites",
+					"members",
+					"name",
+					"owner",
+					"owner_id",
+					"public_updates_channel_id",
+					"roles",
+					"stickers",
+					"template",
+					"template_id",
+					"voice_states",
+					"webhooks",
+					"welcome_screen"
+				]
+			},
+			"Channel": {
+				"type": "object",
+				"properties": {
+					"created_at": { "type": "string", "format": "date-time" },
+					"name": { "type": "string" },
+					"type": { "$ref": "#/components/schemas/ChannelType" },
+					"recipients": { "type": "array", "items": { "$ref": "#/components/schemas/Recipient" } },
+					"last_message_id": { "type": "string" },
+					"last_message": { "$ref": "#/components/schemas/Message" },
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"parent_id": { "type": "string" },
+					"parent": { "$ref": "#/components/schemas/Channel" },
+					"owner_id": { "type": "string" },
+					"owner": { "$ref": "#/components/schemas/User" },
+					"last_pin_timestamp": { "type": "integer" },
+					"default_auto_archive_duration": { "type": "integer" },
+					"position": { "type": "integer" },
+					"permission_overwrites": { "type": "array", "items": { "$ref": "#/components/schemas/ChannelPermissionOverwrite" } },
+					"video_quality_mode": { "type": "integer" },
+					"bitrate": { "type": "integer" },
+					"user_limit": { "type": "integer" },
+					"nsfw": { "type": "boolean" },
+					"rate_limit_per_user": { "type": "integer" },
+					"topic": { "type": "string" },
+					"id": { "type": "string" }
+				},
+				"required": [
+					"created_at",
+					"guild",
+					"id",
+					"last_message_id",
+					"name",
+					"owner",
+					"owner_id",
+					"parent_id",
+					"permission_overwrites",
+					"position",
+					"type"
+				]
+			},
+			"ChannelType": { "enum": [0, 1, 2, 3, 4, 5, 6], "type": "number" },
+			"Recipient": {
+				"type": "object",
+				"properties": {
+					"channel_id": { "type": "string" },
+					"channel": { "$ref": "#/components/schemas/Channel" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"id": { "type": "string" }
+				},
+				"required": ["channel", "channel_id", "id", "user"]
+			},
+			"Message": {
+				"type": "object",
+				"properties": {
+					"id": { "type": "string" },
+					"channel_id": { "type": "string" },
+					"channel": { "$ref": "#/components/schemas/Channel" },
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"author_id": { "type": "string" },
+					"author": { "$ref": "#/components/schemas/User" },
+					"member_id": { "type": "string" },
+					"member": { "$ref": "#/components/schemas/Member" },
+					"webhook_id": { "type": "string" },
+					"webhook": { "$ref": "#/components/schemas/Webhook" },
+					"application_id": { "type": "string" },
+					"application": { "$ref": "#/components/schemas/Application" },
+					"content": { "type": "string" },
+					"timestamp": { "type": "string", "format": "date-time" },
+					"edited_timestamp": { "type": "string", "format": "date-time" },
+					"tts": { "type": "boolean" },
+					"mention_everyone": { "type": "boolean" },
+					"mentions": { "type": "array", "items": { "$ref": "#/components/schemas/User" } },
+					"mention_roles": { "type": "array", "items": { "$ref": "#/components/schemas/Role" } },
+					"mention_channels": { "type": "array", "items": { "$ref": "#/components/schemas/Channel" } },
+					"sticker_items": { "type": "array", "items": { "$ref": "#/components/schemas/Sticker" } },
+					"attachments": { "type": "array", "items": { "$ref": "#/components/schemas/Attachment" } },
+					"embeds": { "type": "array", "items": { "$ref": "#/components/schemas/Embed" } },
+					"reactions": { "type": "array", "items": { "$ref": "#/components/schemas/Reaction" } },
+					"nonce": { "type": "string" },
+					"pinned": { "type": "boolean" },
+					"type": { "$ref": "#/components/schemas/MessageType" },
+					"activity": {
+						"type": "object",
+						"properties": { "type": { "type": "integer" }, "party_id": { "type": "string" } },
+						"additionalProperties": false,
+						"required": ["party_id", "type"]
+					},
+					"flags": { "type": "string" },
+					"message_reference": {
+						"type": "object",
+						"properties": {
+							"message_id": { "type": "string" },
+							"channel_id": { "type": "string" },
+							"guild_id": { "type": "string" }
+						},
+						"additionalProperties": false,
+						"required": ["message_id"]
+					},
+					"referenced_message": { "$ref": "#/components/schemas/Message" },
+					"interaction": {
+						"type": "object",
+						"properties": {
+							"id": { "type": "string" },
+							"type": { "$ref": "#/components/schemas/InteractionType" },
+							"name": { "type": "string" },
+							"user_id": { "type": "string" }
+						},
+						"additionalProperties": false,
+						"required": ["id", "name", "type", "user_id"]
+					},
+					"components": { "type": "array", "items": { "$ref": "#/components/schemas/MessageComponent" } }
+				},
+				"required": [
+					"application_id",
+					"author_id",
+					"channel",
+					"channel_id",
+					"embeds",
+					"id",
+					"member_id",
+					"mention_channels",
+					"mention_roles",
+					"mentions",
+					"reactions",
+					"timestamp",
+					"type",
+					"webhook_id"
+				]
+			},
+			"Member": {
+				"type": "object",
+				"properties": {
+					"user": { "$ref": "#/components/schemas/User" },
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"nick": { "type": "string" },
+					"roles": { "type": "array", "items": { "$ref": "#/components/schemas/Role" } },
+					"joined_at": { "type": "string", "format": "date-time" },
+					"premium_since": { "type": "integer" },
+					"deaf": { "type": "boolean" },
+					"mute": { "type": "boolean" },
+					"pending": { "type": "boolean" },
+					"settings": { "$ref": "#/components/schemas/UserGuildSettings" },
+					"id": { "type": "string" }
+				},
+				"required": ["deaf", "guild", "guild_id", "id", "joined_at", "mute", "pending", "roles", "settings", "user"]
+			},
+			"Role": {
+				"type": "object",
+				"properties": {
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"color": { "type": "integer" },
+					"hoist": { "type": "boolean" },
+					"managed": { "type": "boolean" },
+					"mentionable": { "type": "boolean" },
+					"name": { "type": "string" },
+					"permissions": { "type": "string" },
+					"position": { "type": "integer" },
+					"tags": {
+						"type": "object",
+						"properties": {
+							"bot_id": { "type": "string" },
+							"integration_id": { "type": "string" },
+							"premium_subscriber": { "type": "boolean" }
+						},
+						"additionalProperties": false
+					},
+					"id": { "type": "string" }
+				},
+				"required": ["color", "guild", "guild_id", "hoist", "id", "managed", "mentionable", "name", "permissions", "position"]
+			},
+			"UserGuildSettings": {
+				"type": "object",
+				"properties": {
+					"channel_overrides": {
+						"type": "array",
+						"items": {
+							"type": "object",
+							"properties": {
+								"channel_id": { "type": "string" },
+								"message_notifications": { "type": "integer" },
+								"mute_config": { "$ref": "#/components/schemas/MuteConfig" },
+								"muted": { "type": "boolean" }
+							},
+							"additionalProperties": false,
+							"required": ["channel_id", "message_notifications", "mute_config", "muted"]
+						}
+					},
+					"message_notifications": { "type": "integer" },
+					"mobile_push": { "type": "boolean" },
+					"mute_config": { "$ref": "#/components/schemas/MuteConfig" },
+					"muted": { "type": "boolean" },
+					"suppress_everyone": { "type": "boolean" },
+					"suppress_roles": { "type": "boolean" },
+					"version": { "type": "integer" }
+				},
+				"required": [
+					"channel_overrides",
+					"message_notifications",
+					"mobile_push",
+					"mute_config",
+					"muted",
+					"suppress_everyone",
+					"suppress_roles",
+					"version"
+				]
+			},
+			"MuteConfig": {
+				"type": "object",
+				"properties": { "end_time": { "type": "integer" }, "selected_time_window": { "type": "integer" } },
+				"required": ["end_time", "selected_time_window"]
+			},
+			"Webhook": {
+				"type": "object",
+				"properties": {
+					"id": { "type": "string" },
+					"type": { "$ref": "#/components/schemas/WebhookType" },
+					"name": { "type": "string" },
+					"avatar": { "type": "string" },
+					"token": { "type": "string" },
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"channel_id": { "type": "string" },
+					"channel": { "$ref": "#/components/schemas/Channel" },
+					"application_id": { "type": "string" },
+					"application": { "$ref": "#/components/schemas/Application" },
+					"user_id": { "type": "string" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"source_guild_id": { "type": "string" },
+					"source_guild": { "$ref": "#/components/schemas/Guild" }
+				},
+				"required": [
+					"application",
+					"application_id",
+					"channel",
+					"channel_id",
+					"guild",
+					"guild_id",
+					"id",
+					"source_guild",
+					"source_guild_id",
+					"type",
+					"user",
+					"user_id"
+				]
+			},
+			"WebhookType": { "enum": [1, 2], "type": "number" },
+			"Application": {
+				"type": "object",
+				"properties": {
+					"name": { "type": "string" },
+					"icon": { "type": "string" },
+					"description": { "type": "string" },
+					"rpc_origins": { "type": "array", "items": { "type": "string" } },
+					"bot_public": { "type": "boolean" },
+					"bot_require_code_grant": { "type": "boolean" },
+					"terms_of_service_url": { "type": "string" },
+					"privacy_policy_url": { "type": "string" },
+					"owner": { "$ref": "#/components/schemas/User" },
+					"summary": { "type": "string" },
+					"verify_key": { "type": "string" },
+					"team": { "$ref": "#/components/schemas/Team" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"primary_sku_id": { "type": "string" },
+					"slug": { "type": "string" },
+					"cover_image": { "type": "string" },
+					"flags": { "type": "string" },
+					"id": { "type": "string" }
+				},
+				"required": ["bot_public", "bot_require_code_grant", "description", "flags", "guild", "id", "name", "verify_key"]
+			},
+			"Sticker": {
+				"type": "object",
+				"properties": {
+					"name": { "type": "string" },
+					"description": { "type": "string" },
+					"tags": { "type": "string" },
+					"pack_id": { "type": "string" },
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"type": { "$ref": "#/components/schemas/StickerType" },
+					"format_type": { "$ref": "#/components/schemas/StickerFormatType" },
+					"id": { "type": "string" }
+				},
+				"required": ["format_type", "id", "name", "pack_id", "tags", "type"]
+			},
+			"StickerType": { "enum": [1, 2], "type": "number" },
+			"StickerFormatType": { "enum": [1, 2, 3], "type": "number" },
+			"Attachment": {
+				"type": "object",
+				"properties": {
+					"filename": { "type": "string" },
+					"size": { "type": "integer" },
+					"url": { "type": "string" },
+					"proxy_url": { "type": "string" },
+					"height": { "type": "integer" },
+					"width": { "type": "integer" },
+					"content_type": { "type": "string" },
+					"message_id": { "type": "string" },
+					"message": { "$ref": "#/components/schemas/Message" },
+					"id": { "type": "string" }
+				},
+				"required": ["filename", "id", "message", "message_id", "proxy_url", "size", "url"]
+			},
+			"Embed": {
+				"type": "object",
+				"properties": {
+					"title": { "type": "string" },
+					"type": { "$ref": "#/components/schemas/EmbedType" },
+					"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": "#/components/schemas/EmbedImage" },
+					"thumbnail": { "$ref": "#/components/schemas/EmbedImage" },
+					"video": { "$ref": "#/components/schemas/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"]
+						}
+					}
+				}
+			},
+			"EmbedType": { "enum": ["article", "gifv", "image", "link", "rich", "video"], "type": "string" },
+			"EmbedImage": {
+				"type": "object",
+				"properties": {
+					"url": { "type": "string" },
+					"proxy_url": { "type": "string" },
+					"height": { "type": "integer" },
+					"width": { "type": "integer" }
+				}
+			},
+			"Reaction": {
+				"type": "object",
+				"properties": {
+					"count": { "type": "integer" },
+					"emoji": { "$ref": "#/components/schemas/PartialEmoji" },
+					"user_ids": { "type": "array", "items": { "type": "string" } }
+				},
+				"required": ["count", "emoji", "user_ids"]
+			},
+			"PartialEmoji": {
+				"type": "object",
+				"properties": { "id": { "type": "string" }, "name": { "type": "string" }, "animated": { "type": "boolean" } },
+				"required": ["name"]
+			},
+			"MessageType": { "enum": [0, 1, 10, 11, 12, 14, 15, 19, 2, 20, 3, 4, 5, 6, 7, 8, 9], "type": "number" },
+			"InteractionType": { "enum": [1, 2], "type": "number" },
+			"MessageComponent": {
+				"type": "object",
+				"properties": {
+					"type": { "type": "integer" },
+					"style": { "type": "integer" },
+					"label": { "type": "string" },
+					"emoji": { "$ref": "#/components/schemas/PartialEmoji" },
+					"custom_id": { "type": "string" },
+					"url": { "type": "string" },
+					"disabled": { "type": "boolean" },
+					"components": { "type": "array", "items": { "$ref": "#/components/schemas/MessageComponent" } }
+				},
+				"required": ["components", "type"]
+			},
+			"ChannelPermissionOverwrite": {
+				"type": "object",
+				"properties": {
+					"allow": { "type": "number" },
+					"deny": { "type": "number" },
+					"id": { "type": "string" },
+					"type": { "$ref": "#/components/schemas/ChannelPermissionOverwriteType" }
+				},
+				"required": ["allow", "deny", "id", "type"]
+			},
+			"ChannelPermissionOverwriteType": { "enum": [0, 1], "type": "number" },
+			"Ban": {
+				"type": "object",
+				"properties": {
+					"user_id": { "type": "string" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"executor_id": { "type": "string" },
+					"executor": { "$ref": "#/components/schemas/User" },
+					"ip": { "type": "string" },
+					"reason": { "type": "string" },
+					"id": { "type": "string" }
+				},
+				"required": ["executor", "executor_id", "guild", "guild_id", "id", "ip", "user", "user_id"]
+			},
+			"Template": {
+				"type": "object",
+				"properties": {
+					"code": { "type": "string" },
+					"name": { "type": "string" },
+					"description": { "type": "string" },
+					"usage_count": { "type": "integer" },
+					"creator_id": { "type": "string" },
+					"creator": { "$ref": "#/components/schemas/User" },
+					"created_at": { "type": "string", "format": "date-time" },
+					"updated_at": { "type": "string", "format": "date-time" },
+					"source_guild_id": { "type": "string" },
+					"source_guild": { "$ref": "#/components/schemas/Guild" },
+					"serialized_source_guild": { "$ref": "#/components/schemas/Guild" },
+					"id": { "type": "string" }
+				},
+				"required": [
+					"code",
+					"created_at",
+					"creator",
+					"creator_id",
+					"id",
+					"name",
+					"serialized_source_guild",
+					"source_guild",
+					"source_guild_id",
+					"updated_at"
+				]
+			},
+			"Emoji": {
+				"type": "object",
+				"properties": {
+					"animated": { "type": "boolean" },
+					"available": { "type": "boolean" },
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"managed": { "type": "boolean" },
+					"name": { "type": "string" },
+					"require_colons": { "type": "boolean" },
+					"id": { "type": "string" }
+				},
+				"required": ["animated", "available", "guild", "guild_id", "id", "managed", "name", "require_colons"]
+			},
+			"Invite": {
+				"type": "object",
+				"properties": {
+					"code": { "type": "string" },
+					"temporary": { "type": "boolean" },
+					"uses": { "type": "integer" },
+					"max_uses": { "type": "integer" },
+					"max_age": { "type": "integer" },
+					"created_at": { "type": "string", "format": "date-time" },
+					"expires_at": { "type": "string", "format": "date-time" },
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"channel_id": { "type": "string" },
+					"channel": { "$ref": "#/components/schemas/Channel" },
+					"inviter_id": { "type": "string" },
+					"inviter": { "$ref": "#/components/schemas/User" },
+					"target_user_id": { "type": "string" },
+					"target_user": { "type": "string" },
+					"target_user_type": { "type": "integer" },
+					"id": { "type": "string" }
+				},
+				"required": [
+					"channel",
+					"channel_id",
+					"code",
+					"created_at",
+					"expires_at",
+					"guild",
+					"guild_id",
+					"id",
+					"inviter",
+					"inviter_id",
+					"max_age",
+					"max_uses",
+					"target_user_id",
+					"temporary",
+					"uses"
+				]
+			},
+			"VoiceState": {
+				"type": "object",
+				"properties": {
+					"guild_id": { "type": "string" },
+					"guild": { "$ref": "#/components/schemas/Guild" },
+					"channel_id": { "type": "string" },
+					"channel": { "$ref": "#/components/schemas/Channel" },
+					"user_id": { "type": "string" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"session_id": { "type": "string" },
+					"deaf": { "type": "boolean" },
+					"mute": { "type": "boolean" },
+					"self_deaf": { "type": "boolean" },
+					"self_mute": { "type": "boolean" },
+					"self_stream": { "type": "boolean" },
+					"self_video": { "type": "boolean" },
+					"suppress": { "type": "boolean" },
+					"id": { "type": "string" }
+				},
+				"required": [
+					"channel",
+					"channel_id",
+					"deaf",
+					"guild_id",
+					"id",
+					"mute",
+					"self_deaf",
+					"self_mute",
+					"self_video",
+					"session_id",
+					"suppress",
+					"user",
+					"user_id"
+				]
+			},
+			"AuditLogEvents": {
+				"enum": [
+					1, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 40, 41, 42, 50, 51, 52, 60, 61, 62, 72, 73,
+					74, 75, 80, 81, 82
+				],
+				"type": "number"
+			},
+			"AuditLogChange": {
+				"type": "object",
+				"properties": {
+					"new_value": { "$ref": "#/components/schemas/AuditLogChangeValue" },
+					"old_value": { "$ref": "#/components/schemas/AuditLogChangeValue" },
+					"key": { "type": "string" }
+				},
+				"required": ["key"]
+			},
+			"AuditLogChangeValue": {
+				"type": "object",
+				"properties": {
+					"name": { "type": "string" },
+					"description": { "type": "string" },
+					"icon_hash": { "type": "string" },
+					"splash_hash": { "type": "string" },
+					"discovery_splash_hash": { "type": "string" },
+					"banner_hash": { "type": "string" },
+					"owner_id": { "type": "string" },
+					"region": { "type": "string" },
+					"preferred_locale": { "type": "string" },
+					"afk_channel_id": { "type": "string" },
+					"afk_timeout": { "type": "integer" },
+					"rules_channel_id": { "type": "string" },
+					"public_updates_channel_id": { "type": "string" },
+					"mfa_level": { "type": "integer" },
+					"verification_level": { "type": "integer" },
+					"explicit_content_filter": { "type": "integer" },
+					"default_message_notifications": { "type": "integer" },
+					"vanity_url_code": { "type": "string" },
+					"$add": { "type": "array", "items": { "type": "object", "properties": {} } },
+					"$remove": { "type": "array", "items": { "type": "object", "properties": {} } },
+					"prune_delete_days": { "type": "integer" },
+					"widget_enabled": { "type": "boolean" },
+					"widget_channel_id": { "type": "string" },
+					"system_channel_id": { "type": "string" },
+					"position": { "type": "integer" },
+					"topic": { "type": "string" },
+					"bitrate": { "type": "integer" },
+					"permission_overwrites": { "type": "array", "items": { "$ref": "#/components/schemas/ChannelPermissionOverwrite" } },
+					"nsfw": { "type": "boolean" },
+					"application_id": { "type": "string" },
+					"rate_limit_per_user": { "type": "integer" },
+					"permissions": { "type": "string" },
+					"color": { "type": "integer" },
+					"hoist": { "type": "boolean" },
+					"mentionable": { "type": "boolean" },
+					"allow": { "type": "string" },
+					"deny": { "type": "string" },
+					"code": { "type": "string" },
+					"channel_id": { "type": "string" },
+					"inviter_id": { "type": "string" },
+					"max_uses": { "type": "integer" },
+					"uses": { "type": "integer" },
+					"max_age": { "type": "integer" },
+					"temporary": { "type": "boolean" },
+					"deaf": { "type": "boolean" },
+					"mute": { "type": "boolean" },
+					"nick": { "type": "string" },
+					"avatar_hash": { "type": "string" },
+					"id": { "type": "string" },
+					"type": { "type": "integer" },
+					"enable_emoticons": { "type": "boolean" },
+					"expire_behavior": { "type": "integer" },
+					"expire_grace_period": { "type": "integer" },
+					"user_limit": { "type": "integer" }
+				}
+			},
+			"AuditLog": {
+				"type": "object",
+				"properties": {
+					"target": { "$ref": "#/components/schemas/User" },
+					"user_id": { "type": "string" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"action_type": { "$ref": "#/components/schemas/AuditLogEvents" },
+					"options": {
+						"type": "object",
+						"properties": {
+							"delete_member_days": { "type": "string" },
+							"members_removed": { "type": "string" },
+							"channel_id": { "type": "string" },
+							"messaged_id": { "type": "string" },
+							"count": { "type": "string" },
+							"id": { "type": "string" },
+							"type": { "type": "string" },
+							"role_name": { "type": "string" }
+						},
+						"additionalProperties": false
+					},
+					"changes": { "type": "array", "items": { "$ref": "#/components/schemas/AuditLogChange" } },
+					"reason": { "type": "string" },
+					"id": { "type": "string" }
+				},
+				"required": ["action_type", "changes", "id", "user", "user_id"]
+			},
+			"ReadState": {
+				"type": "object",
+				"properties": {
+					"channel_id": { "type": "string" },
+					"channel": { "$ref": "#/components/schemas/Channel" },
+					"user_id": { "type": "string" },
+					"user": { "$ref": "#/components/schemas/User" },
+					"last_message_id": { "type": "string" },
+					"last_message": { "$ref": "#/components/schemas/Message" },
+					"last_pin_timestamp": { "type": "string", "format": "date-time" },
+					"mention_count": { "type": "integer" },
+					"manual": { "type": "boolean" },
+					"id": { "type": "string" }
+				},
+				"required": ["channel", "channel_id", "id", "last_message_id", "manual", "mention_count", "user", "user_id"]
+			},
+			"UserPublic": {
+				"type": "object",
+				"properties": {
+					"username": { "type": "string" },
+					"discriminator": { "type": "string" },
+					"id": { "type": "string" },
+					"public_flags": { "type": "string" },
+					"avatar": { "type": "string" },
+					"accent_color": { "type": "integer" },
+					"banner": { "type": "string" },
+					"bio": { "type": "string" },
+					"bot": { "type": "boolean" }
+				},
+				"required": ["bio", "bot", "discriminator", "id", "public_flags", "username"]
+			}
+		},
+		"requestBodies": {
+			"BanCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": { "delete_message_days": { "type": "string" }, "reason": { "type": "string" } }
+						}
+					}
+				},
+				"description": ""
+			},
+			"DmChannelCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"name": { "type": "string" },
+								"recipients": { "type": "array", "items": { "type": "string" } }
+							},
+							"required": ["recipients"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"ChannelModifySchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"name": { "type": "string" },
+								"type": { "type": "integer" },
+								"topic": { "type": "string" },
+								"bitrate": { "type": "integer" },
+								"user_limit": { "type": "integer" },
+								"rate_limit_per_user": { "type": "integer" },
+								"position": { "type": "integer" },
+								"permission_overwrites": {
+									"type": "array",
+									"items": {
+										"type": "object",
+										"properties": {
+											"id": { "type": "string" },
+											"type": { "type": "integer" },
+											"allow": { "type": "number" },
+											"deny": { "type": "number" }
+										},
+										"additionalProperties": false,
+										"required": ["allow", "deny", "id", "type"]
+									}
+								},
+								"parent_id": { "type": "string" },
+								"id": { "type": "string" },
+								"nsfw": { "type": "boolean" },
+								"rtc_region": { "type": "string" },
+								"default_auto_archive_duration": { "type": "integer" }
+							},
+							"required": ["name", "type"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"ChannelGuildPositionUpdateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "array",
+							"items": {
+								"type": "object",
+								"properties": { "id": { "type": "string" }, "position": { "type": "integer" } },
+								"additionalProperties": false,
+								"required": ["id"]
+							}
+						}
+					}
+				},
+				"description": ""
+			},
+			"EmojiCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"name": { "type": "string" },
+								"image": { "type": "string" },
+								"roles": { "type": "array", "items": { "type": "string" } }
+							},
+							"required": ["image", "name"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"GuildCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"name": { "type": "string" },
+								"region": { "type": "string" },
+								"icon": { "type": "string" },
+								"channels": { "type": "array", "items": { "$ref": "#/components/requestBodies/ChannelModifySchema" } },
+								"guild_template_code": { "type": "string" },
+								"system_channel_id": { "type": "string" },
+								"rules_channel_id": { "type": "string" }
+							},
+							"required": ["name"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"GuildUpdateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"banner": { "type": "string" },
+								"splash": { "type": "string" },
+								"description": { "type": "string" },
+								"features": { "type": "array", "items": { "type": "string" } },
+								"verification_level": { "type": "integer" },
+								"default_message_notifications": { "type": "integer" },
+								"system_channel_flags": { "type": "integer" },
+								"explicit_content_filter": { "type": "integer" },
+								"public_updates_channel_id": { "type": "string" },
+								"afk_timeout": { "type": "integer" },
+								"afk_channel_id": { "type": "string" },
+								"preferred_locale": { "type": "string" },
+								"name": { "type": "string" },
+								"region": { "type": "string" },
+								"icon": { "type": "string" },
+								"guild_template_code": { "type": "string" },
+								"system_channel_id": { "type": "string" },
+								"rules_channel_id": { "type": "string" }
+							},
+							"required": ["name"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"GuildTemplateCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": { "name": { "type": "string" }, "avatar": { "type": "string" } },
+							"required": ["name"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"GuildUpdateWelcomeScreenSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"welcome_channels": {
+									"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"]
+									}
+								},
+								"enabled": { "type": "boolean" },
+								"description": { "type": "string" }
+							}
+						}
+					}
+				},
+				"description": ""
+			},
+			"Number": { "content": { "application/json": { "schema": { "type": "object" } } }, "description": "" },
+			"Boolean": { "content": { "application/json": { "schema": { "type": "object" } } }, "description": "" },
+			"InviteCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"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" }
+							}
+						}
+					}
+				},
+				"description": ""
+			},
+			"MemberCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"id": { "type": "string" },
+								"nick": { "type": "string" },
+								"guild_id": { "type": "string" },
+								"joined_at": { "type": "string", "format": "date-time" }
+							},
+							"required": ["guild_id", "id", "joined_at", "nick"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"MemberNickChangeSchema": {
+				"content": {
+					"application/json": {
+						"schema": { "type": "object", "properties": { "nick": { "type": "string" } }, "required": ["nick"] }
+					}
+				},
+				"description": ""
+			},
+			"MemberChangeSchema": {
+				"content": {
+					"application/json": {
+						"schema": { "type": "object", "properties": { "roles": { "type": "array", "items": { "type": "string" } } } }
+					}
+				},
+				"description": ""
+			},
+			"EmbedType": {
+				"content": {
+					"application/json": { "schema": { "enum": ["article", "gifv", "image", "link", "rich", "video"], "type": "string" } }
+				},
+				"description": ""
+			},
+			"EmbedImage": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"url": { "type": "string" },
+								"proxy_url": { "type": "string" },
+								"height": { "type": "integer" },
+								"width": { "type": "integer" }
+							}
+						}
+					}
+				},
+				"description": ""
+			},
+			"MessageCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"content": { "type": "string" },
+								"nonce": { "type": "string" },
+								"tts": { "type": "boolean" },
+								"flags": { "type": "string" },
+								"embed": {
+									"additionalProperties": false,
+									"type": "object",
+									"properties": {
+										"title": { "type": "string" },
+										"type": { "$ref": "#/components/requestBodies/EmbedType" },
+										"description": { "type": "string" },
+										"url": { "type": "string" },
+										"timestamp": { "type": "string" },
+										"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": "#/components/requestBodies/EmbedImage" },
+										"thumbnail": { "$ref": "#/components/requestBodies/EmbedImage" },
+										"video": { "$ref": "#/components/requestBodies/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"]
+											}
+										}
+									}
+								},
+								"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": {}
+							}
+						}
+					}
+				},
+				"description": ""
+			},
+			"RoleModifySchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"name": { "type": "string" },
+								"permissions": { "type": "number" },
+								"color": { "type": "integer" },
+								"hoist": { "type": "boolean" },
+								"mentionable": { "type": "boolean" },
+								"position": { "type": "integer" }
+							}
+						}
+					}
+				},
+				"description": ""
+			},
+			"TemplateCreateSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": { "name": { "type": "string" }, "description": { "type": "string" } },
+							"required": ["name"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"TemplateModifySchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": { "name": { "type": "string" }, "description": { "type": "string" } },
+							"required": ["name"]
+						}
+					}
+				},
+				"description": ""
+			},
+			"UserModifySchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"username": { "type": "string" },
+								"avatar": { "type": "string" },
+								"bio": { "type": "string" },
+								"accent_color": { "type": "integer" },
+								"banner": { "type": "string" },
+								"password": { "type": "string" },
+								"new_password": { "type": "string" },
+								"code": { "type": "string" }
+							}
+						}
+					}
+				},
+				"description": ""
+			},
+			"UserSettingsSchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": {
+								"afk_timeout": { "type": "integer" },
+								"allow_accessibility_detection": { "type": "boolean" },
+								"animate_emoji": { "type": "boolean" },
+								"animate_stickers": { "type": "integer" },
+								"contact_sync_enabled": { "type": "boolean" },
+								"convert_emoticons": { "type": "boolean" },
+								"custom_status": {
+									"type": "object",
+									"properties": {
+										"emoji_id": { "type": "string" },
+										"emoji_name": { "type": "string" },
+										"expires_at": { "type": "integer" },
+										"text": { "type": "string" }
+									},
+									"additionalProperties": false
+								},
+								"default_guilds_restricted": { "type": "boolean" },
+								"detect_platform_accounts": { "type": "boolean" },
+								"developer_mode": { "type": "boolean" },
+								"disable_games_tab": { "type": "boolean" },
+								"enable_tts_command": { "type": "boolean" },
+								"explicit_content_filter": { "type": "integer" },
+								"friend_source_flags": {
+									"type": "object",
+									"properties": { "all": { "type": "boolean" } },
+									"additionalProperties": false,
+									"required": ["all"]
+								},
+								"gateway_connected": { "type": "boolean" },
+								"gif_auto_play": { "type": "boolean" },
+								"guild_folders": {
+									"type": "array",
+									"items": {
+										"type": "object",
+										"properties": {
+											"color": { "type": "integer" },
+											"guild_ids": { "type": "array", "items": { "type": "string" } },
+											"id": { "type": "integer" },
+											"name": { "type": "string" }
+										},
+										"additionalProperties": false,
+										"required": ["color", "guild_ids", "id", "name"]
+									}
+								},
+								"guild_positions": { "type": "array", "items": { "type": "string" } },
+								"inline_attachment_media": { "type": "boolean" },
+								"inline_embed_media": { "type": "boolean" },
+								"locale": { "type": "string" },
+								"message_display_compact": { "type": "boolean" },
+								"native_phone_integration_enabled": { "type": "boolean" },
+								"render_embeds": { "type": "boolean" },
+								"render_reactions": { "type": "boolean" },
+								"restricted_guilds": { "type": "array", "items": { "type": "string" } },
+								"show_current_game": { "type": "boolean" },
+								"status": { "enum": ["dnd", "idle", "offline", "online"], "type": "string" },
+								"stream_notifications_enabled": { "type": "boolean" },
+								"theme": { "enum": ["dark", "white"], "type": "string" },
+								"timezone_offset": { "type": "integer" }
+							},
+							"required": [
+								"afk_timeout",
+								"allow_accessibility_detection",
+								"animate_emoji",
+								"animate_stickers",
+								"contact_sync_enabled",
+								"convert_emoticons",
+								"custom_status",
+								"default_guilds_restricted",
+								"detect_platform_accounts",
+								"developer_mode",
+								"disable_games_tab",
+								"enable_tts_command",
+								"explicit_content_filter",
+								"friend_source_flags",
+								"gateway_connected",
+								"gif_auto_play",
+								"guild_folders",
+								"guild_positions",
+								"inline_attachment_media",
+								"inline_embed_media",
+								"locale",
+								"message_display_compact",
+								"native_phone_integration_enabled",
+								"render_embeds",
+								"render_reactions",
+								"restricted_guilds",
+								"show_current_game",
+								"status",
+								"stream_notifications_enabled",
+								"theme",
+								"timezone_offset"
+							]
+						}
+					}
+				},
+				"description": ""
+			},
+			"WidgetModifySchema": {
+				"content": {
+					"application/json": {
+						"schema": {
+							"type": "object",
+							"properties": { "enabled": { "type": "boolean" }, "channel_id": { "type": "string" } },
+							"required": ["channel_id", "enabled"]
+						}
+					}
+				},
+				"description": ""
+			}
+		},
+		"securitySchemes": { "authorization": { "type": "oauth2" } },
+		"links": {},
+		"callbacks": {}
+	},
+	"security": [{ "authorization": [] }]
+}
diff --git a/api/assets/openapi.yaml b/api/assets/openapi.yaml
deleted file mode 100644
index 06a0b72d..00000000
--- a/api/assets/openapi.yaml
+++ /dev/null
@@ -1,136 +0,0 @@
-openapi: 3.0.3
-info:
-  title: Fosscord
-  version: '9'
-  license:
-    name: GNU AGPLv3
-    url: https://www.gnu.org/licenses/agpl.txt
-    x-last-modified: 1625409195984
-  x-logo:
-    url: ''
-servers:
-  - url: https://api.fosscord.com
-    description: ''
-    x-last-modified: 1625407844365
-paths:
-  /users/:id:
-    summary: get user
-    description: test
-    get:
-      tags: []
-      responses:
-        '200':
-          $ref: '#/components/responses/User'
-          x-last-modified: 1625409722629
-      parameters:
-        - name: id
-          in: path
-          required: true
-          deprecated: false
-          x-last-modified: 1625409813480
-    x-last-modified: 1625409704895
-components:
-  schemas:
-    User:
-      type: object
-      properties:
-        avatar:
-          type: string
-          example:
-            - d83f330fc30367f859bc6ee358b14319
-        bot:
-          type: boolean
-          example:
-            - false
-        desktop:
-          type: boolean
-          example:
-            - false
-        discriminator:
-          type: string
-          example:
-            - '0001'
-        email:
-          type: string
-          example:
-            - example@example.org
-        flags:
-          type: string
-          example:
-            - '0'
-        id:
-          type: string
-          example:
-            - '732645009894277321'
-        mfa_enabled:
-          type: boolean
-          example:
-            - false
-        mobile:
-          type: boolean
-          example:
-            - false
-        nsfw_allowed:
-          type: boolean
-          example:
-            - true
-        premium:
-          type: boolean
-          example:
-            - false
-        premium_type:
-          type: number
-          example:
-            - 0
-        public_flags:
-          type: string
-          example:
-            - '0'
-        username:
-          type: string
-          example:
-            - Example
-        verified:
-          type: boolean
-          example:
-            - true
-      example:
-        avatar: d83f330fc30367f859bc6ee358b14319
-        bot: false
-        desktop: false
-        discriminator: '0001'
-        email: example@example.org
-        flags: '0'
-        id: '732645009894277321'
-        mfa_enabled: false
-        mobile: false
-        nsfw_allowed: true
-        premium: false
-        premium_type: 0
-        public_flags: '0'
-        username: Example
-        verified: true
-      x-last-modified: 1625409630283
-      required: []
-      description: test
-  securitySchemes:
-    JWTAuth:
-      scheme: bearer
-      bearerFormat: JWT
-      type: http
-      description: |-
-        Example: 
-        > Authorization: Bot <token>
-      x-last-modified: 1625407825787
-  headers: {}
-  responses:
-    User:
-      content:
-        application/json:
-          schema:
-            $ref: '#/components/schemas/User'
-      x-last-modified: 1625409578903
-  parameters: {}
-security:
-  - JWTAuth: []
-tags: []
diff --git a/api/assets/openapi.yml b/api/assets/openapi.yml
deleted file mode 100644
index 957b6d16..00000000
--- a/api/assets/openapi.yml
+++ /dev/null
@@ -1,526 +0,0 @@
-swagger: "2.0"
-info:
-    description: "Fosscord backend api docs"
-    version: "1.0.0"
-    title: "Fosscord Backend API"
-    termsOfService: "https://github.com/fosscord/fosscord/blob/master/LICENSE"
-    license:
-        name: "AGPL 3.0"
-        url: "https://www.gnu.org/licenses/agpl-3.0.html"
-host: "dev.fosscord.com"
-basePath: "/api/v9"
-tags:
-  - name: "Audit Log"
-    description: "Guild Audit Log resource"
-    externalDocs:
-        description: "Find out more"
-        url: "https://discord.com/developers/docs/resources/audit-log"
-  - name: "Channel"
-    description: "Channel resource"
-    externalDocs:
-        description: "Find out more"
-        url: "https://discord.com/developers/docs/resources/channel"
-schemes:
-  - "https"
-  - "http"
-paths:
-    /guilds/{guildId}/audit-logs:
-        get:
-            summary: "Returns an audit log object for the guild. Requires the 'VIEW_AUDIT_LOG' permission."
-            tags:
-              - Audit Log
-            parameters:
-              - $ref: "#/definitionsParam/guildId"
-              - name: user_id
-                in: query
-                type: string
-                description: "Type of snowflake - Filter the log for actions made by a user"
-              - name: action_type
-                in: query
-                type: integer
-                description: "The type of audit log event"
-              - name: before
-                in: query
-                type: string
-                description: "Type of snowflake - Filter the log before a certain entry id"
-              - name: limit
-                in: query
-                type: integer
-                description: "How many entries are returned (default 50, minimum 1, maximum 100)"
-            responses:
-                '200': 
-                    description: "Audit Log Object"
-                    schema:
-                        $ref: "#/definitions/Audit%20Log"
-    /channels/{channelId}:
-        get:
-            summary: "Get a channel by ID. Returns a channel object. If the channel is a thread, a thread member object is included in the returned result."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-            responses:
-                '200':
-                    description: "Channel Object"
-                    schema:
-                        $ref: "#/definitions/Channel"
-        patch:
-            summary: "Update a channel's settings. Returns a channel on success, and a 400 BAD REQUEST on invalid parameters. All JSON parameters are optional."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - name: body (Group DM)
-                in: body
-                description: "The request body when modifying Group DM channels - Fires a Channel Update Gateway event."
-                schema:
-                    type: object
-                    properties:
-                        name:
-                            type: string
-                            description: "1-100 character channel name"
-                        icon:
-                            type: string
-                            format: byte
-                            description: "base64 encoded icon"
-              - name: body (Guild channel)
-                in: body
-                description: "Requires the MANAGE_CHANNELS permission for the guild. Fires a Channel Update Gateway event. If modifying a category, individual Channel Update events will fire for each child channel that also changes. If modifying permission overwrites, the MANAGE_ROLES permission is required. 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)."
-                schema:
-                    type: object
-                    properties:
-                        name:
-                            type: string
-                            description: "1-100 character channel name"
-                        type:
-                            type: integer
-                            description: "The type of channel; only conversion between text and news is supported and only in guilds with the \"NEWS\" feature"
-                        position:
-                            type: integer
-                            default: null
-                            description: "The position of the channel in the left-hand listing"
-                        topic:
-                            type: string
-                            default: null
-                            description: "0-1024 character channel topic"
-                        nsfw:
-                            type: boolean
-                            default: null
-                            description: "Whether the channel is nsfw"
-                        rate_limit_per_user:
-                            type: integer
-                            default: null
-                            description: "Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages or manage_channel, are unaffected"
-                        bitrate:
-                            type: integer
-                            default: null
-                            description: "The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)"
-                        user_limit:
-                            type: integer
-                            default: null
-                            description: "The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit"
-                        permission_overwrites:
-                            type: array
-                            items:
-                                $ref: "#/definitions/Overwrite"
-                            default: null
-                            description: "Channel or category-specific permissions"
-                        parent_id:
-                            $ref: "#/definitions/Snowflake"
-                            default: null
-                            description: "Id of the new parent category for a channel"
-                        rtc_region:
-                            type: string
-                            default: null
-                            description: "Channel voice region id, automatic when set to null"
-                        video_quality_mode:
-                            type: integer
-                            default: null
-                            description: "The camera video quality mode of the voice channel"
-                        default_auto_archive_duration:
-                            type: integer
-                            default: null
-                            description: "The default duration for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity"
-              - name: body (Thread)
-                in: body
-                description: "When setting archived to false, when locked is also false, only the SEND_MESSAGES permission is required.Otherwise, requires the MANAGE_THREADS permission. Fires a Thread Update Gateway event. Requires the thread to have archived set to false or be set to false in the request."
-                schema:
-                    type: object
-                    properties:
-                        name:
-                            type: string
-                            description: "1-100 character channel name"
-                        archived:
-                            type: boolean
-                            description: "Whether the channel is archived"
-                        auto_archive_duration:
-                            type: integer
-                            description: "Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080 (The 3 day and 7 day archive durations require the server to be boosted. The guild features will indicate if a server is able to use those settings)"
-                        locked:
-                            type: boolean
-                            description: "When a thread is locked, only users with MANAGE_THREADS can unarchive it"
-                        rate_limit_per_user:
-                            type: integer
-                            default: null
-                            description: "Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected"
-            responses:
-                '200':
-                    description: "Channel Object"
-                    schema:
-                        $ref: "#/definitions/Channel"
-                '400':
-                    description: "Bad Request due to invalid parameters"
-        delete:
-            summary: "Delete a channel, or close a private message. Requires the MANAGE_CHANNELS permission for the guild, or MANAGE_THREADS if the channel is a thread. Deleting a category does not delete its child channels; they will have their parent_id removed and a Channel Update Gateway event will fire for each of them. Returns a channel object on success. Fires a Channel Delete Gateway event (or Thread Delete if the channel was a thread)."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-            responses:
-                '200':
-                    description: "Channel deleted sucessfully"
-    /channels/{channelId}/messages:
-        get:
-            summary: "Returns the messages for a channel. If operating on a guild channel, this endpoint requires the VIEW_CHANNEL permission to be present on the current user. If the current user is missing the 'READ_MESSAGE_HISTORY' permission in the channel then this will return no messages (since they cannot read the message history). Returns an array of message objects on success."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - name: around
-                in: query
-                type: string
-                description: "Type of snowflake - Get messages around this message ID"
-              - name: before
-                in: query
-                type: string
-                description: "Type of snowflake - Get messages before this message ID"
-              - name: after
-                in: query
-                type: string
-                description: "Type of snowflake - Get messages after this message ID"
-              - name: limit
-                in: query
-                type: integer
-                description: "Max number of messages to return (1-100)"
-                default: 50
-            responses:
-                '200':
-                    description: "Returns an array of message objects on success"
-                    schema:
-                        type: array
-                        items:
-                            $ref: "#/definitions/Message"
-    /channels/{channelId}/messages/{messageId}:
-        get:
-            summary: "Returns a specific message in the channel. If operating on a guild channel, this endpoint requires the 'READ_MESSAGE_HISTORY' permission to be present on the current user. Returns a message object on success."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-            responses:
-                '200':
-                    description: "Returns a message object on success"
-                    schema:
-                        $ref: "#/definitions/Message"
-        post:
-            summary: "Post a message to a guild text or DM channel. Returns a message object. Fires a Message Create Gateway event. See message formatting for more information on how to properly format messages."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-              - name: body
-                in: body
-                required: true
-                description: "Request body that contains the necessary data for creating messages"
-                schema:
-                    type: object
-                    properties:
-                        content:
-                            type: string
-                            description: "The message contents (up to 2000 characters)"
-                        tts:
-                            type: boolean
-                            description: "True if this is a TTS message"
-                            default: null
-                        file:
-                            type: string
-                            format: binary
-                            description: "The contents of the file being sent"
-                        embeds:
-                            type: array
-                            items:
-                                $ref: "#/definitions/Embed"
-                            description: "Embedded rich content (up to 6000 characters)"
-                        payload_json:
-                            type: string
-                            description: "JSON encoded body of non-file params"
-                            default: null
-                        allowed_mentions:
-                            $ref: "#/definitions/Allowed%20Mention"
-                            description: "Allowed mentions for the message"
-                            default: null
-                        message_refrence:
-                            $ref: "#/definitions/Message%20Refrence"
-                            description: "Include to make your message a reply"
-                            default: null
-                        components:
-                            type: array
-                            items:
-                                $ref: "#/definitions/Message%20Component"
-                            default: null
-            responses:
-                '200':
-                    description: "Returns a message object on success"
-                    schema:
-                        $ref: "#/definitions/Message"
-        patch:
-            summary: "Edit a previously sent message. The fields content, embeds, and flags can be edited by the original message author. Other users can only edit flags and only if they have the MANAGE_MESSAGES permission in the corresponding channel. When specifying flags, ensure to include all previously set flags/bits in addition to ones that you are modifying. Only flags documented in the table below may be modified by users (unsupported flag changes are currently ignored without error)."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-              - name: body
-                in: body
-                required: true
-                description: "Request body that contains the necessary data for editing messages"
-                schema:
-                    type: object
-                    properties:
-                        content:
-                            type: string
-                            description: "The message contents (up to 2000 characters)"
-                        embeds:
-                            type: array
-                            items:
-                                $ref: "#/definitions/Embed"
-                            description: "Embedded rich content (up to 6000 characters)"
-                        flags:
-                            type: integer
-                            description: "Edit the flags of a message (only SUPPRESS_EMBEDS can currently be set/unset)"
-                        file:
-                            type: string
-                            format: binary
-                            description: "The contents of the file being sent/edited"
-                        payload_json:
-                            type: string
-                            description: "JSON encoded body of non-file params (multipart/form-data only)"
-                            default: null
-                        allowed_mentions:
-                            $ref: "#/definitions/Allowed%20Mention"
-                            description: "Allowed mentions for the message"
-                            default: null
-                        message_refrence:
-                            $ref: "#/definitions/Message%20Refrence"
-                            description: "Include to make your message a reply"
-                            default: null
-                        components:
-                            type: array
-                            items:
-                                $ref: "#/definitions/Message%20Component"
-                            default: null
-            responses:
-                '200':
-                    description: "Message edited"
-        delete:
-            summary: "Delete a message. If operating on a guild channel and trying to delete a message that was not sent by the current user, this endpoint requires the MANAGE_MESSAGES permission. Returns a 204 empty response on success. Fires a Message Delete Gateway event."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-            responses:
-                '204':
-                    description: "Returns a 204 empty response on success."
-    /channels/{channelId}/messages/{messageId}/crosspost:
-        post:
-            summary: "Crosspost a message in a News Channel to following channels. This endpoint requires the 'SEND_MESSAGES' permission, if the current user sent the message, or additionally the 'MANAGE_MESSAGES' permission, for all other messages, to be present for the current user."
-            tags:
-                - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-            responses:
-                '200':
-                    description: "Returns a message object on success"
-                    schema:
-                        $ref: "#/definitions/Message"
-    /channels/{channelId}/messages/{messageId}/reactions/{emoji}/@me:
-        put:
-            summary: "Create a reaction for the message. This endpoint requires the 'READ_MESSAGE_HISTORY' permission to be present on the current user. Additionally, if nobody else has reacted to the message using this emoji, this endpoint requires the 'ADD_REACTIONS' permission to be present on the current user. Returns a 204 empty response on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-              - $ref: "#/definitionsParam/emoji"
-            responses:
-                '204':
-                    description: "Returns a 204 empty response on success."
-        delete:
-            summary: "Delete a reaction the current user has made for the message. Returns a 204 empty response on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-              - $ref: "#/definitionsParam/emoji"
-            responses:
-                '204':
-                    description: "Returns a 204 empty response on success."
-    /channels/{channelId}/messages/{messageId}/reactions/{emoji}/{userId}:
-        delete:
-            summary: "Deletes another user's reaction. This endpoint requires the 'MANAGE_MESSAGES' permission to be present on the current user. Returns a 204 empty response on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-              - $ref: "#/definitionsParam/emoji"
-              - $ref: "#/definitionsParam/userId"
-            responses:
-                '204':
-                    description: "Returns a 204 empty response on success."
-    /channels/{channelId}/messages/{messageId}/reactions/{emoji}:
-        get:
-            summary: "Get a list of users that reacted with this emoji. Returns an array of user objects on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-              - $ref: "#/definitionsParam/emoji"
-              - name: after
-                in: query
-                type: string
-                description: "Type of snowflake - Get users after this user ID"
-              - name: limit
-                in: query
-                type: integer
-                description: "Max number of users to return (1-100)"
-                default: 25
-            responses:
-                '200':
-                    description: "Returns an array of user objects on success"
-                    schema:
-                        type: array
-                        items:
-                            $ref: "#/definitions/User"
-        delete:
-            summary: "Deletes all the reactions for a given emoji on a message. This endpoint requires the MANAGE_MESSAGES permission to be present on the current user. Fires a Message Reaction Remove Emoji Gateway event. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-              - $ref: "#/definitionsParam/emoji"
-            responses:
-                '204':
-                    description: "Returns a 204 empty response on success."
-    /channels/{channelId}/messages/{messageId}/reactions:
-        delete:
-            summary: "Deletes all reactions on a message. This endpoint requires the 'MANAGE_MESSAGES' permission to be present on the current user. Fires a Message Reaction Remove All Gateway event."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-              - $ref: "#/definitionsParam/messageId"
-            responses:
-                '204':
-                    description: "Returns a 204 empty response on success."
-    /channels/{channelId}/messages/bulk-delete:
-        post:
-            summary: "Delete multiple messages in a single request. This endpoint can only be used on guild channels and requires the MANAGE_MESSAGES permission. Returns a 204 empty response on success. Fires a Message Delete Bulk Gateway event."
-            tags:
-              - Channel
-            parameters:
-              - $ref: "#/definitionsParam/channelId"
-            responses:
-                '204':
-                    description: "Returns a 204 empty response on success."
-definitions:
-    Snowflake:
-        type: string
-        pattern: "^\\d+$"
-    Audit Log:
-        type: object
-        properties:
-            webhooks:
-                type: array
-                items:
-                    $ref: "#/definitions/Webhook"
-                description: "List of webhooks found in the audit log"
-            users:
-                type: array
-                items:
-                    $ref: "#/definitions/User"
-                description: "List of users found in the audit log"
-            audit_log_entries:
-                type: array
-                items:
-                    $ref: "#/definitions/Audit%20Log%20Entry"
-                description: "List of audit log entries"
-            integrations:
-                type: array
-                items:
-                    $ref: "#/definitions/Integration"
-                description: "List of partial integration objects"
-    Audit Log Entry:
-        type: object
-    Webhook:
-        type: object
-    User:
-        type: object
-    Integration:
-        type: object
-    Channel:
-        type: object
-    Overwrite:
-        type: object
-    Message:
-        type: object
-    Embed:
-        type: object
-    Allowed Mention:
-        type: object
-    Message Refrence:
-        type: object
-    Message Component:
-        type: object
-definitionsParam:
-    channelId:
-        name: channelId
-        in: path
-        required: true
-        type: string
-        description: "Type of snowflake - A channel Id"
-    messageId:
-        name: messageId
-        in: path
-        required: true
-        type: string
-        description: "Type of snowflake - A message ID"
-    guildId:
-        name: guildId
-        in: path
-        required: true
-        type: string
-        description: "Type of snowflake - A guild ID"
-    emoji:
-        name: emoji
-        in: path
-        required: true
-        type: string
-        format: url
-        description: "The emoji ID to use"
-    userId:
-        name: userId
-        in: path
-        required: true
-        type: string
-        description: "Type of snowflake - A user ID"
-externalDocs:
-    description: "Discord API"
-    url: "https://discord.com/developers/docs/"
diff --git a/api/patches/typescript-json-schema+0.50.1.patch b/api/patches/typescript-json-schema+0.50.1.patch
new file mode 100644
index 00000000..a0d479de
--- /dev/null
+++ b/api/patches/typescript-json-schema+0.50.1.patch
@@ -0,0 +1,14 @@
+diff --git a/node_modules/typescript-json-schema/dist/typescript-json-schema.js b/node_modules/typescript-json-schema/dist/typescript-json-schema.js
+index 47e1598..8397b9d 100644
+--- a/node_modules/typescript-json-schema/dist/typescript-json-schema.js
++++ b/node_modules/typescript-json-schema/dist/typescript-json-schema.js
+@@ -432,6 +432,9 @@ var JsonSchemaGenerator = (function () {
+             else if (flags & ts.TypeFlags.Boolean) {
+                 definition.type = "boolean";
+             }
++            else if (flags & ts.TypeFlags.BigInt) {
++                definition.type = "bigint";
++            }
+             else if (flags & ts.TypeFlags.Null) {
+                 definition.type = "null";
+             }
diff --git a/api/scripts/config_generator.js b/api/scripts/config_generator.js
deleted file mode 100644
index 5b5c52d4..00000000
--- a/api/scripts/config_generator.js
+++ /dev/null
@@ -1,93 +0,0 @@
-const { Snowflake } = require("@fosscord/server-util");
-const crypto = require('crypto');
-const fs = require('fs');
-
-
-const defaultConfig = {
-    // TODO: Get the network interfaces dinamically
-    gateway: "ws://localhost",
-    general: {
-        instance_id: Snowflake.generate(),
-    },
-    permissions: {
-        user: {
-            createGuilds: true,
-        }
-    },
-    limits: {
-        user: {
-            maxGuilds: 100,
-            maxUsername: 32,
-            maxFriends: 1000,
-        },
-        guild: {
-            maxRoles: 250,
-            maxMembers: 250000,
-            maxChannels: 500,
-            maxChannelsInCategory: 50,
-            hideOfflineMember: 1000,
-        },
-        message: {
-			characters: 2000,
-			ttsCharacters: 200,
-			maxReactions: 20,
-			maxAttachmentSize: 8388608,
-			maxBulkDelete: 100,
-		},
-		channel: {
-			maxPins: 50,
-			maxTopic: 1024,
-		},
-		rate: {
-			ip: {
-				enabled: true,
-				count: 1000,
-				timespan: 1000 * 60 * 10,
-			},
-			routes: {},
-		},
-	},
-	security: {
-		jwtSecret: crypto.randomBytes(256).toString("base64"),
-		forwadedFor: null,
-		// forwadedFor: "X-Forwarded-For" // nginx/reverse proxy
-		// forwadedFor: "CF-Connecting-IP" // cloudflare:
-		captcha: {
-			enabled: false,
-			service: null,
-			sitekey: null,
-			secret: null,
-		},
-	},
-	login: {
-		requireCaptcha: false,
-	},
-	register: {
-		email: {
-			necessary: true,
-			allowlist: false,
-			blocklist: true,
-			domains: [], // TODO: efficiently save domain blocklist in database
-			// domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"),
-		},
-		dateOfBirth: {
-			necessary: true,
-			minimum: 13,
-		},
-		requireInvite: false,
-		requireCaptcha: true,
-		allowNewRegistration: true,
-		allowMultipleAccounts: true,
-		password: {
-			minLength: 8,
-			minNumbers: 2,
-			minUpperCase: 2,
-			minSymbols: 0,
-			blockInsecureCommonPasswords: false,
-		},
-    },
-}
-
-let data = JSON.stringify(defaultConfig);
-fs.writeFileSync('./.docker/config/api.json', data);
-
diff --git a/api/scripts/generate_openapi_schema.ts b/api/scripts/generate_openapi_schema.ts
new file mode 100644
index 00000000..c45a43eb
--- /dev/null
+++ b/api/scripts/generate_openapi_schema.ts
@@ -0,0 +1,191 @@
+// https://mermade.github.io/openapi-gui/#
+// https://editor.swagger.io/
+import path from "path";
+import fs from "fs";
+import * as TJS from "typescript-json-schema";
+import "missing-native-js-functions";
+
+const settings: TJS.PartialArgs = {
+	required: true,
+	ignoreErrors: true,
+	excludePrivate: true,
+	defaultNumberType: "integer",
+	noExtraProps: true,
+	defaultProps: false
+};
+const compilerOptions: TJS.CompilerOptions = {
+	strictNullChecks: false
+};
+const openapiPath = path.join(__dirname, "..", "assets", "openapi.json");
+var specification = JSON.parse(fs.readFileSync(openapiPath, { encoding: "utf8" }));
+
+async function generateSchemas() {
+	const program = TJS.getProgramFromFiles([path.join(__dirname, "..", "..", "util", "src", "index.ts")], compilerOptions);
+	const generator = TJS.buildGenerator(program, settings);
+
+	const schemas = [
+		"Application",
+		"Attachment",
+		"Message",
+		"AuditLog",
+		"Ban",
+		"Channel",
+		"Emoji",
+		"Guild",
+		"Invite",
+		"ReadState",
+		"Recipient",
+		"Relationship",
+		"Role",
+		"Sticker",
+		"Team",
+		"TeamMember",
+		"Template",
+		"VoiceState",
+		"Webhook",
+		"User",
+		"UserPublic"
+	];
+
+	// @ts-ignore
+	const definitions = combineSchemas({ schemas, generator, program });
+
+	for (const key in definitions) {
+		specification.components.schemas[key] = definitions[key];
+		delete definitions[key].additionalProperties;
+	}
+}
+
+function combineSchemas(opts: { program: TJS.Program; generator: TJS.JsonSchemaGenerator; schemas: string[] }) {
+	var definitions: any = {};
+
+	for (const name of opts.schemas) {
+		const part = TJS.generateSchema(opts.program, name, settings, [], opts.generator as TJS.JsonSchemaGenerator);
+		if (!part) continue;
+
+		definitions = { ...definitions, ...part.definitions, [name]: { ...part, definitions: undefined, $schema: undefined } };
+	}
+
+	return definitions;
+}
+
+function generateBodies() {
+	const program = TJS.getProgramFromFiles([path.join(__dirname, "..", "src", "schema", "index.ts")], compilerOptions);
+	const generator = TJS.buildGenerator(program, settings);
+
+	const schemas = [
+		"BanCreateSchema",
+		"DmChannelCreateSchema",
+		"ChannelModifySchema",
+		"ChannelGuildPositionUpdateSchema",
+		"ChannelGuildPositionUpdateSchema",
+		"EmojiCreateSchema",
+		"GuildCreateSchema",
+		"GuildUpdateSchema",
+		"GuildTemplateCreateSchema",
+		"GuildUpdateWelcomeScreenSchema",
+		"InviteCreateSchema",
+		"MemberCreateSchema",
+		"MemberNickChangeSchema",
+		"MemberChangeSchema",
+		"MessageCreateSchema",
+		"RoleModifySchema",
+		"TemplateCreateSchema",
+		"TemplateModifySchema",
+		"UserModifySchema",
+		"UserSettingsSchema",
+		"WidgetModifySchema"
+	];
+
+	// @ts-ignore
+	const definitions = combineSchemas({ schemas, generator, program });
+
+	for (const key in definitions) {
+		specification.components.requestBodies[key] = {
+			content: {
+				"application/json": { schema: definitions[key] }
+			},
+			description: ""
+		};
+
+		delete definitions[key].additionalProperties;
+		delete definitions[key].$schema;
+	}
+}
+
+function addDefaultResponses() {
+	Object.values(specification.paths).forEach((path: any) =>
+		Object.values(path).forEach((request: any) => {
+			if (!request.responses?.["401"]) {
+				request.responses["401"] = {
+					description: "Unauthorized",
+					content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } }
+				};
+			}
+			if (!request.responses?.["429"]) {
+				request.responses["429"] = {
+					description: "Rate limit exceeded",
+					content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } },
+					headers: {
+						"X-RateLimit-Bucket": {
+							description:
+								"A unique string denoting the rate limit being encountered (non-inclusive of major parameters in the route path)",
+							schema: { type: "string" }
+						},
+						"X-Rate-Limit-Limit": {
+							description: "The number of allowed requests in the current period",
+							schema: {
+								type: "integer"
+							}
+						},
+						"X-Rate-Limit-Remaining": {
+							description: "The number of remaining requests in the current period",
+							schema: {
+								type: "integer"
+							}
+						},
+						"X-Rate-Limit-Reset": {
+							description: "Date when current period is over in seconds since the Unix epoch",
+							schema: {
+								type: "integer"
+							}
+						},
+						"X-Rate-Limit-Reset-After": {
+							description: "Number of seconds when current period will reset (can have decimal)",
+							schema: {
+								type: "number"
+							}
+						},
+						"Retry-After": {
+							description: "Same as X-Rate-Limit-Reset-After but an integer",
+							schema: {
+								type: "integer"
+							}
+						},
+						"X-RateLimit-Global": {
+							description: "Indicates whether or not all requests from your ip are rate limited",
+							schema: {
+								type: "boolean"
+							}
+						}
+					}
+				};
+			}
+		})
+	);
+}
+
+function main() {
+	addDefaultResponses();
+	generateSchemas();
+	specification = JSON.parse(JSON.stringify(specification).replaceAll("#/definitions", "#/components/schemas"));
+
+	generateBodies();
+
+	fs.writeFileSync(
+		openapiPath,
+		JSON.stringify(specification, null, 4).replaceAll("#/definitions", "#/components/requestBodies").replaceAll("bigint", "number")
+	);
+}
+
+main();
diff --git a/api/src/schema/Emoji.ts b/api/src/schema/Emoji.ts
index deaccf5c..0406919c 100644
--- a/api/src/schema/Emoji.ts
+++ b/api/src/schema/Emoji.ts
@@ -1,14 +1,13 @@
 // https://discord.com/developers/docs/resources/emoji
 
-
 export const EmojiCreateSchema = {
 	name: String, //name of the emoji
 	image: String, // image data the 128x128 emoji image uri
-	roles: Array //roles allowed to use this emoji
+	$roles: Array //roles allowed to use this emoji
 };
 
 export interface EmojiCreateSchema {
 	name: string; // name of the emoji
 	image: string; // image data the 128x128 emoji image uri
-	roles: []; //roles allowed to use this emoji
+	roles?: string[]; //roles allowed to use this emoji
 }
diff --git a/api/src/schema/Guild.ts b/api/src/schema/Guild.ts
index 3e98fe76..0f9fd884 100644
--- a/api/src/schema/Guild.ts
+++ b/api/src/schema/Guild.ts
@@ -48,7 +48,7 @@ export interface GuildUpdateSchema extends Omit<GuildCreateSchema, "channels"> {
 	banner?: string;
 	splash?: string;
 	description?: string;
-	features?: [string];
+	features?: string[];
 	verification_level?: number;
 	default_message_notifications?: number;
 	system_channel_flags?: number;
diff --git a/api/src/schema/Invite.ts b/api/src/schema/Invite.ts
index a22449ba..da6192bc 100644
--- a/api/src/schema/Invite.ts
+++ b/api/src/schema/Invite.ts
@@ -10,13 +10,13 @@ export const InviteCreateSchema = {
 	$target_user_type: Number
 };
 export interface InviteCreateSchema {
-	target_user_id?: String;
-	target_type?: String;
-	validate?: String; //? wtf is this
-	max_age?: Number;
-	max_uses?: Number;
-	temporary?: Boolean;
-	unique?: Boolean;
-	target_user?: String;
-	target_user_type?: Number;
+	target_user_id?: string;
+	target_type?: string;
+	validate?: string; //? wtf is this
+	max_age?: number;
+	max_uses?: number;
+	temporary?: boolean;
+	unique?: boolean;
+	target_user?: string;
+	target_user_type?: number;
 }
diff --git a/api/src/schema/index.ts b/api/src/schema/index.ts
new file mode 100644
index 00000000..b5f38a2f
--- /dev/null
+++ b/api/src/schema/index.ts
@@ -0,0 +1,11 @@
+export * from "./Ban";
+export * from "./Channel";
+export * from "./Emoji";
+export * from "./Guild";
+export * from "./Invite";
+export * from "./Member";
+export * from "./Message";
+export * from "./Roles";
+export * from "./Template";
+export * from "./User";
+export * from "./Widget";