Skip to content

API contract scope

github-actions[bot] edited this page Oct 2, 2026 · 15 revisions

Generated from docs/reference/api-contracts.md. Edit that file in the repository: changes made in the wiki are overwritten.

The RaidManager application programming interface (API) publishes its operations in an OpenAPI document at /openapi/v1.json, which is the source of truth for request shapes, response codes, and security. Failures are returned as ProblemDetails; validation failures list each field under errors.

In Development, the interactive reference page at https://localhost:55366/scalar renders that document and lets you try each operation (ADR-0013). The Aspire dashboard links to it as "API reference" on the api resource. To call a website-only operation, enter the website key in the page's authentication panel; dotnet user-secrets list --project src/Containers/Aspire/Hosting/RaidManager.AppHost shows it as Parameters:website-service-key in your own terminal.

Implemented operations

Operation Caller Purpose
POST /internal/identity/discord-sign-in Website only Resolve a Discord identity confirmed by OAuth to its single local user id.
GET /internal/users/{userId}/character-claims/pending Website only List the player's pending and conflicted character claims, oldest first.
POST /internal/users/{userId}/character-claims/{characterId}/approve Website only Approve a pending claim. Returns 409 and keeps the claim in conflict review when another player owns the character.
POST /internal/users/{userId}/character-claims/{characterId}/reject Website only Reject a pending claim, so the character never becomes the player's signup option.
POST /internal/communities Website only Link a Discord server as a community, with the user who added the bot as its Administrator. Returns 201 with the community id, or 409 when the server is already linked.
GET /internal/communities/{communityId} Website only Get a community's Discord server, realm and Administrator.
GET /internal/communities/by-discord-server/{discordGuildId} Website only Get the community a Discord server links to, or 404 when it isn't linked.
POST /internal/communities/by-discord-servers Website only At sign-in, list the linked communities of the Discord servers the user is in, by name; servers that aren't linked are left out.
GET /internal/users/{userId}/communities?memberOf={communityId} Website only List the communities the user administers, then those in memberOf (repeatable), the ones the user's servers matched at sign-in; each group by name.
GET /internal/users/{userId}/communities/{communityId}/roles Website only Read the community's roles from Discord: the mappable roles, and rows for the Administrator, each role (with its id and permissions) and Member, each with its Discord roles and member count. Only a member of the server may; refreshes the stored server name.
GET /internal/users/{userId}/communities/{communityId}/members Website only List the server's members from Discord, without bots: each one's display name, avatar, Discord roles and roles (Administrator, the roles their Discord roles give, or Member), Administrator first, with the time Discord was asked. Only a member of the server may; refreshes the stored server name.
PUT /internal/users/{userId}/communities/{communityId}/role-mappings/{roleId}/{discordRoleId} Website only Make a Discord role give one of the community's roles; 404 for a role the community doesn't have. One Discord role can give several roles. Only the Administrator may.
DELETE /internal/users/{userId}/communities/{communityId}/role-mappings/{roleId}/{discordRoleId} Website only Stop a Discord role giving that role; any other role it gives stays. Only the Administrator may.

Operations under /internal/ require the website key in the X-RaidManager-Service-Key header, as ADR-0011 describes. A missing or wrong key returns 401. The website passes the signed-in player's user id from its session in the route.

A claim decision returns 204 on success, 404 when the character or claim doesn't exist, and 409 when the claim was already decided or another player owns the character. Claims carry realm, class, race and claim state as names, such as Icecrown or Conflict.

A community carries its realm as a name too. Linking needs a server id that is a Discord snowflake, a name of at most 100 characters, one of the realm names and a known user; anything else returns 400 naming the field, and an unknown user returns 404.

The officer roles operations ask Discord with the bot (ADR-0022). Someone outside the Discord server, or anyone but the Administrator changing a mapping, gets 403. A Discord role that isn't one of the server's mappable roles returns 400: @everyone and roles of other bots can't be mapped. Discord not answering returns 503, and a server the bot was removed from returns 409.

Planned contract areas

  • User-scoped website calls, session, and profile access.
  • Companion pairing, monitored-installation status, and authenticated, idempotent character snapshot ingestion.
  • Resolving an ownership conflict between two players.
  • Character profiles, loadouts, synchronization timestamps, and raid lockouts.
  • Community membership and officer permissions, raid templates, recurrence, scheduling, and publication.
  • Confirmed, tentative, late, and declined signups, presets, compositions, bench, boss assignments, gear-readiness warnings, and raid-buff coverage.
  • Eligibility results per scheduled raid target, including verdict, source, freshness, reason, and reset time.
  • Recorded officer exceptions for unknown data, reminders, roster-change notifications, attendance history, and addon roster export.

Transport models must stay separate from Domain types. The web app and Discord bot must receive the same eligibility decision from the application layer.

Clone this wiki locally