Phase 3: surface the new board data on existing character/user pages. - Character sheet: render the char.profile titles block (fame/karma + skill + selected reward title; numeric clilocs skipped since the site has no cliloc table yet), plus "Guildmaster" and "Governor of <city>" chips. - Char profile enrichment (player/admin /shard/char/:serial, one shared path): attach guild + governorOf from our own boards. Guild is LEADERSHIP-ONLY — it's verifiable from current board state, whereas guessing membership from stale guild.join events risks showing a wrong guild, so we return null instead. - Admin user detail (/admin/users/:id): new "Standing" section (governorships held + guilds led) via GET /users/:id/shard/standing; Houses rows now show the registry fields (decay level, placement price, co-owner/friend counts) already returned by listHousesForAccounts. Server 179/179, client build clean, swagger regenerated. Refs .plans/protocol2-integration.md (Phase 3). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
12496 lines
324 KiB
JSON
12496 lines
324 KiB
JSON
{
|
||
"openapi": "3.0.0",
|
||
"info": {
|
||
"title": "UOMysticmoon API",
|
||
"version": "1.0.0",
|
||
"description": "REST API for the UOMysticmoon website, wiki and admin panel — a private Ultima Online shard.\n\n### Authentication\n- **Web / admin panel** uses an httpOnly session cookie (`uomm_token`) issued by `POST /api/v1/auth/login` (plus `/login/totp` when 2FA is enabled).\n- **Native / mobile clients** use bearer access tokens from `POST /api/v1/auth/mobile/login`, refreshed via `/auth/mobile/refresh`.\n\nEndpoints under `/api/v1/admin/**` require a valid session; some are further restricted to the `admin` role (editors are limited to content)."
|
||
},
|
||
"servers": [
|
||
{
|
||
"url": "/",
|
||
"description": "Same-origin (current host)"
|
||
},
|
||
{
|
||
"url": "http://localhost:3000",
|
||
"description": "Local development"
|
||
}
|
||
],
|
||
"tags": [
|
||
{
|
||
"name": "Health",
|
||
"description": "Liveness probe"
|
||
},
|
||
{
|
||
"name": "Auth",
|
||
"description": "Web session login/logout (cookie + TOTP)"
|
||
},
|
||
{
|
||
"name": "Auth · Mobile",
|
||
"description": "Native bearer-token login, refresh and logout"
|
||
},
|
||
{
|
||
"name": "Auth · SSO",
|
||
"description": "OAuth2 / OIDC provider discovery and redirect flow"
|
||
},
|
||
{
|
||
"name": "Public",
|
||
"description": "Unauthenticated site content (settings, posts, wiki, contact)"
|
||
},
|
||
{
|
||
"name": "Public · Shard",
|
||
"description": "Live shard data ingested from the uo-link sidecar (status, feed, economy, IDOC, characters)"
|
||
},
|
||
{
|
||
"name": "Admin · Account",
|
||
"description": "Self-service account security (2FA, linked identities)"
|
||
},
|
||
{
|
||
"name": "Player",
|
||
"description": "Self-service player accounts (register, credentials, 2FA, linked identities)"
|
||
},
|
||
{
|
||
"name": "Player · Shard",
|
||
"description": "Link an in-game account and read its roster / vendors (uo-link)"
|
||
},
|
||
{
|
||
"name": "Admin · Dashboard",
|
||
"description": "Dashboard summary and site mode"
|
||
},
|
||
{
|
||
"name": "Admin · Posts",
|
||
"description": "News / five-on-friday / newsletter / screenshots + uploads"
|
||
},
|
||
{
|
||
"name": "Admin · Wiki",
|
||
"description": "Wiki pages, categories, tags and revisions"
|
||
},
|
||
{
|
||
"name": "Admin · Settings",
|
||
"description": "Site settings (admin only)"
|
||
},
|
||
{
|
||
"name": "Admin · Activity",
|
||
"description": "Admin activity log"
|
||
},
|
||
{
|
||
"name": "Admin · Bot Activity",
|
||
"description": "Bot-scoring/ban state and emergency unban (admin only)"
|
||
},
|
||
{
|
||
"name": "Admin · Discord Bot",
|
||
"description": "Discord bot token/config and live status (admin only)"
|
||
},
|
||
{
|
||
"name": "Admin · Shard",
|
||
"description": "uo-link sidecar connection config, live status and town crier (admin only)"
|
||
},
|
||
{
|
||
"name": "Admin · Auth Providers",
|
||
"description": "SSO provider configuration (admin only)"
|
||
},
|
||
{
|
||
"name": "Admin · Users",
|
||
"description": "User management (admin only)"
|
||
}
|
||
],
|
||
"paths": {
|
||
"/api/health": {
|
||
"get": {
|
||
"tags": [
|
||
"Health"
|
||
],
|
||
"summary": "Liveness probe",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Service is up",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"status": {
|
||
"type": "string",
|
||
"example": "ok"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/login": {
|
||
"post": {
|
||
"tags": [
|
||
"Auth"
|
||
],
|
||
"summary": "Log in with username and password",
|
||
"description": "On success sets the httpOnly session cookie. If the account has 2FA enabled, returns { totpRequired, challenge } instead and no cookie is set — complete login at POST /login/totp. Rate limited and behind bot/backoff guards.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Session issued, or TOTP challenge required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/LoginResponse"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Incorrect username or password",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"429": {
|
||
"description": "Too many attempts (rate limited / backoff)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/LoginRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/register": {
|
||
"post": {
|
||
"tags": [
|
||
"Auth"
|
||
],
|
||
"summary": "Register a player account",
|
||
"description": "Creates a self-service player account and logs it in (sets the session cookie). Available only when an admin has enabled password registration (player_registration = password|both); otherwise returns 403. Rate limited and behind bot/backoff guards; a hidden honeypot field must stay empty.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Account created and session issued",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/LoginResponse"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error or unavailable username",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Registration is not open",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Username already taken",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"429": {
|
||
"description": "Too many attempts (rate limited / backoff)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/RegisterRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/login/totp": {
|
||
"post": {
|
||
"tags": [
|
||
"Auth"
|
||
],
|
||
"summary": "Complete login with a TOTP code",
|
||
"description": "Second step for 2FA accounts. Exchange the challenge from /login plus the current authenticator code for a session cookie.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Session issued",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/LoginResponse"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Invalid code or expired challenge",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"429": {
|
||
"description": "Too many attempts (rate limited / backoff)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpLoginRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/logout": {
|
||
"post": {
|
||
"tags": [
|
||
"Auth"
|
||
],
|
||
"summary": "Log out (clear the cookie and revoke this session)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Logged out",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Message"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/me": {
|
||
"get": {
|
||
"tags": [
|
||
"Auth"
|
||
],
|
||
"summary": "Current authenticated user",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "The signed-in user",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"user": {
|
||
"$ref": "#/components/schemas/User"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/auth/mobile/login": {
|
||
"post": {
|
||
"tags": [
|
||
"Auth · Mobile"
|
||
],
|
||
"summary": "Native login → access + refresh tokens",
|
||
"description": "Bearer-token login for native clients. Single-request 2FA: if the account has TOTP on and no/invalid code is supplied, returns 401 { totpRequired: true } and the client retries with a code.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Access + refresh tokens",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/MobileTokenResponse"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Invalid credentials, or a TOTP code is required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"429": {
|
||
"description": "Too many attempts (rate limited / backoff)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/MobileLoginRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/mobile/refresh": {
|
||
"post": {
|
||
"tags": [
|
||
"Auth · Mobile"
|
||
],
|
||
"summary": "Rotate a refresh token for a fresh token pair",
|
||
"description": "Refresh tokens are single-use: the presented token is revoked and a new access + refresh pair is issued. Reusing a rotated token fails with 401.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "New access + refresh tokens",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/MobileTokenResponse"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Invalid or expired session",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"429": {
|
||
"description": "Too many refresh attempts",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/MobileRefreshRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/mobile/logout": {
|
||
"post": {
|
||
"tags": [
|
||
"Auth · Mobile"
|
||
],
|
||
"summary": "Revoke the current (or all) refresh tokens",
|
||
"description": "Requires a valid bearer access token. Revokes the given refresh token, or every session for the user when { all: true }. Idempotent.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Logged out",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Message"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Missing or invalid bearer token",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/MobileLogoutRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/providers": {
|
||
"get": {
|
||
"tags": [
|
||
"Auth · SSO"
|
||
],
|
||
"summary": "List enabled SSO providers",
|
||
"description": "Public discovery used by the login page to render provider buttons. Never exposes secrets.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Enabled, valid providers",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/Provider"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/sso/{provider}/start": {
|
||
"get": {
|
||
"tags": [
|
||
"Auth · SSO"
|
||
],
|
||
"summary": "Begin SSO login (redirect to the IdP)",
|
||
"description": "Sets a short-lived signed transaction cookie and 302-redirects to the provider authorize URL. On error redirects back to the login page with an sso_error query param.",
|
||
"parameters": [
|
||
{
|
||
"name": "provider",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Provider id (e.g. google, discord)."
|
||
},
|
||
{
|
||
"name": "returnTo",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Internal /admin path to return to after login."
|
||
}
|
||
],
|
||
"responses": {
|
||
"302": {
|
||
"description": "Redirect to the identity provider (or back to the login page on error)"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/sso/{provider}/link": {
|
||
"get": {
|
||
"tags": [
|
||
"Auth · SSO"
|
||
],
|
||
"summary": "Begin linking an SSO identity to the current account",
|
||
"description": "Requires an authenticated session; the signed transaction captures the acting user so the callback can attach the external identity.",
|
||
"parameters": [
|
||
{
|
||
"name": "provider",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Provider id (e.g. google, discord)."
|
||
}
|
||
],
|
||
"responses": {
|
||
"302": {
|
||
"description": "Redirect to the identity provider (or back to the account page on error)"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/auth/sso/{provider}/callback": {
|
||
"get": {
|
||
"tags": [
|
||
"Auth · SSO"
|
||
],
|
||
"summary": "OAuth redirect target — completes login or linking",
|
||
"description": "The provider redirects here with code + state. On success sets the session cookie (login) or links the identity (link), then 302-redirects into /admin. Login is link-only: unknown identities are refused (sso_error=not_linked).",
|
||
"parameters": [
|
||
{
|
||
"name": "provider",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Provider id (e.g. google, discord)."
|
||
},
|
||
{
|
||
"name": "error",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "code",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "OAuth authorization code."
|
||
},
|
||
{
|
||
"name": "state",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "OAuth state (matched against the tx cookie)."
|
||
}
|
||
],
|
||
"responses": {
|
||
"302": {
|
||
"description": "Redirect into /admin on success, or back to login/account with an error code"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/auth/sso/totp": {
|
||
"post": {
|
||
"tags": [
|
||
"Auth · SSO"
|
||
],
|
||
"summary": "Complete an SSO login with a TOTP code",
|
||
"description": "Second step when a linked account has 2FA enabled. Reads the staged pending-TOTP cookie set by the callback plus the current authenticator code, and on success sets the session cookie. Rate limited and behind bot/backoff guards.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Session issued",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"user": {
|
||
"$ref": "#/components/schemas/SafeUser"
|
||
},
|
||
"returnTo": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Invalid code or expired challenge",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"429": {
|
||
"description": "Too many attempts (rate limited / backoff)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"required": [
|
||
"code"
|
||
],
|
||
"properties": {
|
||
"code": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/settings": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "Public site settings",
|
||
"description": "Whitelisted, non-sensitive settings the client needs to render the site.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Key/value settings",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/status": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "Site mode / status",
|
||
"description": "Current site mode (live or maintenance) so the client can show the maintenance page.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Site status",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/PublicStatus"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/contact": {
|
||
"post": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "Send a contact message",
|
||
"description": "Emails the site owner (or falls back to a mailto). Rate limited.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Message sent",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Message"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"429": {
|
||
"description": "Too many messages (rate limited)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"502": {
|
||
"description": "Mail delivery failed",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ContactRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/posts/{category}": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "List published posts in a category",
|
||
"description": "Gated by site mode: during maintenance only admins with a valid session see content.",
|
||
"parameters": [
|
||
{
|
||
"name": "category",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "news | five-on-friday | newsletter | screenshots"
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Published posts",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/Post"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Unknown category",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/posts/{category}/{idOrSlug}": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "Get a single published post",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "category",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Post category."
|
||
},
|
||
{
|
||
"name": "idOrSlug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Numeric id or slug."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The post",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Post"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Unknown category or post not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/wiki": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "List published wiki pages",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "q",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "category",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "tag",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Published wiki pages",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/WikiPage"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/wiki/categories": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "List wiki categories",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Wiki categories",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/WikiCategory"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/wiki/tags": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "List wiki tags",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Wiki tags",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/wiki/{slug}": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "Get a single published wiki page",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Wiki page slug."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The wiki page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiPage"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/pages/{id}/preview/{token}": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "Render a page from a draft-preview token",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Page id."
|
||
},
|
||
{
|
||
"name": "token",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Preview token from POST /admin/pages/:id/preview."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The page (any status)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Token invalid/expired or page missing",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/pages/{slug}": {
|
||
"get": {
|
||
"tags": [
|
||
"Public"
|
||
],
|
||
"summary": "Get a published CMS page by slug",
|
||
"description": "Drafts 404 for the public; staff sessions see drafts. Gated by site mode.",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Page slug."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/status": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Shard connection state, online count and latest economy",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Shard status",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ShardStatus"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/feed": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Recent notable shard events (from the ingested log)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "kind",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Filter to a single event kind, e.g. vendor.sale."
|
||
},
|
||
{
|
||
"name": "limit",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Max rows (default 100, max 1000)."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Events, newest first",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardEvent"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/economy": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Gold-supply time series (oldest → newest)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "limit",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Max samples (default 100, max 1000)."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Economy samples",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardEconomyPoint"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/online": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Staff online now (linked staff accounts; name + serial + map only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Online players",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardOnlinePlayer"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/idoc": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Houses currently in danger (IDOC)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "IDOC houses",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardHouse"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/champs": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Current champion-spawn board (all categories)",
|
||
"description": "The live board of every champion / mini-champ / sea-boss spawn. Update in place via the champ.update / champ.remove frames on /shard/stream.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Champion spawns, ordered by name",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/guilds": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Current guild board (rosters, alliances, leaders)",
|
||
"description": "The live board of every guild. Update in place via the guild.update / guild.remove / guild.join frames on /shard/stream.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Guilds, ordered by name",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/governors": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Current town-governor board (City Loyalty)",
|
||
"description": "One entry per city with its governor and election phase. Empty if the shard does not run the City Loyalty system. Live via city.update on /shard/stream.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Cities, ordered by name",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/governors/{city}/history": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Governor term history for a city",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "city",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "City name, e.g. Britain."
|
||
},
|
||
{
|
||
"name": "limit",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Max terms (default 100, max 500)."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Terms, newest first",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/presence": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Online population aggregate (count + per-facet + per-region)",
|
||
"description": "The latest presence.online snapshot powering the \"Players Online\" widget. Live via presence.online on /shard/stream.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Population snapshot",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/houses": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "House registry (owner, co-owners, price, decay)",
|
||
"description": "Every house seen via the house.update registry feed. `price` is the placement value, not a for-sale flag. Live via house.update / house.remove on /shard/stream.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Houses, ordered by name",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardHouse"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/public/shard/stream": {
|
||
"get": {
|
||
"tags": [
|
||
"Public · Shard"
|
||
],
|
||
"summary": "Live shard event stream (Server-Sent Events, public/safe kinds)",
|
||
"description": "text/event-stream of curated live events. Sensitive kinds (staff audit, cheat detection, login attempts, IPs) are NOT sent on this channel.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "An SSE stream (Content-Type: text/event-stream)."
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/account": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Get the current account (self)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "The account",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/AccountStatus"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/account/totp/setup": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Begin 2FA enrollment (returns secret + QR)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "otpauth URL and QR data to scan",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpSetup"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Two-factor already enabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/account/totp/enable": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Enable 2FA by confirming a code",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "2FA enabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpState"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Setup not started, or invalid code",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Two-factor already enabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpCodeRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/account/totp/disable": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Disable 2FA by confirming a code",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "2FA disabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpState"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Not enabled, or invalid code",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpCodeRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/account/identities": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "List linked SSO identities (self)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Linked identities",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/LinkedIdentity"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/account/identities/{provider}": {
|
||
"delete": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Unlink an SSO identity (self)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "provider",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Provider id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Unlinked",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/UnlinkedFlag"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "No linked account for that provider",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/link": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Link an in-game account with a one-time code (self)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Linked",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ShardLinkResult"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Unknown or expired code",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"502": {
|
||
"description": "Bad Gateway"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ShardLinkRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/accounts": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "List the caller’s linked game accounts (self)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Linked accounts",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardLink"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/roster/{account}": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Character roster for an account (self; admins: any account)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "account",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "A game account linked to the caller."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Account roster",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"403": {
|
||
"description": "Account not linked to the caller",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/vendors/{account}": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Player vendors for an account (self; admins: any account)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "account",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "A game account linked to the caller."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Vendor snapshot",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"403": {
|
||
"description": "Account not linked to the caller",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/char/{serial}": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Character sheet (self-linked characters; admins: any character)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "serial",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Mobile serial, e.g. 0x24C."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Character profile",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"403": {
|
||
"description": "Character not on an account linked to the caller",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not Found"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"502": {
|
||
"description": "Bad Gateway"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/sales": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Account"
|
||
],
|
||
"summary": "Recent player-vendor sales for the caller’s linked accounts (self)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Vendor sales",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardVendorSale"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/kick": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Kick every live session of an account (admin/moderator)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Kicked",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"403": {
|
||
"description": "Protected target or write plane disabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"account": {
|
||
"type": "string"
|
||
},
|
||
"serial": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/ban": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Ban an account, timed or indefinite (admin/moderator)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Banned",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"403": {
|
||
"description": "Protected target or write plane disabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"account": {
|
||
"type": "string"
|
||
},
|
||
"serial": {
|
||
"type": "string"
|
||
},
|
||
"durationSec": {
|
||
"type": "integer"
|
||
},
|
||
"reason": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/unban": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Clear an account ban (admin/moderator)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Unbanned",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"account": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"required": [
|
||
"account"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/broadcast": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Broadcast a system message to everyone online (admin/moderator)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Broadcast",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"text": {
|
||
"type": "string"
|
||
},
|
||
"hue": {
|
||
"type": "integer"
|
||
}
|
||
},
|
||
"required": [
|
||
"text"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/pages": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Open help-page (support) queue (admin/moderator)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Open pages",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/pages/{id}/respond": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Reply to a help page, optionally closing it (admin/moderator)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Page id (sender serial)."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Responded",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Unknown page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"message": {
|
||
"type": "string"
|
||
},
|
||
"close": {
|
||
"type": "boolean"
|
||
}
|
||
},
|
||
"required": [
|
||
"message"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/pages/{id}/close": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Resolve a help page without a reply (admin/moderator)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Page id (sender serial)."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Closed",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/shard/audit": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Recent in-game moderation audit events (admin/moderator)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "limit",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "admin.audit events, newest first",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardEvent"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/dashboard": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Dashboard"
|
||
],
|
||
"summary": "Dashboard summary counts",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Summary: site mode, last change, post/user counts and recent activity",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"site_mode": {
|
||
"type": "string",
|
||
"example": "live"
|
||
},
|
||
"last_change": {
|
||
"type": "object",
|
||
"properties": {
|
||
"at": {
|
||
"type": "string",
|
||
"nullable": true
|
||
},
|
||
"by": {
|
||
"type": "string",
|
||
"nullable": true
|
||
}
|
||
}
|
||
},
|
||
"counts": {
|
||
"type": "object",
|
||
"properties": {
|
||
"posts": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
},
|
||
"users": {
|
||
"type": "integer"
|
||
}
|
||
}
|
||
},
|
||
"recent_activity": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/site-mode": {
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Dashboard"
|
||
],
|
||
"summary": "Set site mode (admin only)",
|
||
"description": "Switch the site between live and maintenance.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated site mode",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/SiteModeState"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/SiteModeRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/posts": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "List all posts (including unpublished)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "category",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Optional category filter."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Posts",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/Post"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Create a post",
|
||
"description": "",
|
||
"responses": {
|
||
"201": {
|
||
"description": "Created post",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Post"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error or unknown category",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/PostCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/posts/upload": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Upload a post image (multipart)",
|
||
"description": "",
|
||
"responses": {
|
||
"201": {
|
||
"description": "Stored image URL",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"image_url": {
|
||
"type": "string",
|
||
"example": "/uploads/1700000000-abcd.png"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "No image / disallowed type",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"multipart/form-data": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"image": {
|
||
"type": "string",
|
||
"format": "binary"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/uploads": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Upload an image for rich-text editors (multipart)",
|
||
"description": "",
|
||
"responses": {
|
||
"201": {
|
||
"description": "Stored file URL",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/UploadResponse"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "No file / disallowed type",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"multipart/form-data": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"image": {
|
||
"type": "string",
|
||
"format": "binary"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/posts/{id}": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Get a post by id",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Post id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The post",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Post"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Update a post",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Post id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated post",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Post"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error or unknown category",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/PostCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"delete": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Delete a post",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Post id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Deleted (echoes the id)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/DeletedId"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/posts/{id}/publish": {
|
||
"patch": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Publish / unpublish a post",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Post id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated post",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Post"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/PublishRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/posts/{id}/announce": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Get the announcement pipeline status for a post",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Post id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The announce job for the post, or null if never announced",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"nullable": true,
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/posts/{id}/announce/retry": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Posts"
|
||
],
|
||
"summary": "Retry one announcement delivery leg (town crier or Discord)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Post id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated announce job",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "No announcement job for this post",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"leg": {
|
||
"type": "string",
|
||
"enum": [
|
||
"towncrier",
|
||
"discord"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"leg"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki/categories": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "List wiki categories",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Wiki categories",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/WikiCategory"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Create a wiki category",
|
||
"description": "",
|
||
"responses": {
|
||
"201": {
|
||
"description": "Created category",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiCategory"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Slug already exists",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiCategoryCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki/categories/{id}": {
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Update a wiki category",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Category id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated category",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiCategory"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Slug already exists",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiCategoryCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"delete": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Delete a wiki category",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Category id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Deleted (echoes the id)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/DeletedId"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki/tags": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "List wiki tags",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Wiki tags",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "List all wiki pages (including unpublished)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "q",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "category",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "tag",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "status",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Wiki pages",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/WikiPage"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Create a wiki page",
|
||
"description": "",
|
||
"responses": {
|
||
"201": {
|
||
"description": "Created wiki page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiPage"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error or unknown category",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Slug already exists",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiPageCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki/{slug}": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Get a wiki page by slug",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Wiki page slug."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The wiki page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiPage"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Update a wiki page (creates a revision)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Wiki page slug."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated wiki page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiPage"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error or unknown category",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/components/schemas/WikiPageCreateRequest"
|
||
},
|
||
{
|
||
"type": "object",
|
||
"properties": {
|
||
"change_note": {
|
||
"type": "string",
|
||
"maxLength": 280
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"delete": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Delete a wiki page",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Wiki page slug."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Deleted (echoes the slug)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/DeletedSlug"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki/{slug}/publish": {
|
||
"patch": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Publish / unpublish a wiki page",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Wiki page slug."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated wiki page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiPage"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/PublishRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki/{slug}/revisions": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "List revisions of a wiki page",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Wiki page slug."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Revisions",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki/{slug}/revisions/{id}": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Get a single wiki revision",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Wiki page slug."
|
||
},
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Revision id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The revision",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/wiki/{slug}/revisions/{id}/restore": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Wiki"
|
||
],
|
||
"summary": "Restore a wiki page to a revision",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "slug",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Wiki page slug."
|
||
},
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Revision id to restore."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Restored wiki page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/WikiPage"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/pages": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Pages"
|
||
],
|
||
"summary": "List all CMS pages (summaries)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Page summaries",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Pages"
|
||
],
|
||
"summary": "Create a CMS page",
|
||
"description": "",
|
||
"responses": {
|
||
"201": {
|
||
"description": "Created page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Invalid slug / title / blocks / metadata / settings",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Slug already exists",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"slug": {
|
||
"type": "string"
|
||
},
|
||
"title": {
|
||
"type": "string"
|
||
},
|
||
"status": {
|
||
"type": "string",
|
||
"enum": [
|
||
"draft",
|
||
"published"
|
||
]
|
||
},
|
||
"blocks": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object"
|
||
}
|
||
},
|
||
"metadata": {
|
||
"type": "object"
|
||
},
|
||
"settings": {
|
||
"type": "object"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/pages/{id}": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Pages"
|
||
],
|
||
"summary": "Get a CMS page by id (full, incl. blocks)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Page id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"patch": {
|
||
"tags": [
|
||
"Admin · Pages"
|
||
],
|
||
"summary": "Update a CMS page (title, status, blocks, metadata, settings)",
|
||
"description": "slug is immutable; disabling protection is rejected here (use /unprotect).",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Page id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated page",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error (slug immutable, invalid blocks, etc.)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Disabling protection requires /unprotect",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"delete": {
|
||
"tags": [
|
||
"Admin · Pages"
|
||
],
|
||
"summary": "Delete a CMS page (blocked if protected)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Page id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Deleted (echoes the id)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/DeletedId"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"403": {
|
||
"description": "Page is protected",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/pages/{id}/unprotect": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Pages"
|
||
],
|
||
"summary": "Disable page protection (password step-up re-auth)",
|
||
"description": "Verifies the current admin password server-side, then flips protected → false.",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Page id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated page (protected=false)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Password incorrect",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"password": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"required": [
|
||
"password"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/pages/{id}/preview": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Pages"
|
||
],
|
||
"summary": "Mint a 1h draft-preview link for a page",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Page id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Preview token + path",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"token": {
|
||
"type": "string"
|
||
},
|
||
"expiresInSeconds": {
|
||
"type": "integer"
|
||
},
|
||
"path": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/settings": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Settings"
|
||
],
|
||
"summary": "Get all site settings (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "All settings",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Settings"
|
||
],
|
||
"summary": "Update site settings (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated settings",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Body must be an object of key/value settings",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true,
|
||
"description": "An object of key/value settings."
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/activity": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Activity"
|
||
],
|
||
"summary": "List recent admin activity",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "offset",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "limit",
|
||
"in": "query",
|
||
"required": false,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "Max rows to return."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Activity entries",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/bot-activity": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Bot Activity"
|
||
],
|
||
"summary": "Bot-scoring / ban state and recent events (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Banned IPs, scores and recent events",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/bot-activity/unban": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Bot Activity"
|
||
],
|
||
"summary": "Emergency unban an IP (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Unbanned (echoes the ip and whether an entry was cleared)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/UnbanResult"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Invalid IP",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/UnbanRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/discord-bot/config": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Discord Bot"
|
||
],
|
||
"summary": "Get Discord bot config + live status (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Masked config + live status",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Discord Bot"
|
||
],
|
||
"summary": "Save Discord bot config (admin only)",
|
||
"description": "token is write-only — omit/blank it to keep the existing one unchanged.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated config + live status",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error, invalid token, or missing token while enabling",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"guildId": {
|
||
"type": "string"
|
||
},
|
||
"token": {
|
||
"type": "string"
|
||
},
|
||
"enabled": {
|
||
"type": "boolean"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/email/config": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Email"
|
||
],
|
||
"summary": "Get email delivery config + status (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Config (refresh token stripped) + status",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Email"
|
||
],
|
||
"summary": "Update email delivery config (admin only)",
|
||
"description": "Set the From display name and enabled toggle. Enabling requires a connected Gmail account.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated config",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Cannot enable before connecting a mailbox",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"senderName": {
|
||
"type": "string"
|
||
},
|
||
"enabled": {
|
||
"type": "boolean"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/email/connect/start": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Email"
|
||
],
|
||
"summary": "Begin the Gmail OAuth2 connect flow (admin only)",
|
||
"description": "Returns { url } to redirect the browser to Google. Reuses the google SSO OAuth client.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Authorization URL",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"url": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Google OAuth client not configured",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/email/connect/callback": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Email"
|
||
],
|
||
"summary": "OAuth2 callback — stores the refresh token, redirects to Settings",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "code",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "state",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
{
|
||
"name": "error",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"302": {
|
||
"description": "Redirect back to /admin/settings"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/email/test": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Email"
|
||
],
|
||
"summary": "Send a test email (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Sent",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"sent": {
|
||
"type": "boolean"
|
||
},
|
||
"to": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"502": {
|
||
"description": "Send failed / not configured",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"to": {
|
||
"type": "string",
|
||
"format": "email"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/email/disconnect": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Email"
|
||
],
|
||
"summary": "Disconnect Gmail and disable email (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Disconnected config",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/auth/providers": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Auth Providers"
|
||
],
|
||
"summary": "List configured SSO providers (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Providers (secrets stripped)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ProviderConfig"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Auth Providers"
|
||
],
|
||
"summary": "Create a custom SSO provider (admin only)",
|
||
"description": "Built-in providers (google, discord) are configured via PUT, not created here.",
|
||
"responses": {
|
||
"201": {
|
||
"description": "Created provider",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ProviderConfig"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error, or a built-in/invalid kind",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Provider id already exists",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ProviderCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/auth/providers/{id}": {
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Auth Providers"
|
||
],
|
||
"summary": "Update an SSO provider (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Provider id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated provider",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ProviderConfig"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Provider not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ProviderCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"delete": {
|
||
"tags": [
|
||
"Admin · Auth Providers"
|
||
],
|
||
"summary": "Delete a custom SSO provider (admin only)",
|
||
"description": "Built-in providers cannot be deleted — disable them instead.",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Provider id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Deleted",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/DeletedFlag"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Built-in provider cannot be deleted",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Provider not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/stats/summary": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Moderation action counts for 24h/7d/30d (admin or moderator)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/recent": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Recent moderation actions, optionally filtered by type",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/search": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Look up moderated users by Discord id or username snapshot",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "q",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/members": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Recent member join/leave events (optionally filtered by type)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "type",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/filter-hits": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Recent automated content-filter hits",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/spam-hits": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Recent automated spam-detection hits",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/user/{discordId}": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Per-user moderation summary (counts, latest tag, linked account)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "discordId",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/user/{discordId}/actions": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Full moderation action history for a user",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "discordId",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/moderation/user/{discordId}/notes": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Staff notes for a user (admin_only notes hidden from moderators)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "discordId",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "OK"
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Moderation"
|
||
],
|
||
"summary": "Add a staff note (admin_only visibility requires the admin role)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "discordId",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"201": {
|
||
"description": "Created"
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"visibility": {
|
||
"example": "any"
|
||
},
|
||
"body": {
|
||
"example": "any"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/users": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "List users (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Users",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/User"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "Create a user (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"201": {
|
||
"description": "Created user",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/User"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Username already taken",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/UserCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/users/{id}": {
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "Update a user (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "User id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated user",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/User"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error, or cannot demote the last admin",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Username already taken",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/UserCreateRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"delete": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "Delete a user (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "User id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Deleted (echoes the id)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/DeletedId"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Cannot delete your own account or the last admin",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "Get a single user (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "User id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "The user",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/User"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/users/{id}/shard/accounts": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "A user’s linked game accounts (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "User id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Linked accounts",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardLink"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/users/{id}/shard/sales": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "Recent vendor sales on a user’s accounts (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "User id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Vendor sales",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardVendorSale"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/users/{id}/shard/houses": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "Houses owned by a user’s accounts (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "User id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Houses (IDOC first)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/users/{id}/shard/online": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "A user’s characters currently online (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "User id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Online characters",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/users/{id}/shard/standing": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Users"
|
||
],
|
||
"summary": "A user’s shard standing — governorships held and guilds led (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
},
|
||
"description": "User id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Standing { governorOf, guildsLed }",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Not found",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/uo-link/config": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Get uo-link config + live status + ingestion stats (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Masked config, health and ingestion stats",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
},
|
||
"put": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Save uo-link connection config (admin only)",
|
||
"description": "token is write-only — omit/blank it to keep the existing one. Saving (re)starts the WS ingest client.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated config + live status",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error, or missing token while enabling",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Admin role required",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"baseUrl": {
|
||
"type": "string"
|
||
},
|
||
"wsUrl": {
|
||
"type": "string"
|
||
},
|
||
"token": {
|
||
"type": "string"
|
||
},
|
||
"protocol": {
|
||
"type": "integer"
|
||
},
|
||
"enabled": {
|
||
"type": "boolean"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/uo-link/towncrier": {
|
||
"post": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Publish / replace a town-crier message (admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Posted",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Rejected (over caps)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"502": {
|
||
"description": "Bad Gateway"
|
||
},
|
||
"503": {
|
||
"description": "Shard unavailable",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TownCrierRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/admin/uo-link/towncrier/{id}": {
|
||
"delete": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Remove a town-crier message (admin only)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Town-crier message id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Removed",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"404": {
|
||
"description": "Unknown id",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"502": {
|
||
"description": "Bad Gateway"
|
||
},
|
||
"503": {
|
||
"description": "Service Unavailable"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/admin/uo-link/stream": {
|
||
"get": {
|
||
"tags": [
|
||
"Admin · Shard"
|
||
],
|
||
"summary": "Full live shard event stream incl. audit/cheat (SSE, admin only)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "An SSE stream (Content-Type: text/event-stream)."
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/player/account": {
|
||
"get": {
|
||
"tags": [
|
||
"Player"
|
||
],
|
||
"summary": "Get the current player account (self)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "The player account",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/PlayerAccount"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Not authenticated",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"403": {
|
||
"description": "Player role required, or account not active",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/player/account/username": {
|
||
"patch": {
|
||
"tags": [
|
||
"Player"
|
||
],
|
||
"summary": "Change the current player’s username",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Updated username (session cookie re-issued)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"username": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error or unavailable username",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ValidationError"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Player role required, or account not active",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"409": {
|
||
"description": "Username already taken",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"429": {
|
||
"description": "Too many changes (rate limited)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ChangeUsernameRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/player/account/password": {
|
||
"patch": {
|
||
"tags": [
|
||
"Player"
|
||
],
|
||
"summary": "Change or set the current player’s password",
|
||
"description": "If the account already has a password, currentPassword is required and verified. SSO-provisioned accounts with no password may set an initial one without a current password. On success the caller’s session is re-issued (they stay logged in) while all other sessions are revoked.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Password changed",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/OkFlag"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Validation error or wrong current password",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Player role required, or account not active",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"429": {
|
||
"description": "Too many changes (rate limited)",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ChangePasswordRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/player/account/totp/setup": {
|
||
"post": {
|
||
"tags": [
|
||
"Player"
|
||
],
|
||
"summary": "Begin 2FA enrollment (returns secret + QR)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "otpauth URL and QR data to scan",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpSetup"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"409": {
|
||
"description": "Two-factor already enabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/player/account/totp/enable": {
|
||
"post": {
|
||
"tags": [
|
||
"Player"
|
||
],
|
||
"summary": "Enable 2FA by confirming a code",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "2FA enabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpState"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Setup not started, or invalid code",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"409": {
|
||
"description": "Two-factor already enabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpCodeRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/player/account/totp/disable": {
|
||
"post": {
|
||
"tags": [
|
||
"Player"
|
||
],
|
||
"summary": "Disable 2FA by confirming a code",
|
||
"description": "Requires a valid current authenticator code (proves control of the authenticator); it does not take a password.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "2FA disabled",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpState"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Not enabled, or invalid code",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/TotpCodeRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/player/account/identities": {
|
||
"get": {
|
||
"tags": [
|
||
"Player"
|
||
],
|
||
"summary": "List linked SSO identities (self)",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Linked identities",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/LinkedIdentity"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/player/account/identities/{provider}": {
|
||
"delete": {
|
||
"tags": [
|
||
"Player"
|
||
],
|
||
"summary": "Unlink an SSO identity (self)",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "provider",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Provider id."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Unlinked",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/UnlinkedFlag"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"404": {
|
||
"description": "No linked account for that provider",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/player/shard/link": {
|
||
"post": {
|
||
"tags": [
|
||
"Player · Shard"
|
||
],
|
||
"summary": "Link an in-game account with a one-time code",
|
||
"description": "The player runs [link in game to get a code, then submits it here. The server confirms it with the sidecar and mirrors the link.",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Linked",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ShardLinkResult"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Unknown or expired code",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"502": {
|
||
"description": "Bad Gateway"
|
||
},
|
||
"503": {
|
||
"description": "Shard unavailable — retry",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ShardLinkRequest"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/api/v1/player/shard/accounts": {
|
||
"get": {
|
||
"tags": [
|
||
"Player · Shard"
|
||
],
|
||
"summary": "List the caller’s linked game accounts",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Linked accounts",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardLink"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/player/shard/roster/{account}": {
|
||
"get": {
|
||
"tags": [
|
||
"Player · Shard"
|
||
],
|
||
"summary": "Character roster for a linked account",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "account",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "A game account linked to the caller."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Account roster",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Account not linked to the caller",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Shard unavailable — retry",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/player/shard/vendors/{account}": {
|
||
"get": {
|
||
"tags": [
|
||
"Player · Shard"
|
||
],
|
||
"summary": "Player vendors for a linked account",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "account",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "A game account linked to the caller."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Vendor snapshot",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Account not linked to the caller",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"503": {
|
||
"description": "Shard unavailable — retry",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/player/shard/char/{serial}": {
|
||
"get": {
|
||
"tags": [
|
||
"Player · Shard"
|
||
],
|
||
"summary": "Character sheet — only for a character on the caller’s linked account",
|
||
"description": "",
|
||
"parameters": [
|
||
{
|
||
"name": "serial",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Mobile serial, e.g. 0x24C."
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Character profile",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"additionalProperties": true
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "Bad Request"
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Character not on an account linked to the caller",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Not Found"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
},
|
||
"502": {
|
||
"description": "Bad Gateway"
|
||
},
|
||
"503": {
|
||
"description": "Shard unavailable — retry",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Error"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/api/v1/player/shard/sales": {
|
||
"get": {
|
||
"tags": [
|
||
"Player · Shard"
|
||
],
|
||
"summary": "Recent player-vendor sales for the caller’s linked accounts",
|
||
"description": "",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Vendor sales",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ShardVendorSale"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "Unauthorized"
|
||
},
|
||
"403": {
|
||
"description": "Forbidden"
|
||
},
|
||
"500": {
|
||
"description": "Internal Server Error"
|
||
}
|
||
},
|
||
"security": [
|
||
{
|
||
"cookieAuth": []
|
||
},
|
||
{
|
||
"bearerAuth": []
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"components": {
|
||
"securitySchemes": {
|
||
"cookieAuth": {
|
||
"type": "apiKey",
|
||
"in": "cookie",
|
||
"name": "uomm_token",
|
||
"description": "Session JWT set as an httpOnly cookie by POST /api/v1/auth/login."
|
||
},
|
||
"bearerAuth": {
|
||
"type": "http",
|
||
"scheme": "bearer",
|
||
"bearerFormat": "JWT",
|
||
"description": "Access token from POST /api/v1/auth/mobile/login (or /refresh)."
|
||
}
|
||
},
|
||
"schemas": {
|
||
"Error": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"message": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Not found"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ValidationError": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"errors": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "array"
|
||
},
|
||
"items": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "field"
|
||
}
|
||
}
|
||
},
|
||
"msg": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Invalid value"
|
||
}
|
||
}
|
||
},
|
||
"path": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "username"
|
||
}
|
||
}
|
||
},
|
||
"location": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "body"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"SafeUser": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1
|
||
}
|
||
}
|
||
},
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
},
|
||
"role": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"admin",
|
||
"editor"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"LoginRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"username",
|
||
"password"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
},
|
||
"password": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "password"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "super-secret"
|
||
}
|
||
}
|
||
},
|
||
"company": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Honeypot — must be empty for humans."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": ""
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"RegisterRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"username",
|
||
"password"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"minLength": {
|
||
"type": "number",
|
||
"example": 3
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 32
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "newplayer"
|
||
}
|
||
}
|
||
},
|
||
"password": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "password"
|
||
},
|
||
"minLength": {
|
||
"type": "number",
|
||
"example": 8
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 64
|
||
}
|
||
}
|
||
},
|
||
"email": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "email"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "player@example.com"
|
||
}
|
||
}
|
||
},
|
||
"company": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Honeypot — must be empty for humans."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": ""
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"LoginResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Either a session (user) or, for 2FA accounts, a TOTP challenge to complete at /login/totp."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"user": {
|
||
"$ref": "#/components/schemas/SafeUser"
|
||
},
|
||
"totpRequired": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"challenge": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Signed challenge token for the TOTP step."
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"TotpLoginRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"challenge",
|
||
"code"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"challenge": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Token returned by /login when totpRequired."
|
||
}
|
||
}
|
||
},
|
||
"code": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "123456"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"MobileLoginRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"username",
|
||
"password"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
},
|
||
"password": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "password"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "super-secret"
|
||
}
|
||
}
|
||
},
|
||
"code": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "TOTP code (only when 2FA is enabled)."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "123456"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"MobileTokenResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"accessToken": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Short-lived bearer JWT."
|
||
}
|
||
}
|
||
},
|
||
"refreshToken": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Long-lived, revocable refresh token."
|
||
}
|
||
}
|
||
},
|
||
"expiresIn": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Access token lifetime as a duration string (zeit/ms format, e.g. \"15m\")."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "15m"
|
||
}
|
||
}
|
||
},
|
||
"user": {
|
||
"$ref": "#/components/schemas/SafeUser"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"MobileRefreshRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"refreshToken"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"refreshToken": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"MobileLogoutRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"refreshToken": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Revoke a single session."
|
||
}
|
||
}
|
||
},
|
||
"all": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Revoke every session for the user."
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": false
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"Message": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"message": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Logged out."
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ContactRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"message"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"message": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 5000
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "When does the shard launch?"
|
||
}
|
||
}
|
||
},
|
||
"email": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "email"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "player@example.com"
|
||
}
|
||
}
|
||
},
|
||
"name": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 100
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Lord British"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"Provider": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "google"
|
||
}
|
||
}
|
||
},
|
||
"name": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Google"
|
||
}
|
||
}
|
||
},
|
||
"icon": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Icon hint — the provider kind ('google' | 'discord' | 'oidc' | 'oauth2')."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "google"
|
||
}
|
||
}
|
||
},
|
||
"loginUrl": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Relative URL to begin the redirect flow."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "/api/v1/auth/sso/google/start"
|
||
}
|
||
}
|
||
},
|
||
"priority": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Sort order (ascending)."
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ProviderConfig": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "okta"
|
||
}
|
||
}
|
||
},
|
||
"kind": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"google",
|
||
"discord",
|
||
"oidc",
|
||
"oauth2"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "oidc"
|
||
}
|
||
}
|
||
},
|
||
"name": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Okta"
|
||
}
|
||
}
|
||
},
|
||
"enabled": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"clientId": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"hasSecret": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Whether a client secret is stored (the secret itself is never returned)."
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"authorizeUrl": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "uri"
|
||
}
|
||
}
|
||
},
|
||
"tokenUrl": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "uri"
|
||
}
|
||
}
|
||
},
|
||
"userinfoUrl": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "uri"
|
||
}
|
||
}
|
||
},
|
||
"scopes": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "openid email profile"
|
||
}
|
||
}
|
||
},
|
||
"priority": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 10
|
||
}
|
||
}
|
||
},
|
||
"builtin": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "True for the fixed google/discord providers."
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": false
|
||
}
|
||
}
|
||
},
|
||
"health": {
|
||
"$ref": "#/components/schemas/ProviderHealth"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ProviderHealth": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Config-completeness check that gates whether a provider is offered to end users."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"valid": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"missing": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "array"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Names of required config fields that are still missing."
|
||
},
|
||
"items": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "array",
|
||
"example": [],
|
||
"items": {}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ProviderCreateRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"id",
|
||
"kind",
|
||
"name"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"pattern": {
|
||
"type": "string",
|
||
"example": "^[a-z0-9-]+$"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "okta"
|
||
}
|
||
}
|
||
},
|
||
"kind": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"oidc",
|
||
"oauth2"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "oidc"
|
||
}
|
||
}
|
||
},
|
||
"name": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 80
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Okta"
|
||
}
|
||
}
|
||
},
|
||
"enabled": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"clientId": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"secret": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "password"
|
||
}
|
||
}
|
||
},
|
||
"authorizeUrl": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "uri"
|
||
}
|
||
}
|
||
},
|
||
"tokenUrl": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "uri"
|
||
}
|
||
}
|
||
},
|
||
"userinfoUrl": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "uri"
|
||
}
|
||
}
|
||
},
|
||
"scopes": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 500
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "openid email profile"
|
||
}
|
||
}
|
||
},
|
||
"priority": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 10
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"Post": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 12
|
||
}
|
||
}
|
||
},
|
||
"category": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "news"
|
||
}
|
||
}
|
||
},
|
||
"title": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Server maintenance this weekend"
|
||
}
|
||
}
|
||
},
|
||
"slug": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "server-maintenance-this-weekend"
|
||
}
|
||
}
|
||
},
|
||
"excerpt": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"body": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"image_url": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "/uploads/1700000000-abcd.png"
|
||
}
|
||
}
|
||
},
|
||
"published": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"author_id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1
|
||
}
|
||
}
|
||
},
|
||
"created_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
},
|
||
"updated_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
},
|
||
"published_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"PostCreateRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"category",
|
||
"title"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"category": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "news"
|
||
}
|
||
}
|
||
},
|
||
"title": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 200
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Server maintenance this weekend"
|
||
}
|
||
}
|
||
},
|
||
"body": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"image_url": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Required for the screenshots category."
|
||
}
|
||
}
|
||
},
|
||
"published": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": false
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"PublishRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"published"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"published": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"UploadResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"url": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "/uploads/1700000000-abcd.png"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"WikiPage": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 3
|
||
}
|
||
}
|
||
},
|
||
"slug": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "getting-started"
|
||
}
|
||
}
|
||
},
|
||
"title": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Getting Started"
|
||
}
|
||
}
|
||
},
|
||
"excerpt": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"body": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"category_id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 2
|
||
}
|
||
}
|
||
},
|
||
"published": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"tags": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "array"
|
||
},
|
||
"items": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "array",
|
||
"example": [
|
||
"newbie",
|
||
"guide"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"created_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
},
|
||
"updated_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"WikiPageCreateRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"slug",
|
||
"title"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"slug": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"pattern": {
|
||
"type": "string",
|
||
"example": "^[a-z0-9-]+$"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "getting-started"
|
||
}
|
||
}
|
||
},
|
||
"title": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 200
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Getting Started"
|
||
}
|
||
}
|
||
},
|
||
"excerpt": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 400
|
||
}
|
||
}
|
||
},
|
||
"body": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"category_id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"published": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": false
|
||
}
|
||
}
|
||
},
|
||
"tags": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "array"
|
||
},
|
||
"items": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"WikiCategory": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 2
|
||
}
|
||
}
|
||
},
|
||
"slug": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "guides"
|
||
}
|
||
}
|
||
},
|
||
"title": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Guides"
|
||
}
|
||
}
|
||
},
|
||
"description": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
}
|
||
}
|
||
},
|
||
"sort_order": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 0
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"WikiCategoryCreateRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"slug",
|
||
"title"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"slug": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"pattern": {
|
||
"type": "string",
|
||
"example": "^[a-z0-9-]+$"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "guides"
|
||
}
|
||
}
|
||
},
|
||
"title": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 200
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Guides"
|
||
}
|
||
}
|
||
},
|
||
"description": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 400
|
||
}
|
||
}
|
||
},
|
||
"sort_order": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 0
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"User": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1
|
||
}
|
||
}
|
||
},
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
},
|
||
"role": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"admin",
|
||
"editor",
|
||
"moderator",
|
||
"player"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
},
|
||
"status": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"active",
|
||
"disabled",
|
||
"banned",
|
||
"pending"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "active"
|
||
}
|
||
}
|
||
},
|
||
"email": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "email"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"email_verified": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": false
|
||
}
|
||
}
|
||
},
|
||
"totp_enabled": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"last_login_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"created_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"UserCreateRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"username",
|
||
"password"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"minLength": {
|
||
"type": "number",
|
||
"example": 3
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 32
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "editor1"
|
||
}
|
||
}
|
||
},
|
||
"password": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "password"
|
||
},
|
||
"minLength": {
|
||
"type": "number",
|
||
"example": 8
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 64
|
||
}
|
||
}
|
||
},
|
||
"role": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"admin",
|
||
"editor",
|
||
"moderator",
|
||
"player"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "editor"
|
||
}
|
||
}
|
||
},
|
||
"status": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"active",
|
||
"disabled",
|
||
"banned",
|
||
"pending"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "active"
|
||
}
|
||
}
|
||
},
|
||
"email": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "email"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ChangeUsernameRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"username"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"minLength": {
|
||
"type": "number",
|
||
"example": 3
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 32
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "newname"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ChangePasswordRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"newPassword"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"newPassword": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "password"
|
||
},
|
||
"minLength": {
|
||
"type": "number",
|
||
"example": 8
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 64
|
||
}
|
||
}
|
||
},
|
||
"currentPassword": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "password"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Required when the account already has a password. Omit only for an SSO-provisioned account setting its first password."
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"PlayerAccount": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Self-service player account (GET /player/account)."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 42
|
||
}
|
||
}
|
||
},
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "newplayer"
|
||
}
|
||
}
|
||
},
|
||
"role": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"player"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "player"
|
||
}
|
||
}
|
||
},
|
||
"email": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "email"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "player@example.com"
|
||
}
|
||
}
|
||
},
|
||
"status": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"active",
|
||
"disabled",
|
||
"banned",
|
||
"pending"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "active"
|
||
}
|
||
}
|
||
},
|
||
"totp_enabled": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": false
|
||
}
|
||
}
|
||
},
|
||
"has_password": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "False for an SSO-provisioned account that has not set a password yet."
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"OkFlag": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"ok": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"TotpCodeRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"code"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"code": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "123456"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"SiteModeRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"mode"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"mode": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"live",
|
||
"maintenance"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "live"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"UnbanRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"ip"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"ip": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "203.0.113.5"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"AccountStatus": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Self-service account security status (GET /admin/account)."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1
|
||
}
|
||
}
|
||
},
|
||
"username": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
},
|
||
"role": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"admin",
|
||
"editor"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
},
|
||
"totp_enabled": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"TotpSetup": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Enrollment material returned by POST /account/totp/setup."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"otpauthUrl": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "otpauth://totp/UOMysticmoon:admin?secret=..."
|
||
}
|
||
}
|
||
},
|
||
"qr": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "QR code as a data: URL."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "data:image/png;base64,iVBORw0KGgo..."
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"TotpState": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Result of enabling/disabling 2FA."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"totp_enabled": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"LinkedIdentity": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"provider": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "google"
|
||
}
|
||
}
|
||
},
|
||
"email": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "email"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "user@example.com"
|
||
}
|
||
}
|
||
},
|
||
"linked_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"SiteModeState": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Result of PUT /admin/site-mode."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"site_mode": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"live",
|
||
"maintenance"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "maintenance"
|
||
}
|
||
}
|
||
},
|
||
"changed_at": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
},
|
||
"changed_by": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "admin"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"PublicStatus": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Public site status (GET /public/status)."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"mode": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"enum": {
|
||
"type": "array",
|
||
"example": [
|
||
"live",
|
||
"maintenance"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "live"
|
||
}
|
||
}
|
||
},
|
||
"status_message": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": ""
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"DeletedId": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 12
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"DeletedSlug": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"slug": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "getting-started"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"DeletedFlag": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"deleted": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"UnlinkedFlag": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"unlinked": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"UnbanResult": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"ip": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "203.0.113.5"
|
||
}
|
||
}
|
||
},
|
||
"removed": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Whether the IP had an entry that was cleared."
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardStatus": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Public shard status (GET /public/shard/status)."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"enabled": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"status": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "connected"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "connected | reconnecting | disconnected | error"
|
||
}
|
||
}
|
||
},
|
||
"pluginConnected": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Is the shard link up right now?"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"lastEventAt": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"onlineCount": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 12
|
||
}
|
||
}
|
||
},
|
||
"economy": {
|
||
"$ref": "#/components/schemas/ShardEconomyPoint"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardEvent": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "A logged shard event."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 4821
|
||
}
|
||
}
|
||
},
|
||
"kind": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "vendor.sale"
|
||
}
|
||
}
|
||
},
|
||
"t": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Event time, epoch ms."
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1783720195626
|
||
}
|
||
}
|
||
},
|
||
"bootId": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "boot-abc123"
|
||
}
|
||
}
|
||
},
|
||
"payload": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"additionalProperties": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "The full event object."
|
||
}
|
||
}
|
||
},
|
||
"createdAt": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardEconomyPoint": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "One gold-supply sample."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"accounts": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 240
|
||
}
|
||
}
|
||
},
|
||
"gold": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1028983421
|
||
}
|
||
}
|
||
},
|
||
"t": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Sample time, epoch ms."
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1783720000000
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardOnlinePlayer": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "A LINKED player online now (only accounts linked to a website user are listed)."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"serial": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "0x24C"
|
||
}
|
||
}
|
||
},
|
||
"name": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Darrow"
|
||
}
|
||
}
|
||
},
|
||
"map": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Trammel"
|
||
}
|
||
}
|
||
},
|
||
"x": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1402
|
||
}
|
||
}
|
||
},
|
||
"y": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1604
|
||
}
|
||
}
|
||
},
|
||
"z": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 0
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardVendorSale": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "A player-vendor sale (visible only to the linked owner)."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"t": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Sale time, epoch ms."
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1783720195626
|
||
}
|
||
}
|
||
},
|
||
"itemType": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Longsword"
|
||
}
|
||
}
|
||
},
|
||
"amount": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 1
|
||
}
|
||
}
|
||
},
|
||
"price": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 100
|
||
}
|
||
}
|
||
},
|
||
"commission": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 5
|
||
}
|
||
}
|
||
},
|
||
"ownerAcct": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "whitlocktech"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardHouse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "A house at its current decay stage."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"serial": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "0x4004705F"
|
||
}
|
||
}
|
||
},
|
||
"stage": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "IDOC"
|
||
}
|
||
}
|
||
},
|
||
"map": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Trammel"
|
||
}
|
||
}
|
||
},
|
||
"x": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"y": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"z": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"region": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"name": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "An Unnamed House"
|
||
}
|
||
}
|
||
},
|
||
"ownerSerial": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"ownerAcct": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"builtOn": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"lastRefreshed": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"isIdoc": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"updatedAt": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardLinkRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"code"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"code": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "The one-time code shown by [link in game."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "AB12CD"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardLinkResult": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"linked": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "boolean"
|
||
},
|
||
"example": {
|
||
"type": "boolean",
|
||
"example": true
|
||
}
|
||
}
|
||
},
|
||
"account": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "whitlocktech"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"ShardLink": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "A linked in-game account (GET /player/shard/accounts)."
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"account": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "whitlocktech"
|
||
}
|
||
}
|
||
},
|
||
"userId": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 42
|
||
}
|
||
}
|
||
},
|
||
"charName": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"nullable": {
|
||
"type": "boolean",
|
||
"example": true
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "Darrow"
|
||
}
|
||
}
|
||
},
|
||
"linkedAt": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"example": "date-time"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"TownCrierRequest": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "object"
|
||
},
|
||
"required": {
|
||
"type": "array",
|
||
"example": [
|
||
"id",
|
||
"lines"
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 64
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"example": "Re-posting the same id replaces the prior entry."
|
||
},
|
||
"example": {
|
||
"type": "string",
|
||
"example": "news-42"
|
||
}
|
||
}
|
||
},
|
||
"lines": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "array"
|
||
},
|
||
"items": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "string"
|
||
},
|
||
"maxLength": {
|
||
"type": "number",
|
||
"example": 200
|
||
}
|
||
}
|
||
},
|
||
"example": {
|
||
"type": "array",
|
||
"example": [
|
||
"Hear ye!",
|
||
"Market tax is now 5%."
|
||
],
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"durationSec": {
|
||
"type": "object",
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"example": "integer"
|
||
},
|
||
"minimum": {
|
||
"type": "number",
|
||
"example": 1
|
||
},
|
||
"maximum": {
|
||
"type": "number",
|
||
"example": 86400
|
||
},
|
||
"example": {
|
||
"type": "number",
|
||
"example": 3600
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} |