Skip to content

Changelog

[2026.05.25] - Harden Bearer Token Transport

Changed

  • Reject bearer tokens in query strings by default and document the WebSocket subprotocol fallback for clients without header support.
  • Require server-owned music channel verification before social realtime server-event subscriptions can attach to Voice events.
  • Seed config-gateway permission nodes so deployments have explicit route and config authorization entries.
  • Limit managed Gateway DNS publication to official Connect gateway servers with public-routable IP targets.
  • Strip caller-supplied proxy identity headers before config-gateway forwards requests upstream.

[2026.05.25] - Add Mandatory Launcher Update Policy

Added

  • Add optional updatePolicy metadata to version releases so clients can distinguish optional updates from required updates.
  • Return mandatoryUpdate from the public version resolver when a launcher release requires older clients to update before launch.

[2026.05.21] - Preserve Minigame Round Metadata

Changed

  • Accept and return roundBased on public minigame catalog reports so live Uebliche.games entries keep their party-ready behavior.

[2026.05.20] - Format CurseForge Discover Descriptions

Fixed

  • Normalize cached CurseForge HTML descriptions into Markdown so Discover clients receive formatted headings, lists, links, inline emphasis, and code blocks.

[2026.05.20] - Normalize Discover Provider Details

Changed

  • Normalize mirrored Modrinth and CurseForge version details into one Discover contract with minecraftVersions, loaders, and supportTargets.
  • Keep old cached provider details readable while new mirror refreshes write matrix-ready support data.

[2026.05.20] - Cache CurseForge Details

Added

  • Cache CurseForge project, description, file list, file detail, and search responses in the Public API proxy.
  • Add a public CurseForge project description route for clients that need the full project body.

Changed

  • Include cached CurseForge descriptions in project detail responses and Discover mirror records.

[2026.05.20] - Complete Experience Public Beta APIs

Added

  • Add Experience Presence endpoints for listing collaborators and updating the current user's cursor and selection state.
  • Add Experience Live runtime endpoints for status, start, and stop responses that expose experienceId, runtime kind, entrypoint, resource packs, join target, and status.
  • Add Experience script validation so creator playtests and publish approvals can reject unsafe or invalid scripts before runtime startup.

Changed

  • Treat experienceId as the V1 runtime alias for projectId in Experience version, playtest, and live responses.
  • Activate approved Experience publish reviews by default while keeping immutable published versions as the only source for public live runtime startup.
  • Keep Experience project roles additive to global permissions so project membership cannot replace the required creator permission node.

[2026.05.20] - Add Multiplexed Social Live Stream

Added

  • Add /v1/social/live as a multiplexed WebSocket for Friends, Party, Chat Inbox, and subscribed Chat Conversations.
  • Add subscribe and unsubscribe commands for chat conversation detail snapshots on the unified Social stream.

Changed

  • Reuse existing Party and Chat broadcast senders inside the unified Social stream while keeping the legacy live endpoints available.

[2026.05.20] - Add Chat Inbox Live Stream

Added

  • Add a global /v1/social/chat/live WebSocket stream for authenticated chat participants so inboxes can update without opening each conversation.
  • Include optional last-message metadata on chat conversations so clients can distinguish new messages from edits, deletes, and poll vote updates.

Changed

  • Broadcast chat conversation list updates to all participants when conversations, messages, edits, deletes, or poll votes change.

[2026.05.20] - Add Experience Builder API Foundation

Added

  • Add Experience project endpoints for creating, listing, opening, and updating creator-owned experience projects.
  • Add Experience collaboration endpoints for project members, direct invites, invite acceptance, draft documents, optimistic document patches, playtest requests, publish requests, review approval, and immutable published versions.
  • Add MongoDB collections and indexes for Experience projects, members, invites, documents, patch logs, playtests, publish requests, and versions.
  • Add project-scoped publish-request listing so creators can review their own pending and reviewed Experience release requests.

Changed

  • Seed Experience creator permission nodes for create, view, invite, edit, script, playtest, publish request, and publish review actions.
  • Use the canonical experience_* MongoDB collection names across the Public API and Java Experience Mongo storage.

[2026.05.20] - Push Party Invites Live

Changed

  • Push party snapshots to active /v1/social/party/live WebSocket clients immediately after party invites and party state changes, so incoming invites no longer wait for the fallback polling tick.

[2026.05.18] - Synchronize Party Play Lobby

Added

  • Add Party lobby state to party payloads so clients can share the selected minigame, server, world, ready states, selector permissions, and short-lived launch signals.
  • Add Public API endpoints for party lobby selection, selector permissions, and ready status updates.

Changed

  • Reset all party ready states whenever the selected lobby target changes.
  • Emit a launch signal when every current party member is ready for the selected round-based minigame.

[2026.05.18] - Expose FairPlay Mod Stats

Added

  • Store, backfill, and return Modrinth project categories for FairPlay mod hash records so admin tools can sort reviewed mods by feature type.
  • Return FairPlay mod download and install counters so admin tools can sort high-impact mods first.
  • Add an exact FairPlay project filter for admin mod lists so Dash can load every known version in a grouped mod review.

Fixed

  • Retry stale unknown FairPlay mod hash cache entries when clients provide fresh file evidence, so older records can resolve to Modrinth names instead of staying permanently unknown.

[2026.05.18] - Backfill FairPlay Mod File Names

Fixed

  • Preserve incoming FairPlay mod file names for cached hash records so Dash can show a mod label instead of only the hash after clients report the same mod again.

[2026.05.18] - Keep Online Node Reporting Deployed

Fixed

  • Preserve or require uebliche.online heartbeat settings during Public API deploys, so regional nodes keep reporting status and traffic data instead of disappearing after a deploy with empty Online configuration.

[2026.05.18] - Add Uebliche Discover Extensions

Added

  • Include first-party Uebliche Extensions as a custom provider in public Discover mod search results, including the Playerlist extension.

Fixed

  • Return Discover search results from projected mirror fields instead of loading full provider mirror documents for each list item, so the web Discover page no longer times out on normal mod searches.
  • Add a title-aware Discover provider rank index so default catalog pages can use the same ordering without scanning and sorting full mirror records.

[2026.05.17] - Speed Up Public API Deploys

Changed

  • Select a native, sufficiently sized Docker build context for local Public API deploys instead of defaulting to slow or memory-constrained local builders.
  • Cap Public API image builds at 600 seconds by default, so bad builder choices fail fast instead of blocking deploys for hours.
  • Use faster configurable Rust release-build defaults for deploy images, including parallel cargo jobs, multiple codegen units, and threaded lld linking.

[2026.05.17] - Keep Discover Search Mirrored

Changed

  • Serve public Discover provider search only from mirrored Modrinth and CurseForge catalog copies, so web and launcher clients no longer live-proxy external providers during search.
  • Remove in-process and shared HTTP caches from Discover search and queue provider mirror refreshes when the configured refresh TTL expires, so search responses always reflect the current MongoDB mirror.
  • Expose DISCOVER_PROVIDER_REFRESH_TTL_SECS through the Public API Swarm stack with a default of 300 seconds.

[2026.05.16] - Add Server Friends API

Added

  • Add server-authenticated Friends endpoints so Gameserver commands can list, send, accept, decline, cancel, and remove friends through the Public API.

Changed

  • Keep server Friends behavior aligned with the user-facing Public API rules for blocks, request settings, limits, request expiry, party enrichment, and flame streaks.
  • Align GET /v1/users/{id}/friends with the canonical Friends overview shape, including request lists, self, max-friend count, and party enrichment.

[2026.05.16] - Make Parties Public API Canonical

Changed

  • Make POST /v1/social/party create or return the caller's party instead of leaving it.
  • Add server-authenticated party endpoints for Gameserver and Hub services, including lookup by player ids.
  • Read party voice channel membership from uebliche_parties instead of legacy user partyId fields.

Removed

  • Remove legacy users.partyId party reads from Public API party and voice flows.

[2026.05.15] - Resolve Resource Pack Releases

Added

  • Add a public resource-pack resolve endpoint so games and lobby services can fetch the latest published URL and SHA1 by pack name and channel.

[2026.05.09] - Add Discover Version Side Metadata

Added

  • Include normalized client/server side support on mirrored Discover provider versions so launcher clients can distinguish client-required, server-required, optional, unsupported, and unknown install scopes.
  • Store mirrored provider version loaders, Minecraft versions, side support, and dependencies in the Public API version mirror for local sync and future resolver queries.

[2026.05.08] - Handle Missing World Manifests

Fixed

  • Return a not-found response for missing World version manifests instead of reporting an internal server error.

[2026.05.08] - Add Party Live Stream

Added

  • Add a party WebSocket stream that emits party membership and pending invite changes for launcher clients.

[2026.05.07] - Add Per-Entry Minigame Launch Metadata

Added

  • Accept per-minigame server, Minecraft version, loader, recommended profile, and profile share code metadata in catalog reports so uebliche.games can publish entries that use a dedicated launch setup.

[2026.05.07] - Add Birthday Premium Rewards

Added

  • Add locked profile birthday settings with IANA time zones so players can set their birthday once and support can correct it through an admin endpoint.
  • Grant 7 days of Premium automatically through the existing Shop entitlement pipeline at the player's local birthday midnight, with yearly idempotency.

Changed

  • Treat future startsAt values as inactive for Shop purchases so scheduled rewards only unlock once their start time has arrived.

[2026.05.07] - Add Premium Shop Status

Added

  • Seed a Premium shop product with monthly, 3-month, and 12-month subscription variants, including lower effective pricing for longer terms.
  • Add a Premium role with Uebliche.Games private-game creation, quest XP bonus, Hub premium access, and Founder-like account perks while keeping Founder above the new Games perk tier.
  • Award Premium quest completions with a separate bonus XP event so the bonus is fixed at completion time.

[2026.05.07] - Add Connect Achievements API

Added

  • Add Connect-network achievement definition endpoints with DE/EN translations, progress targets, and active/inactive S3-backed PNG icons.
  • Add authenticated Connect server achievement event reporting with idempotent event IDs, monotonic progress updates, unlock handling, and profile/public read endpoints.
  • Seed achievement permission nodes for read, write, delete, and progress-read access.

[2026.05.06] - Expand Daily Uebliche.Games Quest Assignment

Changed

  • Generate a larger daily Uebliche.Games quest pool and store five automatic per-user quests plus up to two optional selections.
  • Include daily assignment, automatic count, and reroll state in quest campaign responses.

Added

  • Add POST /v1/quests/daily-games/reroll to replace one active daily quest per user per day.

[2026.05.06] - Add Daily Uebliche.Games Quests

Added

  • Generate five rotating daily Uebliche.Games quest campaigns and store each user's two selected daily quests.
  • Include quest XP, progress targets, game modes, daily window keys, and selection state in quest campaign responses.
  • Credit quest points and play.quest_completed XP events when selected daily Uebliche.Games quests are completed through Connect quest events.

[2026.05.05] - Persist Voice Control Plane

