diff --git a/assets/openapi.json b/assets/openapi.json
index 23da8478..c7d9c6f0 100644
--- a/assets/openapi.json
+++ b/assets/openapi.json
@@ -7367,6 +7367,112 @@
}
}
},
+ "SpacebarWellKnownLegacyResponse": {
+ "type": "object",
+ "properties": {
+ "api": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "api"
+ ]
+ },
+ "SpacebarWellKnownClientResponse": {
+ "type": "object",
+ "properties": {
+ "api": {
+ "type": "object",
+ "properties": {
+ "baseUrl": {
+ "type": "string"
+ },
+ "apiVersions": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string"
+ },
+ "active": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "active",
+ "default"
+ ]
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "apiVersions",
+ "baseUrl"
+ ]
+ },
+ "cdn": {
+ "type": "object",
+ "properties": {
+ "baseUrl": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "baseUrl"
+ ]
+ },
+ "gateway": {
+ "type": "object",
+ "properties": {
+ "baseUrl": {
+ "type": "string"
+ },
+ "encoding": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "compression": {
+ "type": "array",
+ "items": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "baseUrl",
+ "compression",
+ "encoding"
+ ]
+ },
+ "admin": {
+ "type": "object",
+ "properties": {
+ "baseUrl": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "baseUrl"
+ ]
+ }
+ },
+ "required": [
+ "api",
+ "cdn",
+ "gateway"
+ ]
+ },
"ApplicationCommandOption": {
"type": "object",
"properties": {
@@ -15191,6 +15297,12 @@
},
"tags": [
{
+ "name": ""
+ },
+ {
+ "name": "_spacebar"
+ },
+ {
"name": "-"
},
{
@@ -15248,6 +15360,9 @@
"name": "guilds"
},
{
+ "name": "healthz"
+ },
+ {
"name": "hub-waitlist"
},
{
@@ -15275,6 +15390,9 @@
"name": "read-states"
},
{
+ "name": "readyz"
+ },
+ {
"name": "reporting"
},
{
@@ -15290,6 +15408,9 @@
"name": "stage-instances"
},
{
+ "name": "static"
+ },
+ {
"name": "sticker-packs"
},
{
@@ -15314,6 +15435,9 @@
"name": "users"
},
{
+ "name": "verify-email"
+ },
+ {
"name": "voice"
},
{
@@ -15321,6 +15445,9 @@
},
{
"name": "webhooks"
+ },
+ {
+ "name": "widget"
}
],
"paths": {
@@ -21488,9 +21615,7 @@
"/guilds/{guild_id}/shield.svg/": {
"get": {
"security": [
- {
- "bearer": []
- }
+ {}
],
"responses": {
"200": {
@@ -29433,6 +29558,273 @@
}
]
}
+ },
+ "/widget/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "widget"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/verify-email/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "verify-email"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/static/logo.png/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "static"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/readyz/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "readyz"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ ""
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/healthz/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "healthz"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/_spacebar/api/version/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "_spacebar"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/_spacebar/api/v1/integrations/gif/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "_spacebar"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/_spacebar/api/schemas.json/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "_spacebar"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/_spacebar/api/openapi.json/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "default": {
+ "description": "No description available"
+ }
+ },
+ "tags": [
+ "_spacebar"
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/.well-known/spacebar/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "deprecated": true,
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SpacebarWellKnownLegacyResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ ""
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
+ },
+ "/.well-known/spacebar/client/": {
+ "get": {
+ "security": [
+ {}
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SpacebarWellKnownClientResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ ""
+ ],
+ "x-badges": [
+ {
+ "label": "Spacebar-only",
+ "color": "red"
+ }
+ ]
+ }
}
}
}
\ No newline at end of file
diff --git a/assets/schemas.json b/assets/schemas.json
index 97ea6b1b..8879a307 100644
--- a/assets/schemas.json
+++ b/assets/schemas.json
@@ -7855,6 +7855,116 @@
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
+ "SpacebarWellKnownLegacyResponse": {
+ "type": "object",
+ "properties": {
+ "api": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "api"
+ ],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "SpacebarWellKnownClientResponse": {
+ "type": "object",
+ "properties": {
+ "api": {
+ "type": "object",
+ "properties": {
+ "baseUrl": {
+ "type": "string"
+ },
+ "apiVersions": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string"
+ },
+ "active": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "active",
+ "default"
+ ]
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "apiVersions",
+ "baseUrl"
+ ]
+ },
+ "cdn": {
+ "type": "object",
+ "properties": {
+ "baseUrl": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "baseUrl"
+ ]
+ },
+ "gateway": {
+ "type": "object",
+ "properties": {
+ "baseUrl": {
+ "type": "string"
+ },
+ "encoding": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "compression": {
+ "type": "array",
+ "items": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "baseUrl",
+ "compression",
+ "encoding"
+ ]
+ },
+ "admin": {
+ "type": "object",
+ "properties": {
+ "baseUrl": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "baseUrl"
+ ]
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "api",
+ "cdn",
+ "gateway"
+ ],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
"ApplicationCommandOption": {
"type": "object",
"properties": {
diff --git a/src/api/routes_toplevel/%2Ewell-known/spacebar/client.ts b/src/api/routes_toplevel/%2Ewell-known/spacebar/client.ts
index daed64f6..d210709a 100644
--- a/src/api/routes_toplevel/%2Ewell-known/spacebar/client.ts
+++ b/src/api/routes_toplevel/%2Ewell-known/spacebar/client.ts
@@ -19,6 +19,7 @@
import { Router, Response, Request } from "express";
import { route } from "@spacebar/api/middlewares";
import { Config } from "@spacebar/util";
+import { SpacebarWellKnownClientResponse } from "@spacebar/schemas/api/spacebar/WellKnown";
const router = Router({ mergeParams: true });
@@ -27,21 +28,26 @@ router.get(
route({
spacebarOnly: true,
authentication: "never",
+ responses: {
+ 200: {
+ body: "SpacebarWellKnownClientResponse",
+ },
+ },
}),
(req: Request, res: Response) => {
res.json({
api: {
- baseUrl: Config.get().api.endpointPublic?.split("/api/")[0],
+ baseUrl: Config.get().api.endpointPublic!.split("/api/")[0],
apiVersions: {
default: Config.get().api.defaultVersion,
active: Config.get().api.activeVersions,
},
},
cdn: {
- baseUrl: Config.get().cdn.endpointPublic,
+ baseUrl: Config.get().cdn.endpointPublic!,
},
gateway: {
- baseUrl: Config.get().gateway.endpointPublic,
+ baseUrl: Config.get().gateway.endpointPublic!,
encoding: ["etf", "json"],
compression: ["zstd-stream", "zlib-stream", null],
},
@@ -49,9 +55,9 @@ router.get(
Config.get().admin.endpointPublic === null
? undefined
: {
- baseUrl: Config.get().admin.endpointPublic,
+ baseUrl: Config.get().admin.endpointPublic!,
},
- });
+ } satisfies SpacebarWellKnownClientResponse);
},
);
diff --git a/src/api/routes_toplevel/%2Ewell-known/spacebar/index.ts b/src/api/routes_toplevel/%2Ewell-known/spacebar/index.ts
index 1a596136..472571e5 100644
--- a/src/api/routes_toplevel/%2Ewell-known/spacebar/index.ts
+++ b/src/api/routes_toplevel/%2Ewell-known/spacebar/index.ts
@@ -19,6 +19,7 @@
import { Router, Response, Request } from "express";
import { route } from "@spacebar/api/middlewares";
import { Config } from "@spacebar/util";
+import { SpacebarWellKnownLegacyResponse } from "@spacebar/schemas/api/spacebar/WellKnown";
const router = Router({ mergeParams: true });
@@ -28,11 +29,16 @@ router.get(
spacebarOnly: true,
authentication: "never",
deprecated: true,
+ responses: {
+ 200: {
+ body: "SpacebarWellKnownLegacyResponse",
+ },
+ },
}),
(req: Request, res: Response) => {
res.json({
api: (Config.get().api.endpointPublic + "/api/").replace("//api/", "/api/"),
- });
+ } satisfies SpacebarWellKnownLegacyResponse);
},
);
diff --git a/src/schemas/api/spacebar/WellKnown.ts b/src/schemas/api/spacebar/WellKnown.ts
new file mode 100644
index 00000000..cc21f5d8
--- /dev/null
+++ b/src/schemas/api/spacebar/WellKnown.ts
@@ -0,0 +1,42 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2026 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+export interface SpacebarWellKnownLegacyResponse {
+ api: string;
+}
+
+export interface SpacebarWellKnownClientResponse {
+ api: {
+ baseUrl: string;
+ apiVersions: {
+ default: string;
+ active: string[];
+ };
+ };
+ cdn: {
+ baseUrl: string;
+ };
+ gateway: {
+ baseUrl: string;
+ encoding: string[];
+ compression: (string | null)[];
+ };
+ admin?: {
+ baseUrl: string;
+ };
+}
|