{"record":{"id":"0d1728a7eff249fb","repo":"bitwarden/server","slug":"email-verified-sends-require-a-premium-membership","errorCode":null,"errorMessage":"Email verified Sends require a premium membership","messagePattern":"Email verified Sends require a premium membership","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Tools/Controllers/SendsController.cs","lineNumber":240,"sourceCode":"                send.Id,\n                EventType.Send_Accessed_File,\n                orgContext);\n        }\n\n        return new ObjectResult(new SendFileDownloadDataResponseModel() { Id = fileId, Url = url });\n    }\n\n    [Authorize(Policies.Application)]\n    [HttpPost(\"\")]\n    public async Task<SendResponseModel> Post([FromBody] SendRequestModel model)\n    {\n        model.ValidateCreation();\n        var userId = _userService.GetProperUserId(User) ?? throw new InvalidOperationException(\"User ID not found\");\n        var hasPremium = await _hasPremiumAccessQuery.HasPremiumAccessAsync(userId);\n\n        if (!hasPremium && !string.IsNullOrWhiteSpace(model.Emails))\n        {\n            throw new BadRequestException(\"Email verified Sends require a premium membership\");\n        }\n\n        var send = model.ToSend(userId, _sendAuthorizationService);\n        await _nonAnonymousSendCommand.SaveSendAsync(send);\n        return new SendResponseModel(send);\n    }\n\n    [Authorize(Policies.Application)]\n    [HttpPost(\"file/v2\")]\n    public async Task<SendFileUploadDataResponseModel> PostFile([FromBody] SendRequestModel model)\n    {\n        if (model.Type != SendType.File)\n        {\n            throw new BadRequestException(\"Invalid content.\");\n        }\n\n        if (!model.FileLength.HasValue)\n        {","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Tools/Controllers/SendsController.cs#L222-L258","documentation":"Thrown as BadRequestException (HTTP 400) from POST /sends (text/item creation) when the requesting user does not have premium access but the request body includes an Emails field (email-verified/OTP access). Email-verified Send access is a premium-only feature; the server rejects non-premium users attempting to use it.","triggerScenarios":"POST /sends with a JSON body where model.Emails is non-empty AND the caller's HasPremiumAccessAsync returns false (free account, or premium not active/expired).","commonSituations":"Free-tier user selects 'email verification' access type in the client; premium subscription lapsed/expired but client still sends Emails; org-based premium not provisioned for the user; test account without premium.","solutions":["Upgrade the user to an active premium subscription, or use password-auth/no-auth instead of email access.","Clear the Emails field in the request when not using premium.","Verify premium status via the billing/account endpoint before submitting.","If org-sponsored premium, confirm the sponsorship is active and synced."],"exampleFix":"// before\n{ \"type\": 1, \"emails\": \"a@b.com\", ... } // free user -> 400\n\n// after: omit emails or use password auth\n{ \"type\": 1, \"password\": \"...\", ... }","handlingStrategy":"validation","validationCode":"// Client: check premium before creating an email-verified Send\nvar hasPremium = await billingClient.HasPremiumAccessAsync();\nif (!hasPremium && !string.IsNullOrWhiteSpace(model.Emails)) {\n    ShowUser(\"Email-verified Sends require Bitwarden Premium.\");\n    return;\n}\nawait client.PostAsync(\"sends\", JsonContent.Create(model));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Disable the email-access option in the client UI for non-premium users.","Refresh premium status after subscription changes.","Default non-premium users to password or no-auth Send access."],"tags":["send","http-400","premium","billing","validation","bitwarden-server"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}