Changed

  • Rehydrate persisted voice nodes and channels during Public API startup so active voice sessions survive API restarts.
  • Persist join, sync, leave, node heartbeat, node unregister, and server control mutations before emitting user or node snapshots.
  • Include attachment, latency, cooldown, session version, server control, and proximity peer state in the stored voice channel document.

Added

  • Add PUT /v1/social/voice/channels/{channelId}/control with Connect server credentials or social:voice.write authorization.
  • Accept proximityPeers on voice join and sync requests while keeping visiblePlayers as the legacy fallback.

[2026.05.05] - Expose Playtime Activity Details

Added

  • Include per-day launcher activity details in the profile playtime summary so clients can show account activity breakdowns by world or server.

[2026.05.05] - Expire Stale Social Presence

Fixed

  • Treat social presence as offline when its heartbeat is stale, so old in-game activity and join targets no longer stay visible after clients stop reporting.

[2026.05.03] - Add Connect Friends Delegation

Added

  • Add Connect server public-key identities and short-lived delegated tokens for social:friends.read.
  • Add a server-authenticated delegated friends endpoint and expose friend capacity in friends counts.

[2026.05.03] - Add World Cloud Storage Shop

Added

  • Seed the world-cloud-storage shop product with 25 GB, 100 GB, and 250 GB monthly EUR variants that grant worlds:cloud.storage.max in GiB.
  • Seed world cloud quota permission nodes and include 50 GB of cloud storage in the Founder/Gründer rank.

Changed

  • Allow storage permission values to use GiB in the admin schema while keeping byte values compatible.
  • Enforce cloud world upload storage against the account's total stored world bytes instead of the current world only.

[2026.05.03] - Add Shop Realtime Events

Added

  • Add an authenticated /v1/shop/events WebSocket that sends purchase snapshots and change notifications for Launcher rank refreshes.

Changed

  • Broadcast shop purchase changes after Polar fulfillment, refunds, cancellations, and status updates, with a polling fallback so connected clients still update across API processes.

[2026.05.03] - Fix Level Cache Writes

Fixed

  • Store level XP source buckets without MongoDB field names that contain dots, so /v1/profile/level can rebuild and cache profiles with sources such as play.minute instead of returning 500.
  • Treat concurrent level projection upserts as cache hits when another request already stored the same projection.

[2026.05.02] - Speed Up Social Chat Reads

Changed

  • Keep social chat message reads and live streams on recent messages by default, while archived history remains available through explicit archive requests.
  • Warn on Public API requests above 100 ms so slow endpoints are visible as latency target violations.

Fixed

  • Move social chat archive maintenance out of the read path and run it after new messages in the background, so chat refreshes do not block on archive scans or object-storage writes.

[2026.05.02] - Enable Founder Shop Product

Added

  • Publish the Founder / Gründer lifetime shop item for the live catalog with a 14.99 EUR price and Polar checkout mapping.
  • Add a TEST100 100% test discount code for the Founder product, limited to 20 redemptions.

Changed

  • Set Polar's default presentment currency to EUR and add EUR prices to existing live products so new checkouts open in EUR.

[2026.05.02] - Fix Polar Production Config

Fixed

  • Retry Polar product creation without organization_id when Polar reports that an organization-scoped access token disallows that field.
  • Allow rotated Polar access-token Swarm secrets in the Public API stack so production shop checkout can be configured without reusing empty legacy secret placeholders.

[2026.05.02] - Add Founder Rank

Added

  • Seed a global founder rank with Founder/Gründer display name, premium Hub access, founder-specific permission flag, and launch supporter limits so it can be sold through the Shop.

[2026.05.02] - Finish Polar Shop Fulfillment

Added

  • Store resolved shop role IDs and visible grants on purchases so /v1/shop/purchases shows what an active purchase unlocks.
  • Apply active Polar purchases to user_role assignments and Connect permission responses, including rank data and direct permission grants.

Fixed

  • Make Polar order/subscription webhooks idempotent for paid, updated, refunded, canceled, and revoked purchases.
  • End only shop-managed role assignments on refunds or cancellations while preserving manual role grants.

Changed

  • Configure production checkout success and cancel URLs for the Public API stack.

[2026.05.02] - Add Connect Permission Tokens

Added

  • Issue short-lived Connect permission JWTs with permission grants so Minecraft servers can verify transferred player permissions without reading MongoDB directly.
  • Include the highest applicable server rank in Connect permission responses and tokens so game servers can render rank-aware tab names.

[2026.05.01] - Extend Connect Permissions

Changed

  • Include structured Connect permission grants with optional values while keeping the legacy permissions string list for existing clients.
  • Resolve role and direct user permission values through the Connect permission API so game runtimes do not need direct MongoDB access.

[2026.05.01] - Seed Hub Permission Nodes

Added

  • Seed Hub permission nodes such as hub.debug, hub.premium, hub.team, and the value-based hub.skyblock.slots.max so Dash roles can manage Minecraft Hub access.
  • Seed service and extension role-creation permissions used by the role API scope checks.

[2026.05.01] - Grant Launcher Skin Profile Access

Fixed

  • Give the default signed-in user role access to launcher cape and skin-builder profile permissions, so Capes and Skin Builder profile reads no longer fail with 403 FORBIDDEN for normal users.
  • Seed the missing cape and skin-builder moderation permission nodes so admin role configuration can reference the same permissions enforced by the API endpoints.

[2026.04.30] - Keep launcher profile shares permanent

Changed

  • Keep launcher profile share codes active until the owner replaces or deletes them, so public server and Connect profile links can be reused as stable profile bases.
  • Expose recommendedProfileShareCode in the public minigame catalog so clients can import the recommended base profile directly.

Fixed

  • Remove expiry filtering from profile-share resolution and Connect profile validation so existing share codes no longer disappear after the old seven-day TTL window.

[2026.04.30] - Allow Default Profile Sharing

Fixed

  • Let default signed-in users create launcher profile shares and keep a bounded active-share quota.

[2026.04.30] - Remove Minigame Queue Commands

Changed

  • Omit queueCommand from the public minigame catalog because Launchers now start Uebliche.games entries through the Connect minigame join payload.

[2026.04.30] - Normalize Public Minigame Catalog

Fixed

  • Return public minigame catalog timestamps as plain ISO strings and expose only launcher-safe JSON fields, so Launchers can decode Uebliche.games reports without BSON Extended JSON date maps.

[2026.04.27] - Auto-Repair Public Route DNS

Fixed

  • Auto-sync the managed uebliche.gg DNS records on Public API startup and periodically afterwards, including the apex Worker record, so an empty public route zone is repaired without waiting for a gateway or slug update.

[2026.04.26] - Accept Delta Update Flags

Fixed

  • Accept delta=1 and delta=0 on the public versions resolve endpoint so launcher delta-update checks no longer fail during query parsing.

[2026.04.26] - Add Friend Flame Streaks

Added

  • Add pair-shared friend flame streaks with idempotent daily encounter credit, UTC day boundaries, configurable grace days through social:flame-streak.grace-days.max, and flameStreak data in Friends API responses.

[2026.04.26] - Award Creator XP For Favorites

Added

  • Award create.like_received XP to the verified creator of a public server when another user favorites it, with self-favorites ignored and idempotency preventing repeated unfavorite/refavorite farming.

[2026.04.26] - Add User Level Profiles

Added

  • Add per-user level profiles in the Public API with cached projections from raw XP activity events, so user level reads stay cheap while policy and abuse-rule changes can still rebuild the profile from the ledger.
  • Add trusted level event ingestion for play, create, and interaction sources plus public and authenticated profile-level read endpoints.

[2026.04.26] - Add Social Chat Message Mutations

Added

  • Add authenticated social chat endpoints for editing and soft-deleting messages, returning editedAt and deletedAt metadata in live and archived message payloads.

[2026.04.26] - Store public server icons

Added

  • Store imported launcher server icons on public server records and return them from the public server directory plus a dedicated icon lookup endpoint for chat embeds.

[2026.04.26] - Add build.moe banner submissions

Added

  • Add authenticated POST /v1/profile/build-moe/banners so launcher creators can submit generated banners into the moderation queue.
  • Add banner colorSlots metadata and color/colorSlot query support for GET /v1/banner/search, GET /v1/banner/random, and GET /v1/banner/{id} so colorized variants can be fetched without duplicating every banner.

[2026.04.26] - Add build.moe head and banner catalogs

Added

  • Add public GET /v1/head/search, GET /v1/banner/search, GET /v1/head/{id}, and GET /v1/banner/{id} endpoints so build.moe heads and banners can be served separately through the Public API.
  • Add configurable BuildMoe Mongo database and collection settings for heads and banners, with Docker stack environment variables for production rollout.

Changed

  • Return canonical heads and banners result arrays from the random endpoints while preserving generic items and results fields for existing clients.

[2026.04.25] - Speed up public API rollouts

Added

  • Return public server slugs in directory responses and synthesize slugs for imported launcher servers and Connect-backed server rows.
  • Report HTTP 429 rate-limit responses to Sentry with method, path, query-presence, and user-agent context so production limits can be tuned from observed failures without storing query tokens.

Changed

  • Reuse BuildKit Cargo caches during Public API Docker builds, so follow-up deploys avoid recompiling unchanged dependencies.
  • Start Public API services before non-blocking database index checks finish in production, so deploys stop waiting on index maintenance before accepting traffic.
  • Seed permission nodes with one read and one batch insert instead of many startup upserts, reducing database round trips during regional restarts.
  • Add a container health check for /health, so rolling updates can keep old tasks alive until new API tasks are actually reachable.
  • Mark the legacy world-storage backfill as completed after a successful run, so future Public API starts skip the already-finished migration scan.

Fixed

  • Resolve friend-request targets by player name case-insensitively when legacy user rows do not have a name_lc field, so adding friends from the launcher works with normal Minecraft name casing.

[2026.04.25] - Recover legacy chat conversations

Fixed

  • Resolve social chat conversations from legacy participant fields, string conversation ids, and participantsKey fallbacks so existing chat windows can send messages instead of failing with Conversation not found.
  • Validate chat participant users across UUID storage formats when creating or loading conversations, matching the existing chat list compatibility path.

[2026.04.24] - Bound public catalog search cache

Fixed

  • Enforce real eviction in the public mod-search cache and refresh cache recency on hits, so bursts of unique launcher queries no longer let the in-memory Modrinth and CurseForge page cache grow past its configured bound.

[2026.04.23] - Add public news RSS feed

Added

  • Add GET /v1/public/news/rss as an RSS 2.0 view over published news entries, so feed readers and external sites can subscribe to launcher and project news without polling the JSON endpoint directly.

Changed

  • Reuse the existing public-news publication filters and shared cache policy for the RSS feed, and default missing RSS scope values to global, so reader-friendly feed URLs stay aligned with the same release visibility rules as /v1/public/news.

[2026.04.22] - Add managed Velocity network control plane

