bitwarden/server
Internal client API
The internal API is what every Bitwarden first-party client speaks to. It is not formally versioned; clients and server change together (gated by feature flags and minimum-version constants in src/Core/Constants.cs such as Fido2KeyCipherMinimumVersion = "2023.10.0", SSHKeyCipherMinimumVersion = "2024.12.0").
Controllers are spread across src/Api/<Domain>/Controllers/. The big ones:
| Path prefix | Controller(s) | Notes |
|---|---|---|
/accounts/* |
AccountsController (src/Api/Auth/Controllers/) |
Register, profile, password change, premium upgrade, key rotation, API keys. |
/sync |
SyncController (src/Api/Vault/Controllers/) |
Returns the user, ciphers, folders, sends, orgs in a single payload. |
/ciphers/* |
CiphersController (src/Api/Vault/Controllers/) |
The 1,713-line behemoth. Cipher CRUD + sharing + attachments + bulk + restore. |
/folders/* |
FoldersController |
Personal folders. |
/collections/* |
CollectionsController (src/Api/AdminConsole/Controllers/) |
Per-org collection CRUD + permissions. |
/organizations/* |
OrganizationsController (src/Api/AdminConsole/Controllers/) |
Org create / update / leave / sponsor / verify-domain. |
/organizations/{id}/users/* |
OrganizationUsersController |
Members + invites + confirm + revoke. |
/organizations/{id}/groups/* |
GroupsController |
Group CRUD. |
/organizations/{id}/policies/* |
PoliciesController |
Org-wide policies. |
/organizations/{id}/billing/* |
OrganizationBillingController (src/Api/Billing/Controllers/) |
Org billing self-service. |
/sends/* |
SendsController (src/Api/Tools/Controllers/) |
Send CRUD. |
/sends/access/{id} |
SendAccessController |
Recipient flow. |
/notifications/* |
NotificationsController (src/Api/NotificationCenter/Controllers/) |
Notification center inbox. |
/devices/* |
DevicesController (src/Api/Controllers/) |
Register / push-token / known-device. |
/two-factor/* |
TwoFactorController (src/Api/Auth/Controllers/) |
2FA enrolment + verification + recovery. |
/auth-requests/* |
AuthRequestsController (src/Api/Auth/Controllers/) |
Login-with-device. |
/emergency-access/* |
EmergencyAccessController (src/Api/Auth/Controllers/) |
Emergency Access. |
/key-rotation/* |
KeyManagementController (src/Api/KeyManagement/) |
User-key rotation orchestration. |
/secrets-manager/* |
src/Api/SecretsManager/Controllers/ |
Projects / Secrets / ServiceAccounts. |
/reports/* |
src/Api/Dirt/Controllers/ |
Password-health, breach, etc. reports. |
/installations/* |
InstallationsController (src/Api/Platform/) |
Self-host installation provisioning. |
/config, /info, /settings |
src/Api/Controllers/ |
Server health/version + per-server config. |
Authorization
Almost every endpoint is decorated with [Authorize(Policy = Policies.Application)] (or one of the more specific policies: Web, Push, Organization, Installation, Licensing, Secrets, Send). The set of policies is defined in src/Api/Startup.cs's AddPolicy calls.
Resource-based authorization is layered on top via IAuthorizationHandler implementations under each domain's AuthorizationHandlers/ folder. A typical controller pattern:
[HttpPut("{id}")]
public async Task<CipherResponseModel> Put(Guid id, CipherRequestModel model)
{
var cipher = await _cipherRepository.GetByIdAsync(id);
var result = await _authzService.AuthorizeAsync(User, cipher, BulkCollectionOperations.Update);
if (!result.Succeeded) throw new NotFoundException();
await _cipherService.SaveAsync(cipher.Update(model), cipher.UserId ?? cipher.OrganizationId.Value);
return new CipherResponseModel(cipher);
}Pagination & filtering
There is no global pagination scheme. A handful of endpoints (events, audit log, secrets manager listings) use ?continuationToken=… skip-tokens. Vault sync endpoints return everything in one shot — historically because clients cache the full vault locally.
Error responses
ApiExceptionFilterAttribute translates:
| Exception | HTTP | Body |
|---|---|---|
BadRequestException |
400 | { message, validationErrors } |
UnauthorizedException |
401 | { message } |
NotFoundException |
404 | { message } |
ForbiddenException |
403 | { message } |
BillingException |
400 | { message } plus billing-specific fields |
Any other Exception |
500 | { message: "An unhandled server error has occurred.", exceptionMessage, exceptionStackTrace? } |
Stack traces are included only in Development and QA environments.
Swagger groups
ApiExplorerGroupConvention (src/Api/Utilities/) puts public-API controllers into a separate Public group. The internal Swagger doc is internal/swagger.json; the public one is public/swagger.json.
Where to look
- Pick the feature page closest to the endpoint you care about.
- The matching primary controller is usually under
src/Api/<Domain>/Controllers/. - Request/response models live next door under
Models/Request/andModels/Response/.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.