- name
- backend-api-routes
- description
- Add or edit SwarmUI backend API routes, including handler signatures, registration, permissions, HTTP or WebSocket behavior, and generated route documentation.
# Backend API Routes
## When to Use
- Use when you are adding a new backend API route, or editing an existing route.
- Routes served under `/API/<MethodName>`
- Only ever add a new route if a user has directly instructed you to. If you think one is needed or helpful and they haven't instructed you to, explain your idea and ask the user if it's okay.
## Relevant Paths
- `src/WebAPI/API.cs`: registration, request/session/permission handling, HTTP and WebSocket dispatch, documentation attributes, and documentation generation.
- `src/WebAPI/APICallReflectBuilder.cs` and `APICall.cs`: valid handler signatures, JSON coercion, and route metadata.
- `src/WebAPI/BasicAPIFeatures.cs`: startup registration for core route groups. Related core routes live beside it in `AdminAPI.cs`, `BackendAPI.cs`, `ModelsAPI.cs`, `T2IAPI.cs`, and `UtilAPI.cs`.
- `src/Accounts/Permissions.cs`: core permissions, groups, defaults, and safety levels.
- `src/BuiltinExtensions/*`: extension-owned routes and permissions; register these from the extension's `OnInit()`.
- `docs/API.md`: public protocol overview. `docs/APIRoutes/` is autogenerated; never edit it directly.
## Add or Edit a Route
1. Understand: The API layer reflects over registered C# methods: the method name becomes the route name, its parameters define the JSON contract, and it must return `Task<JObject>`.
2. Put the handler with the closest related API class, or create a cohesive class marked `[API.APIClass("...")]`. For a new core class, add its `Register()` call to `BasicAPIFeatures.Register()`; extensions register routes in `OnInit()`.
3. Implement `public static async Task<JObject> RouteName(...)` for core routes. Extension handlers may be instance methods. Add `[API.APIDescription(description, returnShape)]`, `[API.APIParameter("...")]` to every client input, and `[API.APINonfinalMark]` only when the contract is intentionally experimental.
4. Register it with `API.RegisterAPICall(RouteName, isUserUpdate, permission)`. Use `true` for user actions that should refresh session/user activity and `false` for getters or automated calls. Reuse the narrowest suitable permission; ordinary routes must not be permissionless.
5. Return JSON objects consistently: successful mutations usually return `{ "success": true }`; expected failures return an object containing `error` and, when callers need to branch, a stable `error_id`. Validate domain rules and access to user-supplied resources inside the handler.
## Choose Handler Inputs
- `Session` and `HttpContext` are injected. Add `WebSocket` to make the route require using a WebSocket, conventionally with a `WS` method suffix; send incremental messages through the socket and return the final `JObject` or `null` after handling output yourself.
- JSON-bound scalar types are `string`, `int`, `long`, `float`, `double`, `bool`, `byte`, `char`, and `string[]`. Their exact C# parameter names are JSON keys. No default means required; a C# default makes the input optional, so choose defaults that preserve safe existing behavior.
- A `JObject` receives a copy of the entire request body with `session_id` removed; it is not bound beneath the parameter name. Use it for genuinely free-form or mixed payloads, not to avoid defining a stable typed contract. Conventionally `JObject raw`.
- An `IDataHolder` can model a structured group through public fields marked `[IDataHolder.NetData(Name = "...", Required = ...)]`; its object may be nested under the parameter name or supplied at the request root. Its fields must use supported scalar types.
- Keep parameter descriptions concrete: state units, accepted values or formats, meaning of null/empty/sentinel values, and interactions with other inputs. The return-shape string documents fields inside the returned JSON object.
## Choose Permissions
Prefer an existing `Permissions` entry that exactly covers the capability. When a distinct capability needs a new permission, register a stable lowercase `snake_case` ID, clear display name and scope, the least-privileged `PermissionDefault`, and the closest `PermInfoGroup`. Leave safety as `UNTESTED` unless there is a justified stronger classification; use `RISKY` or `POWERFUL` when the capability can access sensitive data or materially alter the server, and never claim `SAFE` without the required security review.
Sessionless routes are exceptional authentication/bootstrap flows controlled by `API.SessionlessRoutes`; do not add one merely for convenience.
## Verify
- Check registration occurs once, the route name is unique case-insensitively, and HTTP/WebSocket callers match the signature.
- Exercise required, optional, malformed, unauthorized, and successful requests; for mutations, also verify ownership/path validation and side effects.
- Confirm descriptions and return examples match the actual JSON contract, then run the relevant build/tests and review `git diff`. Do not edit generated files under `docs/APIRoutes/`.
View on GitHub