Added

  • Add managed-server network, proxy-group, move, topology, peer-resolve, and relay-session endpoints plus Mongo persistence for network/group/session documents, so the Public API can orchestrate Velocity proxy groups and backend placement as an explicit control plane instead of ad-hoc Connect commands.
  • Extend managed-server runtime snapshots and agent host records with mesh endpoint, player-count, topology-version, and host mesh metadata, so proxy topology reads can resolve direct mesh targets and future relay sessions from one canonical API surface.

Changed

  • Validate network host placement against mesh-capable agent hosts, enforce backend-alias uniqueness inside a proxy group, and restrict proxy roles to Velocity-managed servers, so invalid network topology updates are rejected before they reach agents or proxies.
  • Drive drain-based move progression through managed-server command completion state, so successful move-drain and move-cutover transitions now update host assignment and rollback state without a second orchestration channel.
  • Match managed-server and agent-host owner/member UUID filters against binary and legacy UUID shapes, so newly created managed servers, proxy groups, memberships, and claimed agent hosts show up reliably in list endpoints instead of only through direct detail reads.

[2026.04.22] - Add agent host runtime metadata for managed servers

Added

  • Persist runtimeMode, hostingMode, platform, arch, and agent capabilities on Connect hosts, so the Public API can expose whether a host is native or a Docker-service host and whether it supports managed server hosting.
  • Include managed-server listen ports and host-issued Connect credentials in the host control plane, so direct agent hosts can bootstrap managed servers onto the canonical Connect/Gateway publishing path.

Changed

  • Reject managed-server host assignment to non-capable hosts and default legacy agent records to native plus direct, so old agent registrations keep working while the host model stays explicit.

[2026.04.22] - Add launcher performance telemetry ingestion

Added

  • Add POST /v1/launcher/performance-reports plus indexed structured Mongo storage for launcher launch-performance batches, so opt-in launcher telemetry can be ingested separately from feedback and queried by version, profile, runtime, platform, and outcome.

Changed

  • Validate launcher performance batches per report while preserving numeric step timings and partial optional hardware context, so malformed entries are dropped cleanly without turning timing data into opaque blobs.

[2026.04.21] - Add public Connect slug pages

Added

  • Add slug, publicSummary, publicProfileMode, and publicProfileShareCode to Connect networks plus a public GET /v1/public/connect/slugs/{slug} resolve endpoint, so managed join aliases can drive uebliche.gg/<slug> pages and launcher handoffs from one control-plane record.

Changed

  • Allow Connect network owners to patch public slug metadata separately from route ownership, so launch pages, recommended profiles, and non-custom-domain joins can be managed without touching gateway routing docs.
  • Treat resolved Connect slug pages as cache-safe public reads, so uebliche.gg/<slug> can sit behind shared edge caching without bypassing the Public API cache policy layer.
  • Default unverified Connect route hosts to the managed slug domain when a network slug exists, and auto-manage *.uebliche.gg plus _minecraft._tcp.<slug>.uebliche.gg records through dedicated Public API Cloudflare config, so slug.uebliche.gg works as both the canonical browser entry point and the actual Minecraft join address.

[2026.04.21] - Unify Connect collaboration and publications

Added

  • Add canonical Connect collaboration endpoints for server access policy, invites, invite acceptance, and unified publications under /v1/connect/publications/{targetType}/{targetId}, so Connect owns the full server collaboration surface instead of splitting it between connect and profile.

Changed

  • Move managed-server access policy persistence into a generic per-server Connect access document, so managed and externally claimed Connect servers resolve the same private / friends_only / public rules.
  • Resolve Connect collaboration rights from one shared server.* capability path across owners, explicit server members, and scoped roles on global, network, and server, so delegated groups and direct memberships no longer diverge.
  • Rename live listing status ingestion to /v1/connect/servers/{serverId}/publication/status and update server-target plus network-target publications from the same reporter snapshots, so publication updates use one consistent Connect flow.

[2026.04.21] - Report gateway client and target breakdowns

Changed

  • Attach normalized clientVersion and targetServerType dimensions to anonymized Public API traffic buckets and live samples, so uebliche.online can break gateway traffic down by launcher/browser version and by target type such as Community Server, Uebliche Server, or World Invite.
  • Classify world-share, managed-server, and community-connect routes into stable target-type buckets before reporting traffic, so dashboard charts reflect connection intent instead of raw endpoint names.

Added

  • Add GET /v1/public/mods/search to fan out launcher catalog searches to Modrinth and CurseForge from the Public API and return provider-tagged pages plus provider-specific warnings in one response.

Changed

  • Cache aggregated provider search pages inside the Public API and expose shared cache headers on the new endpoint, so repeated launcher searches hit the upstream providers far less often during burst traffic.

[2026.04.20] - Harden public API origin traffic

Changed

  • Add origin-side Nginx request, connection, timeout, and body-size guards in front of the Public API so abusive traffic is throttled earlier and large uploads only stay open on the explicitly allowed routes.
  • Keep the existing Public API cache headers as the source of truth while tightening origin handling, so safe public reads still benefit from upstream caches without adding a new Nginx proxy cache layer.

Removed

  • Remove GET /metrics from the Public API surface and stop scraping the Public API from the observability Prometheus stack, so Public API health reporting now relies on uebliche.online instead of a public Prometheus endpoint.

[2026.04.20] - Fix version asset proxy build regression

Fixed

  • Restore the missing version-asset download filename helper in the Public API download proxy, so the service builds again and /v1/public/versions/assets keeps returning stable attachment filenames for runtime and launcher artifacts.

[2026.04.20] - Add shared cache headers to safe public reads

Changed

  • Add centralized shared Cache-Control headers for safe anonymous GET/HEAD responses such as public news, MOTDs, user profiles, capes, skin-builder catalogs, world listings, and version resolve/stats reads, so repeat traffic can be served from upstream caches instead of always hitting Mongo.
  • Exclude personalized, random, token-bound, and download-tracking endpoints from the new shared cache policy, so favorites, public-server viewer state, ad-session tokens, and version/world download counters keep their current live behavior.

[2026.04.20] - Classify Cloudflare LB health checks

Changed

  • Detect Cloudflare Load Balancer health monitors as their own live-traffic agent type, either from Cloudflare's fixed Cloudflare-Traffic-Manager user-agent or from an explicit X-Uebliche-Agent-Kind / X-Uebliche-Traffic-Source header, so health checks no longer collapse into the generic unknown bucket in uebliche.online.
  • Forward GET /health monitor pings into the live traffic feed as sample-only healthcheck events, so Cloudflare LB checks appear in the feed without inflating the normal request counters, flow map, or heatmap statistics.
  • Reclassify headerless infrastructure and launcher-side requests by path fallback, so gateway heartbeats, voice-node heartbeats, internal status polls, and launcher fetches no longer flood the live feed as generic unknown entries.

[2026.04.20] - Add anonymized live traffic samples

Added

  • Attach a small rolling sample feed to the existing anonymized traffic-bucket ingest so uebliche.online can show masked client IPs alongside normalized client types such as Launcher, Browser, Bot, Gateway, or API client.

Changed

  • Classify the live traffic feed from x-uebliche-user-agent and user-agent headers instead of exposing raw user-agent strings, while keeping the existing aggregated bucket privacy model unchanged.

[2026.04.20] - Fix Version Artifact AccessDenied Redirects

Fixed

  • Stop sending version artifact downloads and version asset redirects straight to the public CDN when the versions bucket objects are not publicly readable, so runtime and launcher artifact downloads fall back to signed internal URLs instead of failing with S3 AccessDenied.
  • Serve version artifacts through the Public API asset endpoint when direct Space signatures are not reliable, so runtime downloads keep working even if the storage backend rejects presigned URLs with SignatureDoesNotMatch.
  • Fall back from authenticated storage reads to the public version CDN when the storage backend rejects a GET with 403, so already-public artifacts can still download through /v1/public/versions/assets.

[2026.04.20] - Restore Runtime Resolve Fallback

Fixed

  • Let filtered versions/resolve runtime lookups fall back to the newest published matching release even when the matching runtime artifacts are not part of the signed-service validation set, so runtime/windows-x64?javaVersion=21 resolves again instead of only working through the direct download endpoint.

[2026.04.20] - Fix Runtime Target Resolve Fallback

Fixed

  • Fall back to the newest published release that actually matches the requested target, Java version, loader, or Minecraft version when the channel head does not carry that artifact, so filtered versions/resolve and versions/download calls no longer return no_matching_artifact for valid runtime releases such as Windows runtime javaVersion=21.

[2026.04.20] - Fix shared GeoIP deploy packaging

Fixed

  • Package the shared libs/geoip/core crate into the Public API container build context, so Swarm rollouts can ship the shared GeoIP and traffic-reporting changes instead of failing during Docker build.
  • Reuse a stable PUBLIC_API_INSTANCE_ID per deployed region by default, so uebliche.online no longer grows phantom extra nodes after a Public API container restart or rollout.
  • Allow Public API heartbeats to advertise explicit node coordinates and region-specific location metadata, so uebliche.online can place nodes correctly even when the heartbeat reaches it from private Tailscale or Docker addresses that GeoIP cannot resolve.

[2026.04.19] - Add anonymized traffic bucket reporting

Added

  • Aggregate Public API request traffic into anonymized per-country buckets and push them to the private uebliche.online ingest endpoint for the new live world-map view.

Changed

  • Reuse the shared GeoIP / region module to resolve source countries and regions before reporting traffic, while collapsing very small buckets into other instead of exposing low-volume countries directly.

[2026.04.19] - Extend online regional status reporting

Added

  • Include per-region Public API metrics in the uebliche online heartbeat payload, including player totals, public-server counts, gateway totals, and active route counts.

Changed

  • Build the background uebliche online heartbeat from live Mongo-backed region snapshots instead of static process metadata only, so the dashboard can render one richer regional status row per API region.

[2026.04.19] - Restore sharded Mongo routing

Changed

  • Publish each Mongo config server on 27019/tcp and point mongos at the API nodes' Tailscale addresses, so the config replica set forms its quorum over stable host networking instead of flaky Swarm VIP routing.
  • Route every regional Public API deployment back through its local mongos service instead of the temporary direct mongo_mongo-shard-us override, so future rollouts return to the intended sharded topology.

Fixed

  • Reinitialize config-rs, re-register all three shards, and restore healthy mongos routers on eu, us, and ap, so /health is green again on every API node without the old 502 startup failures.

[2026.04.19] - Standardize API node Tailscale access

Added

  • Document a reproducible Public API node bootstrap that creates the shared deploy SSH user, adds it to the docker group, and installs the shared deploy key for Swarm rollouts.

Changed

  • Move Public API node SSH operations to the Tailscale path and treat public SSH as closed by default, so region hosts stay manageable without reopening direct Internet access.

[2026.04.19] - Add online heartbeat reporting

Added

  • Add an optional background heartbeat loop that lets every Public API instance report its node presence, build, region, and advertised endpoint to the new first-party uebliche online status service.

