{"record":{"id":"c55c9a2dbab89308","repo":"BookStackApp/BookStack","slug":"errors-email-confirmation-awaiting","errorCode":null,"errorMessage":"errors.email_confirmation_awaiting","messagePattern":"errors\\.email_confirmation_awaiting","errorType":"exception","errorClass":"ApiAuthException","httpStatus":null,"severity":"error","filePath":"app/Api/ApiTokenGuard.php","lineNumber":92,"sourceCode":"    /**\n     * Check the API token in the request and fetch a valid authorised user.\n     *\n     * @throws ApiAuthException\n     */\n    protected function getAuthorisedUserFromRequest(): Authenticatable\n    {\n        $authToken = trim($this->request->headers->get('Authorization', ''));\n        $this->validateTokenHeaderValue($authToken);\n\n        [$id, $secret] = explode(':', str_replace('Token ', '', $authToken));\n        $token = ApiToken::query()\n            ->where('token_id', '=', $id)\n            ->with(['user'])->first();\n\n        $this->validateToken($token, $secret);\n\n        if ($this->loginService->awaitingEmailConfirmation($token->user)) {\n            throw new ApiAuthException(trans('errors.email_confirmation_awaiting'));\n        }\n\n        return $token->user;\n    }\n\n    /**\n     * Validate the format of the token header value string.\n     *\n     * @throws ApiAuthException\n     */\n    protected function validateTokenHeaderValue(string $authToken): void\n    {\n        if (empty($authToken)) {\n            throw new ApiAuthException(trans('errors.api_no_authorization_found'));\n        }\n\n        if (!str_contains($authToken, ':') || !str_starts_with($authToken, 'Token ')) {\n            throw new ApiAuthException(trans('errors.api_bad_authorization_format'));","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Api/ApiTokenGuard.php#L74-L110","documentation":"getAuthorisedUserFromRequest() checks whether the token's user is still awaiting email confirmation via LoginService::awaitingEmailConfirmation(). If so, it throws ApiAuthException with the translated message errors.email_confirmation_awaiting, blocking API access until the email address is confirmed.","triggerScenarios":"API request with a syntactically valid token id:secret pair, validateToken() passing, but the owning user has not completed email confirmation (new registration or recent email change) while email confirmation is required by the instance.","commonSituations":"Freshly registered API users on instances with REQUIRE_EMAIL_CONFIRMATION enabled; users who changed their email address and did not click the confirmation link; automated integrations created before the user confirmed; mail delivery failures leaving confirmation emails unopened.","solutions":["Have the user open the email-confirmation link sent to their address, then retry the API call.","Resend the confirmation email from the admin user management page if the link expired.","An admin can manually confirm/activate the user in the admin area.","Check the instance's mail configuration (SMTP logs) if confirmation emails are not arriving."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $response = $client->get($apiUrl);\n} catch (ApiAuthException $e) {\n    if (str_contains($e->getMessage(), 'email_confirmation_awaiting')) {\n        // prompt user to confirm email, then retry after confirmation\n    }\n    throw $e;\n}","preventionTips":["Complete email confirmation before provisioning API integrations for a new user.","Automate checking confirmation status during onboarding.","Ensure SMTP is configured so confirmation mails actually arrive."],"tags":["api","authentication","email-confirmation","http-401"],"backgroundTag":"email-not-confirmed","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}