Changed

  • Add ONLINE_STATUS_* and PUBLIC_API_INSTANCE_ID runtime knobs to local and deploy project configuration so Public API nodes can be identified individually when reporting into uebliche online.
  • Route online heartbeats to a dedicated private heartbeat base URL and port instead of the public uebliche.online domain, and refuse the heartbeat loop when it is misconfigured back to the public host.

[2026.04.19] - Stabilize public API nginx upstream connections

Fixed

  • Stop sending Connection: upgrade to the Public API upstream on every HTTPS request, so normal HTTP traffic no longer triggers avoidable upstream connection resets and intermittent 502 responses on live API reads.
  • Raise the Public API nginx nofile limit in the swarm stack, so Cloudflare health checks and burst traffic no longer exhaust upstream sockets and degrade into intermittent 500/502 failures.

[2026.04.18] - Add synced saved public servers

Added

  • Add user_public_servers as the canonical per-user relation for synced saved servers plus favorites, including startup backfill from the legacy public_server_favorites collection and dedicated indexes for saved-order, favorites, and server counters.
  • Add authenticated saved-server endpoints:
    • GET /v1/profile/public-servers/saved
    • POST /v1/profile/public-servers/saved
    • DELETE /v1/profile/public-servers/saved/{serverId}
    • PUT /v1/profile/public-servers/saved/order
    • GET /v1/users/{id}/public-servers/saved
    • GET /v1/users/{id}/public-servers/favorites
  • Add GET /v1/public/public-servers/{id} for direct public-server detail reads with the same response shape as browse cards.
  • Add privacy.serverListVisibility (PUBLIC, FRIENDS, PRIVATE) to profile settings and seed the social:servers.read.others permission node for privacy overrides.

Changed

  • Extend public-server payloads with saved and savedPosition, and keep favorite plus denormalized favoriteCount available across browse, detail, profile, saved-list, and favorite-list responses.
  • Rewire legacy favorite endpoints to the new saved-server relation so POST /v1/public/public-servers/{id}/favorite auto-saves the server and DELETE only clears the favorite flag without removing the saved entry.
  • Stop filtering saved-server relations by homeRegion, so the saved order and favorite state stay stable across device and region changes while homeRegion remains stored only as routing metadata.

[2026.04.17] - Add extension release dependencies

Added

  • Accept first-class release dependencies on scoped version create/update payloads with provider, projectId, optional versionId, and kind.

Changed

  • Include dependencies in shared version release payloads, including GET /v1/public/versions/resolve and the internal release listing/read surfaces.

[2026.04.17] - Add version download stats

Added

  • Add version download stats endpoints:
    • GET /v1/public/versions/stats
    • GET /v1/versions/stats
  • Persist a raw downloadCount on version releases and backfill missing counters from historical version_events with event=download.

Changed

  • Include downloadCount in shared version release payloads, including GET /v1/public/versions/resolve and the internal release listing/read surfaces.

[2026.04.17] - Require signed launcher support model artifacts

Changed

  • Treat service/launcher-support-llm as a signed release scope in the Versions API, so published model releases are now rejected unless every artifact carries sha256, signature, and metadata.signatureFormat=sha256-hex-ed25519.
  • Keep the existing runtime and guard-agent signed-artifact policy unchanged while extending the manifest/resolve pipeline to recognize the new signed launcher model service.

[2026.04.15] - Restore version upload bucket secrets

Fixed

  • Wire the Public API swarm stack to dedicated VERSIONS_S3_*_FILE secrets for the updates-uebliche bucket and document the separate version-storage envs again, so POST /v1/versions/uploads can write launcher release artifacts without silently falling back to the shared CDN credentials.
  • Capture internal_error(...) failures and background version-cleanup storage errors as explicit Sentry events, so broken version uploads and bucket-permission regressions are visible even when they only surface as server-side 500 responses.

[2026.04.15] - Accept profile sync ids in playtime sessions

Changed

  • Accept optional profileSyncId on authenticated launcher playtime session uploads and persist it with each stored launcher session, so launcher clients can prepare a stable future cloud profile join key without breaking older upload payloads.

[2026.04.14] - Add system daily ad quest flow

Added

  • Add authenticated ad-session endpoints plus public browser-hub endpoints for the platform-owned system_ad daily quest, including signed launch tokens, TTL validation, rate limiting, and one-shot rewarded claims.
  • Seed one active daily-google-rewarded system campaign with browser-hub launch metadata and persist ad-session documents plus supporting indexes so the shared quest domain can host ad-backed dailies without sponsor authoring.

Changed

  • Extend quest campaign, quest state, and profile-settings payloads with system_ad metadata and a dedicated daily summary block so launcher clients can render availability, active sessions, completion state, and next eligibility directly from the normal quest API.
  • Serialize system_ad participation against the current UTC day instead of raw lifetime completions, while still crediting the normal quest wallet and ledger exactly once when a rewarded browser event is accepted.

[2026.04.14] - Persist tracked quest state

Added

  • Add GET/PUT /v1/quests/tracked plus POST /v1/connect/servers/{serverId}/quests/resolve-tracked, so launcher clients can persist one tracked quest per user and Connect servers can validate tracked quest replies before routing players.

Changed

  • Mark visible quest campaign payloads with tracked, extend quest state and profile settings with trackedCampaignId, and reject tracked-quest resolve requests unless the campaign is still active, audience-eligible, and owned by the requesting Connect network.

Changed

  • Include connectNetworkId on public server directory responses, so launcher surfaces can attach visible sponsored quests to the correct server cards and focus views.

[2026.04.14] - Add sponsored quest APIs

Added

  • Add a dedicated quest domain with sponsor budgets, campaign authoring, user wallet, reward redemption, and connect-server quest event ingestion so sponsored and ad-backed quests can run through one shared Public API surface.

Changed

  • Add structured audience scope to quest campaigns with geoScopeKind, geoScopeValue, and localeAllowlist, and expose the resolved user eligibility context with persistent homeRegion, homeCountry, and preferredLocale.
  • Persist preferredLocale in profile settings and extend profile settings responses with current quest wallet and active supporter-light reward state so clients can render quest-related account state without custom storage.

[2026.04.13] - Add public cape domain

Added

  • Add public, profile, and admin cape endpoints for uploads, moderation, upload-term acceptance, account-bound selection, and public selection resolution for launcher and mod clients.

Changed

  • Validate uploaded cape textures as PNG-only Minecraft cape layouts and keep Mojang capes outside the Public API so uebliche remains the only API-backed cape source in v1.

[2026.04.13] - Filter version artifacts by Java line

Changed

  • Accept javaVersion on public version resolve/download requests and use artifact metadata to select the matching release asset, so service/runtime can publish multiple Java-major variants for the same channel and platform without splitting them into separate releases.

[2026.04.13] - Restore launcher version bucket

Fixed

  • Point Public API version downloads back at the updates-uebliche bucket, use its direct public URLs for launcher artifacts, and wire separate version-bucket credentials so launcher release uploads and self-update downloads stop failing with broken presigned redirects, 403 responses, or upload-side 500 errors.
  • Build the Public API Docker image with a lower-memory linker setup (lld plus reduced linker memory flags), so the launcher updater hotfix can actually ship from the local deploy pipeline instead of dying during the final release link step.

[2026.04.12] - Add scheduled launcher featuring

Added

  • Add permanent and time-window-based featuring for Connect public servers plus admin-managed profile shares, including featuredStartsAt, featuredEndsAt, and computed featuredActive fields in the relevant API responses.

Changed

  • Add admin:profile-share:edit permission handling and persist launcher highlight metadata on profile shares and public server listings so admin and launcher clients can render one consistent featured state.

[2026.04.12] - Add device-code service exchange flow

Added

  • Add flow=device_code support to POST /v1/auth/service/exchange plus GET /v1/auth/service/exchange/resolve, so native clients can show a short-lived verification code instead of relying on a browser redirect or native callback.

Changed

  • Store service-exchange flow metadata and hashed user codes alongside the existing poll token, while keeping the browser-based exchange contract backward compatible for current callers.

[2026.04.12] - Prune superseded version artifacts

Changed

  • Run a background cleanup for stable version channels so non-active releases older than seven days drop artifacts that have been superseded by newer target/loader/Minecraft combinations, while keeping the newest remaining coverage per combination.
  • Remove stale version artifact references when their s3Key no longer exists in storage, and delete empty historical release documents after pruning.

Fixed

  • Delete stored version artifact objects when a release is removed, so manual release cleanup now frees the corresponding S3 space instead of leaving orphaned files behind.

[2026.04.12] - Add managed server control plane

Added

  • Add managed server product models and profile endpoints for templates, plans, instances, invites, access policies, install jobs, world-transfer jobs, and capability catalog reads.
  • Add a Connect-facing managed-access read endpoint plus new database indexes for server instances, invites, jobs, and member lookups so hosts and clients can resolve one stable server control plane.

Changed

  • Extend Connect member payloads and permission checks with explicit capability lists, so delegated server roles can grant invite, install, moderation, lifecycle, and world-transfer rights without hardcoding everything into one role.
  • Enforce server-target compatibility for install jobs by loader and respect inviteRequiresDirectFriend on friends-only invite flows, while returning sorted effective capability lists for stable launcher/mobile rendering.

[2026.04.12] - Finalize social friends and chat surface

Added

  • Add a dedicated Chat API reference page covering direct/group conversation creation, message snapshots, attachments, polls, and the thread live endpoint.

Changed

  • Expand the Friends API reference with block, report, and live snapshot flows so launcher and mobile clients can target the full shipped social surface without falling back to Dash-specific knowledge.
  • Add unit coverage for social friends/chat helper normalization paths so participant ids, note/visibility sanitization, attachment decoding, and mention canonicalization stay stable across future API changes.

[2026.04.12] - Restore CurseForge proxy secret wiring

Fixed

  • Mount the shared curseforge_api_key swarm secret into the Public API stack and export CURSEFORGE_API_KEY_FILE, so /v1/public/curseforge/* requests authenticate against CurseForge again instead of failing every launcher lookup with 403 Forbidden.

[2026.04.11] - Add polled service exchanges

Added

  • Add a short-lived POST /v1/auth/service/exchange flow plus poll and complete endpoints so local apps can finish uebliche.net service logins without receiving auth tokens over custom-scheme redirects.

Changed

  • Let Dash-backed service consent requests complete against a stored pending exchange, while the legacy redirect-based /v1/auth/service/token flow stays available for existing clients.

[2026.04.11] - Align shared content bucket wiring

Fixed

  • Point the Public API swarm stack back at the shared cdn.uebliche content bucket and re-enable path-style S3 writes, so personal totem assets, version artifacts, and world storage stop defaulting into the legacy personal-totem bucket.
  • Refresh the Public API stack docs and example env file to match the current shared CONTENT_S3_* storage wiring and CDN endpoint.
  • Reject version artifact uploads that target reserved shared-content prefixes such as totem/, chat/, feedback/, and worlds/, so admin release metadata cannot overwrite unrelated content in the shared bucket.

[2026.04.11] - Expose highest role label on profile self

Changed

  • Extend GET /v1/profile/self with highestRoleLabel, resolved from the authenticated user's assigned non-default roles by descending role weight so launcher clients can show a rank label without fetching admin role endpoints.
  • Expose weight on admin role list/create/update payloads and user-role listings so dashboard and admin clients can edit and reuse the same role priority the launcher label selection depends on.

[2026.04.11] - Expose world cloud storage usage

Added

  • Add GET /v1/profile/worlds/storage so authenticated launcher clients can load used bytes, optional quota, remaining bytes, usage ratio, and world count for cloud world backups.

[2026.04.11] - Move world storage onto storageWorldId keys

Changed

  • Store world manifests and blobs under a server-side storageWorldId namespace so S3 keys now use worlds/<storageWorldId>/... instead of leaking the owner UUID into the path.
  • Persist storageWorldId across world documents, versions, blob refs, shares, publications, and upload drafts so the public World API keeps one stable internal storage identity per world.

Fixed

  • Run a startup migration that rewrites existing world manifest and blob objects into the new storageWorldId key layout before the API starts serving requests, so the hard cut-over does not need runtime legacy fallbacks.
  • Skip missing legacy world objects during that startup migration, so one broken historical key no longer aborts the whole API rollout.
  • Serialize the local Public API release build to one Cargo job in Docker so the deployment image can still be produced on the current 8 GB build host without running into linker OOM kills.

[2026.04.11] - Restore API deploy wiring

Fixed

  • Restore the Public API build by wiring the in-memory voice runtime back into AppState, so social voice registration, session updates, and live streams compile and run again.
  • Restore the public CurseForge proxy handlers and their optional shared API key config, so /v1/public/curseforge/* requests build and forward upstream responses again.
  • Re-add the missing voice models and database indexes, and drop stale handler exports that no longer have backing endpoints, so the API crate deploys cleanly again.
  • Let the local Public API deploy script switch to buildx with an insecure-registry push path, so local rollouts work against the current plain-HTTP private registry without reconfiguring Docker Desktop first.
  • Move Public API content uploads and CDN URL generation back onto the shared CONTENT_S3_* configuration, using the shared cdn.uebliche.info endpoint and path-style S3 writes for the dotted cdn.uebliche bucket.
  • Store new personal-totem assets under totem/<modelId>.<ext> so itemModelUrl stays namespaced on the shared CDN instead of leaking into the bucket root.

[2026.04.09] - Read-only support probes

Changed

  • Allow GET /v1/public/versions/resolve callers to pass trackSupportRequest=false so automation can probe Minecraft-version support without creating a synthetic support-request event during planning or dry runs.

[2026.04.09] - Track missing version support requests

Added

  • Create a deduplicated support-request version event automatically when GET /v1/public/versions/resolve is asked for a minecraftVersion that has no matching published artifact or no release at all.

Changed

  • Return a supportRequest hint in public version resolve responses for missing Minecraft-version support so callers and automation can tell whether the request was newly accepted or deduplicated.
  • Accept optional source and client query parameters on public version resolve requests and persist them with generated support-request events for later automation and triage.

[2026.04.08] - Add version coverage matrix checks

Added

  • Add internal POST /v1/versions/coverage so admin callers can inspect per-release coverage across targets, loaders, and Minecraft version ranges without creating a separate persisted matrix.
  • Expand Minecraft version ranges from the official Mojang catalog, with optional inclusion of snapshots, pre-releases, and release candidates for coverage checks.

Changed

  • Persist first-class minecraftVersions on uploaded version artifacts and expose them in release responses so coverage, resolve, download, and manifest generation all use the same explicit artifact compatibility data.
  • Keep public version resolution backward compatible by falling back to legacy metadata.minecraftVersion only when an artifact does not yet provide first-class minecraftVersions.

[2026.04.08] - Add server-managed voice channel control

Added

  • Add PUT /v1/social/voice/channels/{channelId}/control so trusted servers can fully replace serverMutes and serverGroups for an existing voice channel.
  • Accept either Connect server credentials (X-Server-Id + bearer secret) or the shared UEBLICHE_SOCIAL_API_TOKEN for server-side voice control writes.

Changed

  • Include per-user serverMuted and serverGroupId fields in voice join, sync, and live payloads so clients can reflect authoritative server voice state without downloading the full control matrix.
  • Emit live voice updates with an explicit channelId, so clients can reconnect or clear only the affected route on leave and recovery events.

[2026.04.06] - Retry Minecraft join verification

Fixed

  • Retry Mojang hasJoined lookups for a short window before failing the join-token exchange, so launcher and mod session verification no longer breaks on brief upstream propagation lag right after join.
  • Treat empty hasJoined responses as a missing join instead of crashing the parser, so failed Minecraft session checks now return a stable auth error instead of an internal parse failure.

[2026.04.05] - Publish public extension catalog reads

Added

  • Add GET /v1/public/connect/extensions and GET /v1/public/connect/extensions/{extensionId} as public read-only catalog endpoints for launcher browse integrations.

Changed

  • Sort public extension catalog entries by name and extension id before returning them, so launcher browse results stay stable across repeated loads.

[2026.03.19] - Filter version artifacts by Minecraft version

Added

  • Add optional minecraftVersion support to the public versions resolve and download endpoints so clients can request the correct artifact for a specific Minecraft version inside one shared release.

Changed

  • Match version artifacts against metadata.minecraftVersion in addition to loader and target filters, and return no artifact instead of a mismatched file when the requested Minecraft version is missing.
  • Write versioned static update manifests such as update-fabric-1.21.11.json while keeping an unversioned alias per target for backward compatibility.

[2026.03.17] - Add Modrinth public proxy

Added

  • Add GET /v1/public/modrinth/{*path} as a transparent Modrinth v2 proxy for launcher catalog lookups and metadata reads.
  • Add optional MODRINTH_API_TOKEN / MODRINTH_API_TOKEN_FILE support so the proxy can authenticate upstream requests when the deployment provides a shared token.

Changed

  • Forward Modrinth query strings and selected response headers unchanged through the public proxy so launcher clients can consume the native Modrinth payloads without a second normalization layer.
  • Prefer a caller Authorization header over the shared server token when both are present, so explicit user-authenticated requests keep their own upstream identity.
  • Wire an optional shared CURSEFORGE_API_KEY / CURSEFORGE_API_KEY_FILE through the Public API runtime and deployment configs so the CurseForge proxy can authenticate upstream requests without hardcoding a key in the repo.

[2026.03.17] - Publish launcher guard allowlist

Added

  • Add GET /v1/public/launcher/network-guard-allowlist as a public read-only endpoint for the hosted launcher Network Guard allowlist.

Changed

  • Read the launcher guard allowlist directly from Mongo, expose only enabled public fields, and support ETag/If-None-Match caching for launcher syncs.

[2026.03.17] - Add GeoIP endpoint to the public API

Added

  • Add GET /v1/ip/geo as a permission-gated GeoLite2 lookup endpoint for caller or explicit IP addresses.
  • Add the permission node ip:geo.read so users, roles, and service grants can authorize GeoIP access.
  • Add PUBLIC_API_GEOIP_CITY_DB_PATH to configure the GeoLite2 city database path for the Public API.

Changed

  • Allow the seeded uebliche.dev service to request ip:geo.read during consent and service-token issuance.

[2026.03.16] - Persist voice runtime and hard-switch to voice-node

Added

  • Add POST /v1/social/voice/channels/party so clients can bootstrap the caller's current party voice channel through the social voice control plane.
  • Add persisted Mongo collections and indexes for voice nodes/channels so session state survives Public API restarts.
  • Add encrypted-at-rest voice channel secrets with server-side decryption only for live session/node payloads.
  • Ensure the built-in Connect extension catalog entry social exists when missing so Connect servers can publish the social bridge without a manual catalog create step first.

Changed

  • Replace in-memory voice runtime state with Mongo-backed voice node/channel persistence, heartbeat pruning, lease-based member cleanup, and recovery-driven reassignment.
  • Extend voice session/live/node payloads with sessionVersion so clients can ignore stale assignments and reconnect only on newer voice runtime changes.
  • Build user and node live snapshots from persisted voice channel state instead of process-local memory.

Removed

  • Remove the old assumption that the Public API must keep voice runtime state alive in RAM to keep sessions valid.

[2026.03.15] - Enforce signed runtime artifacts

Changed

  • Require signature and sha256 on service/runtime version artifacts before a runtime release can be created, updated, activated, or resolved as current.
  • Keep runtime artifact signatures in the normal version release payload so launcher clients can verify runtime.tar.zst directly from GET /v1/public/versions/resolve.
  • Include runtime signatures in generated non-global update manifests for parity with the normal resolve payload.

[2026.03.15] - Add CurseForge public catalog proxy

Added

  • Add public CurseForge catalog routes for normalized launcher access:
    • GET /v1/public/curseforge/search
    • GET /v1/public/curseforge/projects/{projectId}
    • GET /v1/public/curseforge/projects/{projectId}/files
    • GET /v1/public/curseforge/projects/{projectId}/files/{fileId}

Changed

  • Normalize CurseForge search, project, and file responses into the shared launcher catalog shape so the client can reuse the same UI and provider abstractions as Modrinth.
  • Forward CurseForge project links and browser download URLs through the proxy response so launcher browser-required installs can jump straight to the correct website flow.

Fixed

  • Build CurseForge file browser URLs from the project slug instead of the numeric project id so browser-required downloads resolve to valid CurseForge pages.
  • Keep CurseForge project detail responses populated with source and issue links instead of dropping them during proxy normalization.

[2026.03.15] - Unified content storage config

Changed

  • Replace split storage envs (PERSONAL_TOTEM_S3_*, VERSIONS_S3_*, VERSIONS_PUBLIC_BASE_URL) with a single shared CONTENT_S3_* configuration for public API uploads/downloads.
  • Resolve personal totem and version artifact URLs from the shared content CDN endpoint (CONTENT_S3_PUBLIC_ENDPOINT).
  • Require s3Key metadata for public version download URL resolution.

Removed

  • Remove legacy fallback URL rewriting for old artifact hosts in the public version downloader.

[2026.03.13] - Service to extension migration endpoint

Added

  • Add POST /v1/services/{serviceId}/migrate-extension to migrate a service into a Connect extension catalog entry.

Changed

  • Migrate scoped version data from service to extension for matching scope ids across:
    • version_releases
    • version_channels
    • version_events
  • Migrate catalog scopes from service to extension when referenced by the migrated service slug/id.
  • Support optional service cleanup after migration (deleteService) including service grant removal.

[2026.03.07] - Voice control-plane MVP routes

Added

  • Add social voice node registration routes for regional runtime discovery:
    • POST /v1/social/voice/nodes/register
    • POST /v1/social/voice/nodes/{nodeId}/heartbeat
    • DELETE /v1/social/voice/nodes/{nodeId}
    • GET /v1/social/voice/regions
  • Add social voice session routes for private/group/proximity channel bootstrap:
    • POST /v1/social/voice/channels/private
    • POST /v1/social/voice/session/join
    • POST /v1/social/voice/session/sync
    • POST /v1/social/voice/session/leave
  • Add live websocket stream for voice session updates:
    • GET /v1/social/voice/live
  • Add permission seed nodes for voice access and node auth:
    • social:voice.read
    • social:voice.write
    • social:voice.manage
    • social:voice.node

Changed

  • Extend Public API runtime state with in-memory voice node/channel registries and per-user voice event streams.
  • Add channel-secret issuance and recipient resolution logic for no-server-support proximity routing (worldId + visiblePlayers).

[2026.02.28] - Scoped versioning for services and extensions

Added

  • Add scoped version release APIs:
    • GET /v1/versions/releases
    • POST /v1/versions/releases
    • GET /v1/versions/releases/{releaseId}
    • PATCH /v1/versions/releases/{releaseId}
    • DELETE /v1/versions/releases/{releaseId}
  • Add active-channel management for scoped releases:
    • GET /v1/versions/channels/active
    • POST /v1/versions/channels/active
  • Add public version resolve endpoint for clients:
    • GET /v1/public/versions/resolve
  • Add version event ingestion and listing:
    • POST /v1/public/versions/events
    • GET /v1/public/versions/download
    • GET /v1/versions/events
  • Add persisted version collections with indexes:
    • version_releases
    • version_channels
    • version_events
  • Add permission seed nodes for version operations:
    • versions:read
    • versions:write
    • versions:publish
    • versions:track

Changed

  • Enforce scope-aware version workflows via scope.type + scope.id with validation for service and extension scopes.
  • Make channel activation explicitly assign the active release pointer per scope+channel, enabling roll-forward/rollback by pointer update.

[2026.02.20] - Add profile UI style settings payload

Added

  • Extend profile settings request payload with uiStyle support (syncEnabled, source, payload) for cross-app style sync.

Changed

  • Extend GET /v1/profile/settings response with uiStyle metadata and payload.
  • Extend PATCH /v1/profile/settings to persist uiStyle updates with updatedAt tracking and default source handling.

Fixed

  • Validate uiStyle payload shape and size before storing to prevent invalid or oversized style documents.

[2026.02.20] - News polls and chat legacy compatibility

Added

  • Add poll support to news entries with question, options, vote state, and duration (durationMs) including computed expiry (expiresAt) and total vote counts.
  • Add POST /v1/news/{newsId}/poll/vote so authenticated users can vote on published, released news polls.

Changed

  • Extend GET /v1/news, GET /v1/news/feed, and GET /v1/public/news responses with a poll payload including per-option vote counts and viewer selection state.
  • Extend POST /v1/news and PATCH /v1/news/{newsId} to accept an optional poll definition with validated options and bounded duration.

Fixed

  • Load social chat conversations for users across legacy participant id encodings (UUID binary, generic binary, and string UUID values).
  • Prevent malformed legacy conversation rows from failing the full conversation list by skipping invalid entries instead of aborting the request.
  • Add compatibility parsing for find_conversation so message/thread endpoints can resolve older conversation documents.

[2026.02.20] - Add social chat polls and voting

Added

  • Add poll fields to social chat message payloads for live and archived messages (poll.question, poll.options, selection state, total votes, expiry, closed state).
  • Add POST /v1/social/chat/conversations/{conversationId}/messages/{messageId}/poll/vote to submit poll votes for chat participants.

Changed

  • Allow POST /v1/social/chat/conversations/{conversationId}/messages to create poll-only messages (without text content).
  • Validate poll input on message creation (required question, unique option labels, option count limits, optional future expiry).
  • Set conversation preview text for poll and attachment-only messages so conversation list updates stay informative.

[2026.02.19] - Friend accept write conflict fix

Fixed

  • Fix POST /v1/social/friends/requests/{id}/accept failing with Freundschaft konnte nicht erstellt werden. in mobile and launcher.
  • Remove conflicting userId/friendId updates from the friend-link upsert ($set + $setOnInsert on same fields), which caused MongoDB write error code 40.

[2026.02.19] - Friends listing legacy UUID compatibility

Fixed

  • Load friendships, outgoing requests, and friend-related user summaries with UUID-compatible queries (Uuid + legacy binary formats) so existing relations are visible again.
  • Make friend metadata updates/removal and relationship cleanup work with legacy UUID-encoded rows.
  • Normalize both friendship directions to canonical userId/friendId fields during upsert to self-heal stale rows over time.

[2026.02.19] - Friendship self-healing on request/accept

Fixed

  • Heal asymmetric friendship rows automatically during friend request creation and request acceptance.
  • If one friendship direction already exists, the API now upserts the missing reverse direction so both users see the same friendship.
  • Prevent Ihr seid bereits befreundet. without a visible friend entry by reconciling stale data before returning the validation error.

[2026.02.18] - Friend acceptance duplicate safety

Fixed

  • Prevent Freundschaft konnte nicht erstellt werden. on friend request acceptance when historic/region-shifted friend link rows already exist.
  • Make friend-link creation idempotent by upserting both friendship directions instead of inserting hard-fail duplicates.
  • Use a global friendship existence check before creation to avoid region-filter false negatives.

[2026.02.18] - Friends region fallback for reads

Fixed

  • Prevent empty Friends and incoming-request lists caused by stale homeRegion filtering.
  • Add a fallback path for social reads: if region-scoped friend links or incoming requests are empty, the API now retries with an unscoped user query.

[2026.02.18] - Presence fields in self profile

Changed

  • Extend GET /v1/profile/self to return online, status, and lastSeenAt from the profile document so clients can render self presence without extra public-user lookups.

Changed

  • Extend GET/PUT/DELETE /v1/admin/discord/role-links with optional guildId selection so role mapping can target a linked Discord server without requiring DISCORD_ROLE_SYNC_GUILD_ID.
  • Return linked Discord guild candidates in role-link responses and auto-fallback to the first manageable linked guild when no guild is preconfigured.
  • Keep role-link status read-only with clear reasons instead of hard failing when guild selection or bot token configuration is missing.

[2026.02.18] - Network Discord server linking

Added

  • Add Connect network Discord endpoints:
    • GET /v1/connect/networks/{networkId}/discord
    • PUT /v1/connect/networks/{networkId}/discord
    • DELETE /v1/connect/networks/{networkId}/discord
  • Persist Discord guild link metadata directly on connect networks (discord.guildId, name/icon fields, linked/update timestamps).

Changed

  • Extend Discord OAuth linking payloads with a guild snapshot list (settings.discord.guilds) including administrator capability flags.
  • Enforce network Discord linking rules in the API:
    • linked Discord account is required,
    • user must have Administrator on the selected guild,
    • configured bot must already be present in the selected guild.

Added

  • Add admin endpoints to manage Discord role links for permission roles:
    • GET /v1/admin/discord/role-links
    • PUT /v1/admin/discord/role-links/{roleId}
    • DELETE /v1/admin/discord/role-links/{roleId}
  • Add persistence for Discord role links (discord_role_links collection) with dedicated Mongo indexes.
  • Add permission seed nodes for Discord role link administration: admin:discord-role-link:view and admin:discord-role-link:manage.

Changed

  • Add Discord server rights enforcement for role linking: API now requires Discord Manage Roles (or Administrator) for the current linked account plus bot-side role-management capability.
  • Extend API runtime config with Discord role-sync settings:
    • DISCORD_ROLE_SYNC_GUILD_ID (fallback to supporter guild)
    • DISCORD_ROLE_SYNC_BOT_TOKEN (fallback to catalog bot token)
  • Add permission catalog descriptions for the new Discord role link admin nodes.

[2026.02.18] - Discord account linking for profile settings

Added

  • Add Discord OAuth profile linking endpoints: POST /v1/profile/settings/discord/link, DELETE /v1/profile/settings/discord/link, and callback GET /v1/auth/discord/callback.
  • Extend profile settings payloads with a discord section that includes linked account metadata and optional guild sync state (inGuild, boosting, role-based rank labels).
  • Add Discord OAuth runtime configuration keys: DISCORD_OAUTH_CLIENT_ID, DISCORD_OAUTH_CLIENT_SECRET, DISCORD_OAUTH_REDIRECT_URI, DISCORD_OAUTH_SCOPES, DISCORD_OAUTH_DASH_REDIRECT, DISCORD_SUPPORTER_GUILD_ID, and DISCORD_SUPPORTER_ROLE_MAP.

Changed

  • GET /v1/profile/settings now returns both patreon and discord provider sections in one response model.
  • Add public-api stack env support for Discord OAuth settings so the flow can be configured in production without code changes.

[2026.02.18] - Supporter listing preferences

Added

  • Extend profile settings payloads with a supporter section to store supporter listing flags (listed, showTier) and optional supporter card customizations (customMessage, designPreset, designAccent).
  • Add a public supporters endpoint GET /v1/public/supporters that returns all opted-in active supporters for launcher/dashboard use.

Changed

  • GET /v1/profile/settings now returns supporter capability metadata (canUseCustomMessage, canUseCustomDesign) and minimum supporter amounts for gated customization features.
  • PATCH /v1/profile/settings now validates supporter customization by supporter tier amount and rejects custom message/design updates below required thresholds.

[2026.02.17] - Friend acceptance sender notification

Added

  • Create a notification for the original sender when a friend request is accepted.

Changed

  • POST /v1/social/friends/requests/{id}/accept now upserts a friend_accepted notification entry for the request sender with a direct Friends deeplink.

[2026.02.17] - Social profile moderation APIs

Added

  • Add GET/POST/DELETE /v1/social/friends/blocks endpoints to list, create, and remove user blocks.
  • Add POST /v1/social/friends/reports to report user profiles with optional reason text.

Changed

  • Prevent friend requests/acceptance between blocked users.
  • Blocking a user now removes existing friendship links and pending requests in both directions.

[2026.02.17] - Public user profile lookup

Added

  • Add a public user lookup endpoint GET /v1/public/users/{identifier} that resolves by username or UUID.
  • Return normalized profile metadata (userId, name, regions, created/seen timestamps, and allowFriendRequests) for dashboard/public profile views.

[2026.02.17] - Profile settings auth baseline

Fixed

  • Allow authenticated users to access profile settings endpoints without explicit profile:read permission checks (GET/PUT /v1/profile/settings, POST/DELETE /v1/profile/settings/patreon/link, GET/PUT /v1/profile/minecraft-options).
  • Prevent false Patreon "not configured" behavior for users blocked by permission gating.

[2026.02.17] - Patreon profile linking

Changed

  • Extend GET /v1/profile/settings with a patreon object that reports availability, link status, and linked Patreon profile/membership data.

Added

  • Add profile Patreon OAuth routes for linking and unlinking: POST /v1/profile/settings/patreon/link, DELETE /v1/profile/settings/patreon/link, and callback GET /v1/auth/patreon/callback.
  • Add Patreon OAuth runtime configuration via env vars: PATREON_CLIENT_ID, PATREON_CLIENT_SECRET, PATREON_REDIRECT_URI, PATREON_SCOPES, and PATREON_DASH_REDIRECT.

[2026.02.17] - Personalized news feed follows

Added

  • Add authenticated news feed routes for profile-based follow preferences: GET /v1/news/feed, GET /v1/news/follows, and PUT /v1/news/follows.
  • Persist followed project feeds per user in settings.newsFollowProjects and auto-create missing user docs before writes.

Changed

  • GET /v1/news/feed now combines global news with published service news for the user's followed project list.
  • Apply release-date filtering (releaseDate <= now) directly in the feed query and return follow metadata (projects, configured) with the feed response.
  • Add feed cache metadata (lastChangedAtMs) and lightweight delta checks via sinceMs query param. Unchanged feed responses now return notModified=true with an empty items array.

[2026.02.17] - Service deletion endpoint

Added

  • Add DELETE /v1/services/{serviceId} so service owners (or super admins) can remove services.

Changed

  • Remove related service consent grants when a service is deleted.
  • Remove deleted service references from catalog service scopes (catalogScopes[type=service]).

[2026.02.17] - Catalog scopes and scoped random routing

Added

  • Add catalogScopes on catalog payloads (GET/POST/PUT /v1/catalogs) with scope support for global, service, extension, network, and server.
  • Validate catalog scopes against existing entities (service/extension/network/server) when catalogs are created or updated.
  • Add a catalog scope index (catalog_scope_enabled_idx) to speed up enabled scoped catalog lookups.

Changed

  • Extend random catalog endpoints with optional scope filters: scope and scopeId (/v1/public/catalogs/{catalogSlug}/random, /v1/head/random, /v1/banner/random).
  • Resolve random catalog responses scope-aware with fallback order: exact scope match, then global catalog, then newest enabled fallback.

[2026.02.16] - API usage metrics per service

Added

  • Expose Prometheus metrics at GET /metrics in the public API runtime.
  • Add per-service API usage metrics: request rate (public_api_service_requests_total) and latency histogram (public_api_service_request_duration_seconds).

Changed

  • Track API usage labels from service auth context (serviceSlug/serviceId) so Grafana can break down traffic by service.
  • Extend observability with a dedicated Prometheus scrape job for all public API regions (eu, us, ap).
  • Add Grafana panels for API usage by service, p95 latency by service, 5xx error rate by service, and request rate by status.

[2026.02.16] - Dynamic service domains and catalogs

Changed

  • Make CORS origin validation dynamic: browser origins are now matched against verified service allowedDomains entries instead of static one-off code paths.
  • Keep /v1/head/random and /v1/banner/random, but resolve them through enabled catalog aliases (head/banner) at runtime.
  • Replace Discord command sync endpoint with /v1/discord/catalog/commands and resolve head data from the configured catalog source.
  • Extend service payloads (GET/POST/PUT /v1/services) with allowedDomains.

Added

  • Add catalog management endpoints: GET/POST /v1/catalogs, GET/PUT/DELETE /v1/catalogs/{catalogId}.
  • Add public random endpoint for custom catalogs: GET /v1/public/catalogs/{catalogSlug}/random.
  • Add Mongo indexes for catalogs and service allowedDomains.

Removed

  • Remove hardcoded brand-specific API paths/config bindings from the runtime implementation.

[2026.02.16] - Gateway DNS automation

Added

  • Add automatic Cloudflare DNS sync for gateway endpoints under CONNECT_GATEWAY_DNS_BASE_DOMAIN (for example gateway.uebliche.net and <gatewayId>.gateway.uebliche.net) on gateway heartbeat/admin updates.
  • Add optional gateway DNS env config (CONNECT_GATEWAY_DNS_BASE_DOMAIN, CONNECT_GATEWAY_CLOUDFLARE_ZONE_ID, CONNECT_GATEWAY_CLOUDFLARE_API_TOKEN).

Changed

  • POST /v1/connect/networks/{networkId}/domains now returns gateway CNAME instructions (<domain> -> gateway.uebliche.net) and auto-manages the record when Cloudflare DNS automation is configured for the same zone.
  • PUT /v1/connect/networks/{networkId}/dns/cloudflare now attempts to sync gateway CNAME records for already claimed domains in that network.

[2026.02.16] - Connect gateway control APIs

Changed

  • Seed new Connect gateway admin permission nodes (admin:connect:gateway:view, admin:connect:gateway:manage).

Added

  • Add gateway control-plane endpoints for register + heartbeat (POST /v1/connect/gateways/register, POST /v1/connect/gateways/{gatewayId}/heartbeat).
  • Add Connect-server gateway endpoints to list targets and publish/remove active route ownership (GET /v1/connect/servers/{serverId}/gateways, PUT/DELETE /v1/connect/servers/{serverId}/gateway-route).
  • Add admin Connect gateway endpoints for Dash inventory and control (GET /v1/admin/connect/gateways, GET /v1/admin/connect/gateway-routes, PATCH /v1/admin/connect/gateways/{gatewayId}).
  • Add persisted gateway metadata and route collections with indexes/TTL cleanup for stale route entries.
  • Add Connect network Cloudflare DNS config endpoints (GET/PUT/DELETE /v1/connect/networks/{networkId}/dns/cloudflare) for token+zone managed automation.

Changed

  • GET /v1/connect/servers/{serverId}/gateways now includes a preferred routeHost hint (verified network domain when available, fallback to <serverId>.connect.gateway).
  • PUT /v1/connect/servers/{serverId}/gateway-route now defaults routeHost to the network's verified domain (if present) before falling back to <serverId>.connect.gateway.
  • POST /v1/connect/networks/{networkId}/domains now auto-upserts _uebliche.<domain> TXT records via Cloudflare when configured.
  • PUT /v1/connect/servers/{serverId}/gateway-route now auto-upserts Cloudflare A records for route hosts within the configured zone.
  • Cloudflare API tokens configured via Connect DNS automation are now encrypted at rest, with legacy plaintext values migrated on read.

[2026.02.14] - Skin builder part deletion

Added

  • Add DELETE /v1/admin/skin-builder/parts/{id} to remove skin builder community parts (permission admin:skin-builder-parts:delete).
  • Add the admin:skin-builder-parts:delete permission node to the permission catalog/seed.

[2026.02.13] - Role permission grants

Added

  • Expose permissionGrants on role payloads so permissions can carry numeric/amount values (e.g. power or quotas).

Fixed

  • Mark .power permission nodes as numeric schemas for admin editors.

[2026.02.09] - Validation hardening

Fixed

  • Validate role slugs/names and enforce scopeId existence for network/server/service/extension scoped roles.
  • Validate shop catalog scopes against existing Connect/Service/Extension entities.
  • Validate shop permission grants against the permission catalog (known nodes + correct value schema) and reject invalid durations/intervals.

[2026.02.09] - Connect scope ID normalization

Fixed

  • Normalize admin Connect network/server scope IDs (trim + UUID-only) before de-duping to avoid duplicated UUID entries.

[2026.02.09] - Connect server scope filtering

Fixed

  • Exclude Connect agents and templates from the admin Connect server list used by dash scope pickers to avoid duplicate-looking entries.

[2026.02.09] - Connect scope dedupe

Fixed

  • Dedupe admin Connect network/server lists by networkId/serverId for dash pickers.

[2026.02.09] - Admin connect scope lists

Added

  • Add admin endpoints to list Connect networks and servers for scoped role/content editors.

[2026.02.09] - Permission list access

Fixed

  • Allow role admins to list permission nodes for role editors.

[2026.02.09] - Shop currency fixed

Changed

  • Restrict shop item variant currency to EUR (validated on write and enforced during Polar sync).

[2026.02.09] - Shop variant keys

Changed

  • Generate shop variant keys server-side when missing and preserve Polar mappings by key.

[2026.02.09] - Permission schemas

Added

  • Expose permission value schemas (flag vs numeric vs unit-based) for dash/admin editors.

[2026.02.09] - Shop catalog scopes

Added

  • Allow shop catalog items to be scoped (global/server/network/service/extension) and filterable via query params.

[2026.02.09] - Polar shop

Added

  • Add a Polar-backed shop with catalog, checkout, purchases, and webhook endpoints.
  • Add admin endpoints to manage shop items and sync variants to Polar (sandbox/production).
  • Allow shop purchases to grant quota/limit permissions (numeric or {value,unit}) during permission evaluation.

Changed

  • Public API deployment now expects Polar secrets (access token + webhook secret) to be provided via Docker secrets.

[2026.02.08] - Permission quotas

Added

  • Add count-based quota permissions for friends and profile share creation.

[2026.02.08] - Permission values

Added

  • Allow permissions to carry quantitative values (numbers or {value,unit}) for quotas and limits.

[2026.02.07] - Service redirect schemes

Changed

  • Allow non-HTTP service redirect schemes when they are explicitly whitelisted.
  • Allow custom scheme redirect URLs during service creation/update.

[2026.02.06] - Connect public server ownership

Fixed

  • Store ownershipVerifiedBy as a BSON UUID binary when publishing Connect networks as public servers.

[2026.02.06] - Public server UUID compatibility

Fixed

  • Tolerate legacy/extended-JSON UUID shapes in public_servers documents to avoid 500s when loading or updating Connect public servers.

[2026.02.06] - Connect public servers

Added

  • Add endpoints to publish Connect networks as public server listings for the launcher.

[2026.02.05] - News date flexibility

Changed

  • Accept date-only releaseDate values for news items (time optional).

[2026.02.05] - News feed

Added

  • Add scoped news endpoints with draft-aware access controls.
  • Add a public news feed for launcher consumption.

[2026.02.05] - Feedback mine filter

Added

  • Add a mine filter to list feedback submitted by the authenticated user.

[2026.02.05] - MOTDs

Added

  • Add scoped MOTD endpoints with scheduling and recurrence support.
  • Add a public MOTD listing endpoint for launcher consumption.

[2026.01.27] - Feedback scopes

Added

  • Add scoped feedback endpoints with role-based permissions.
  • Allow roles scoped to services and extensions.

Fixed

  • Accept legacy service grant user IDs when loading service consent.
  • Allow Sentry baggage and sentry-trace headers in CORS for dash requests.
  • Allow build.moe health checks to send X-Uebliche-User-Agent in CORS preflight.

[2026.01.27] - Health DB status

Added

  • Include MongoDB ping status and latency in /health responses.

[2026.01.27] - Service token verify

Fixed

  • Accept service JWTs in /v1/auth/verify for build.moe sign-in flows.

[2026.01.27] - Build.moe random endpoints

Added

  • Add /v1/head/random and /v1/banner/random for build.moe random picks.
  • Add BUILD_MOE_BANNERS_COLLECTION to configure the banner collection name.

[2026.01.26] - Discord docs build fix

Fixed

  • Escape Discord command placeholders in the docs to avoid VitePress parsing errors.

[2026.01.26] - Auth token verify

Added

  • Add /auth/verify and /v1/auth/verify to validate API JWTs and return minimal claims for build.moe.

[2026.01.26] - Service exchange errors

Changed

  • Allow super admins to list all services instead of only owned ones.

Fixed

  • Show a friendly HTML error page for failed /v1/auth/service/exchange requests.
  • Fix service consent upserts to avoid duplicate key errors.
  • Fix service token issuance when consent documents store legacy user IDs.

[2026.01.26] - Service auth exchange

Added

  • Add /v1/auth/service/exchange to start service consent flows from a redirect URL.
  • Add /v1/auth/service/token to issue service-scoped JWTs after consent.

Fixed

  • Include legacy string ownerId values when listing services.

[2026.01.25] - Public API deploy cleanup

Removed

  • Remove the "Deploy public API (current context)" action from the Public API project.

[2026.01.25] - Build.moe command startup

Added

  • Auto-update Build.moe Discord commands on Public API startup for the EU region and report failures to Sentry.

[2026.01.25] - Build.moe command auth

Fixed

  • Require a Public API admin JWT when running the Build.moe Discord command update action.

[2026.01.25] - Public API command action fixes

Fixed

  • Add the missing ureq dependency for Build.moe command registration and allow a dedicated Public API base URL in the action.

[2026.01.25] - Build.moe command update action

Added

  • Add a Uebliche.dev action for the Public API project to update Build.moe Discord commands.

[2026.01.25] - Discord heads lookup

Changed

  • Resolve Discord /head lookups against the local MongoDB heads collection instead of build.moe HTTP requests.
  • Split /head into search-only and /randomhead for random results.

Added

  • Add /v1/discord/build-moe/commands to register build.moe bot slash commands globally.

Added

  • Allow overriding the Mongo database and collection used for head lookups.

[2026.01.25] - Discord interactions

Added

  • Add /v1/discord/interaction to process Discord slash-command payloads (including /head and /docs).

[2026.01.25] - Connect extensions

Added

  • Add Connect extension catalog endpoints plus per-server extension registrations and actions.
  • Add source scoping for Connect settings and settings history endpoints.
  • Add server template and temporary instance metadata for Connect servers.

[2026.01.25] - Connect settings schema

Added

  • Store optional settings schemas for Connect servers and return them with settings payloads.

[2026.01.24] - Launcher options sync

Added

  • Add /v1/profile/minecraft-options to sync launcher Minecraft options via the public API.

[2026.01.24] - Profile share admin listing

Added

  • Add /v1/admin/profile-shares to list launcher profile shares with author info.

[2026.01.24] - Games templates and catalog

Added

  • Add template management endpoints (/v1/games/templates, /v1/games/templates/{id}).
  • Add collaborator updates for templates (/v1/games/templates/{id}/collaborators).
  • Add public games catalog endpoint (/v1/games/catalog).
  • Add minigame network binding and publish endpoints (/v1/games/minigames/{id}, /v1/games/minigames/{id}/publish).
  • Add leaderboard creation + delete endpoints (/v1/games/leaderboards, /v1/games/leaderboards/{id}).

[2026.01.24] - Games live stream

Added

  • Add /v1/games/live websocket stream for games dashboard snapshots.

[2026.01.22] - Default roles

Changed

  • Apply default roles automatically during permission checks (without assigning user roles).

[2026.01.22] - Connect host join

Added

  • Add connect network join tokens plus the /v1/connect/networks/join endpoint. (api 07cd76c)
  • Add /v1/connect/hosts for listing agent hosts. (api 07cd76c)

[2026.01.22] - Dash user administration

Added

  • Add admin user lookup and detail endpoints (/v1/admin/users/lookup, /v1/admin/users/{userId}).
  • Add a dashboard user management view with scope filtering, role assignment, and explicit permission edits.

[2026.01.22] - Sanitize internal errors

Fixed

  • Stop returning raw database error messages in API responses; errors are logged server-side.
  • Allow user role lookups to decode legacy UUID shapes when loading admin role assignments.
  • Prefer Cloudflare client IP headers so public API logs and requests use real user IPs.

Added

  • Add /v1/ip to return the caller IP as plain text.
  • Include uptimeSeconds in /health responses.

[2026.01.21] - User last-seen tracking

Fixed

  • Update lastSeenAt for authenticated users on every API request, including region tracking.

[2026.01.19] - 2026-01-19 - Auth user bootstrap

Changed

  • Create missing user records during Minecraft join verification and Microsoft sign-in.

Fixed

  • Repair public API builds by correcting startup module wiring and tracing layer typing.

[2026.01.19] - 2026-01-19

Added

  • Add /v1/profile/settings endpoints so users can read and update profile settings (including friend request privacy).

Changed

  • Block friend request creation when the recipient has disabled allowFriendRequests.

[2026.01.18] - 2026-01-18

Changed

  • Switch Minecraft session auth to a join/hasJoined handshake with short-lived join tokens so clients keep Minecraft access tokens local.

Added

  • Add /v1/auth/session/minecraft/join and /v1/auth/session/minecraft/verify for Mojang join-based auth.
  • Add /v1/profile/auth/sessions so users can inspect recent auth sessions.

Removed

  • Remove /v1/auth/session/minecraft/access from the public API.

Fixed

  • Populate personal totem upload authors from the authenticated user when missing.

[2026.01.17] - 2026-01-17

Added

  • Add /v1/connect/servers/{serverId}/claim-key so Connect servers can request fresh claim keys.

[2026.01.16] - 2026-01-16

Changed

  • Rename the docs path from /public-api/ to /api/ and update section links.
  • Point the live tryout at https://uebliche.info/api and store tokens in local storage.

[2026.01.15] - 2026-01-15

Added

  • Add /v1/auth/session/exchange to mint API tokens from the uebliche_token cookie (SSO for build.moe/dash).
  • Add build.moe redirect support for Microsoft sign-in via MICROSOFT_BUILD_MOE_REDIRECT.
  • Seed the permissions catalog on startup so service consent can reference known nodes.
  • Add role CRUD and user role assignment endpoints under /v1/admin/roles.
  • Add connect network endpoints (/v1/connect/networks) so users can create and list Connect networks.
  • Add Connect server claim and assignment endpoints (/v1/connect/servers, /v1/connect/servers/claim, /v1/connect/servers/{serverId}).
  • Add network domain claim/verification endpoints (/v1/connect/networks/{networkId}/domains).

Changed

  • Replace Connect network shared keys with single-use server claim keys returned by server registration.
  • Remove Connect network claiming; servers are claimed first and assigned to networks in Dash.

[2026.01.13] - 2026-01-13

Added

  • Mirror the personal totem endpoints under /v1/api/profile/... so legacy clients (like TotemMod) can still select and fetch models.
  • Capture 5xx errors and panics in Sentry when SENTRY_DSN is set, tagging each report with the active build and region metadata.

Changed

  • Omit empty gallery item fields (for example rating, author, timestamps, and zero counts) to shrink /v1/profile/personal-totem/gallery payloads.
  • Include itemModelUrl on gallery items so clients can preview each model without extra roundtrips.
  • Remove cdn.baseUrl from gallery responses to avoid leaking public entrypoints.
  • Trim the model endpoint response to the minimal fields needed for model fetches (no duplicate URLs or filenames).
  • Return public CDN URLs from the model endpoint (no presigned links).
  • Extend issued auth JWTs to a 30-day lifetime.
  • Ensure personal totem selection can upsert a minimal user record when none exists to avoid 500s.
  • Avoid deserialization errors when selecting gallery models with legacy author id formats.

Fixed

  • Let /v1/profile/personal-totem/model/{itemModelId} return gallery models when PERSONAL_TOTEM_PUBLIC_API is enabled so each totem entry renders its own preview in the mod gallery.
  • Normalize itemModelPublicUrl so it no longer exposes the totem-models/ storage prefix and instead uses clean https://totem.uebliche.net/{modelId}.json URLs.
  • New uploads store itemModel objects without the totem-models/ prefix, so Mongo and the public URL share a simple {modelId}.json path.
  • Ensure personal totem uploads set public-read ACLs when the public API or public endpoint is enabled, so CDN fetches do not 403.

[2026.01.12] - 2026-01-12

Fixed

  • Serialize connect command/settings payload data to BSON for MongoDB updates.
  • Send connect settings WebSocket payloads using UTF-8 text frames.
  • Include Connect-managed servers in /v1/profile/servers responses (including tag=uebliche).

[2026.01.11] - 2026-01-11

Changed

  • Drop user UUIDs from personal totem S3 storage keys (now totem-models/<modelId>.<ext>).
  • Allow duplicate personal totem uploads while reusing existing storage objects.
  • Skip request logging for /health probes.
  • Default Microsoft OAuth scopes to XboxLive.signin offline_access.
  • Make ANSI log coloring configurable via LOG_ANSI / LOG_NO_COLOR / NO_COLOR (off by default unless LOG_ANSI is set).
  • Allow Microsoft dashboard logins to request a custom redirect URL (limited to localhost/uebliche.net).
  • Allow connect settings WebSocket clients to pass the dash JWT via ?token=.

Added

  • Add optional per-model ratings (rating.content, rating.age) and author metadata (author.id, author.name, author.description) to personal totem uploads and responses.
  • Add a personal totem gallery endpoint with limit/sort ordering and selection counts.
  • Add Microsoft OAuth login endpoints for dashboard sessions.
  • Add /v1/profile/self and /v1/profile/servers for dashboard profile metadata and owned server lists.
  • Add admin permission endpoints to list and edit user permission grants.
  • Add /v1/connect/servers/register for automatic server registration and network grouping.

Removed

  • Remove legacy user_id fallbacks for personal totem history and uploads.

[2026.01.10] - 2026-01-10

Added

  • Add request/response logging for every public API call via an HTTP trace layer.
  • Add a local deploy helper script for the public API.

Changed

  • Require Minecraft access tokens for /v1/auth/session/minecraft/access (remove dev auth fallback).
  • Document public API deploys against the unauthenticated registry.

Fixed

  • Create missing user records on first personal totem upload when using Minecraft tokens.
  • Match compact (no-hyphen) userId formats when loading personal totem history.
  • Reuse existing personal totem storage objects to avoid 1:1 duplicate uploads.
  • Block duplicate personal totem uploads per user with a dedupe key.

[2026.01.09] - 2026-01-09

Added

  • Added /health to expose region and build metadata.
  • Added an auth page for /v1/auth/session/minecraft/access.

Removed

  • Removed the regions and MongoDB pages from the API docs.

[2026.01.08] - 2026-01-08

Changed

  • Track homeRegion for users and tag friends/favorites for shard-friendly routing.

Added

  • Documented region deployment and home region tracking.
  • Added MongoDB sharding deployment notes.

[2026.01.07] - 2026-01-07

Added

  • Documented the friends API endpoints.