diff --git a/docs/Tutorials/Authentication/Overview.md b/docs/Tutorials/Authentication/Overview.md
index 19ddacece..32dfbd738 100644
--- a/docs/Tutorials/Authentication/Overview.md
+++ b/docs/Tutorials/Authentication/Overview.md
@@ -388,3 +388,69 @@ Start-PodeServer {
     New-PodeAuthScheme -Basic | Add-PodeAuthWindowsAd -Name 'Login'
 }
 ```
+
+## Handling Authentication Manually
+
+Sometimes, the standard Pode authentication approach may not provide the flexibility needed to accommodate all use cases. For example, specific requirements such as customizing an OpenAPI definition for an unsuccessful authentication might necessitate a more tailored solution. This approach offers greater control over authentication processing within routes.
+
+### Invoke-PodeAuth
+
+The `Invoke-PodeAuth` function allows for direct invocation of authentication methods and returns the result from `Add-PodeAuth`. This function offers a streamlined approach for manually handling authentication within routes.
+
+#### Usage Example
+
+```powershell
+New-PodeAuthScheme -ApiKey | Add-PodeAuth -Name 'APIKey' -Sessionless -ScriptBlock {
+    param($key)
+
+    # Handle missing API key
+    if (!$key) {
+        return @{ Success = $false; Reason = 'No X-API-KEY Header found' }
+    }
+
+    # Validate API key
+    if ($key -eq 'test_user') {
+        return @{ Success = $true; User = 'test_user'; UserId = 1 }
+    }
+
+    # Return failure for invalid users
+    return @{ Success = $false; User = $key; UserId = -1; Reason = 'Not existing user' }
+}
+
+Add-PodeRoute -Method 'Get' -Path '/api/v3/' -Authentication 'APIKey' -NoMiddlewareAuthentication -ScriptBlock {
+    $auth = Invoke-PodeAuth -Name 'APIKey'
+
+    if ($auth.Success) {
+        Write-PodeJsonResponse -Value @{ Username = $auth.User }
+    } else {
+        Write-PodeJsonResponse -Value @{ message = $auth.Reason; user = $auth.User } -StatusCode 401
+    }
+}
+```
+
+The `Auth` object, when managed this way, includes any value returned by the authentication scriptblock, such as `User`, `UserId`, and `Reason` fields as shown in the example.
+
+### NoMiddlewareAuthentication Parameter
+
+The `-NoMiddlewareAuthentication` parameter for `Add-PodeRoute` enables routes to bypass automatic authentication middleware processing. This allows developers to manually handle authentication within route script blocks.
+
+#### Example Usage
+
+```powershell
+Add-PodeRoute -Method 'Get' -Path '/api/v3/' -Authentication 'APIKey' -NoMiddlewareAuthentication -ScriptBlock {
+    $auth = Invoke-PodeAuth -Name 'APIKey'
+
+    if ($auth.Success) {
+        Write-PodeJsonResponse -Value @{ Username = $auth.User }
+    } else {
+        Write-PodeJsonResponse -Value @{ message = $auth.Reason; user = $auth.User } -StatusCode 401
+    }
+}
+```
+
+### Benefits
+
+- Allows developers to manually control authentication within route logic.
+- Provides flexibility to bypass automatic authentication middleware.
+- Ensures better customization for complex authentication scenarios.
+
diff --git a/examples/Web-AuthBasicBearer.ps1 b/examples/Web-AuthBasicBearer.ps1
index f6c73820d..3cd1ccaf6 100644
--- a/examples/Web-AuthBasicBearer.ps1
+++ b/examples/Web-AuthBasicBearer.ps1
@@ -9,7 +9,13 @@
 .EXAMPLE
     To run the sample: ./Web-AuthBasicBearer.ps1
 
-    Invoke-RestMethod -Method Get -Uri 'http://localhost:8081/users' -Headers @{ Authorization = 'Bearer test-token' }
+    Invoke-RestMethod -Method Get -Uri 'http://localhost:8081/users' -Headers @{ Authorization = 'Bearer test-token' } -ResponseHeadersVariable headers
+
+.EXAMPLE
+    "No Authorization header found" 
+
+    Invoke-RestMethod -Method Get -Uri 'http://localhost:8081/users' -ResponseHeadersVariable headers -Verbose -SkipHttpErrorCheck
+    $headers | Format-List
 
 .LINK
     https://github.com/Badgerati/Pode/blob/develop/examples/Web-AuthBasicBearer.ps1
@@ -64,7 +70,7 @@ Start-PodeServer -Threads 2 {
     }
 
     # GET request to get list of users (since there's no session, authentication will always happen)
-    Add-PodeRoute -Method Get -Path '/users' -Authentication 'Validate' -ScriptBlock {
+    Add-PodeRoute -Method Get -Path '/users' -Authentication 'Validate' -ErrorContentType 'application/json' -ScriptBlock {
         Write-PodeJsonResponse -Value @{
             Users = @(
                 @{
diff --git a/examples/Web-AuthBasicHeader.ps1 b/examples/Web-AuthBasicHeader.ps1
index 0fb0f8d27..eca16bba7 100644
--- a/examples/Web-AuthBasicHeader.ps1
+++ b/examples/Web-AuthBasicHeader.ps1
@@ -17,7 +17,8 @@
     The example used here is Basic authentication.
 
     Login:
-    $session = (Invoke-WebRequest -Uri http://localhost:8081/login -Method Post -Headers @{ Authorization = 'Basic bW9ydHk6cGlja2xl' }).Headers['pode.sid']
+    Invoke-RestMethod -Uri http://localhost:8081/login -Method Post -Headers @{ Authorization = 'Basic bW9ydHk6cGlja2xl' } -ResponseHeadersVariable headers -SkipHttpErrorCheck
+    $session = $headers['pode.sid']
 
     Users:
     Invoke-RestMethod -Uri http://localhost:8081/users -Method Post -Headers @{ 'pode.sid' = "$session" }
@@ -81,13 +82,13 @@ Start-PodeServer -Threads 2 {
     }
 
     # POST request to login
-    Add-PodeRoute -Method Post -Path '/login' -Authentication 'Login'
+    Add-PodeRoute -Method Post -Path '/login' -Authentication 'Login'  -ErrorContentType 'application/json'
 
     # POST request to logout
-    Add-PodeRoute -Method Post -Path '/logout' -Authentication 'Login' -Logout
+    Add-PodeRoute -Method Post -Path '/logout' -Authentication 'Login' -Logout  -ErrorContentType 'application/json'
 
     # POST request to get list of users - the "pode.sid" header is expected
-    Add-PodeRoute -Method Post -Path '/users' -Authentication 'Login' -ScriptBlock {
+    Add-PodeRoute -Method Post -Path '/users' -Authentication 'Login'  -ErrorContentType 'application/json' -ScriptBlock {
         Write-PodeJsonResponse -Value @{
             Users = @(
                 @{
diff --git a/examples/Web-AuthDigest.ps1 b/examples/Web-AuthDigest.ps1
index 7c26eef53..65c8b37ed 100644
--- a/examples/Web-AuthDigest.ps1
+++ b/examples/Web-AuthDigest.ps1
@@ -9,7 +9,97 @@
 .EXAMPLE
     To run the sample: ./Web-AuthDigest.ps1
 
-    Invoke-RestMethod -Uri http://localhost:8081/users -Method Get
+    # Define the URI and credentials
+    $uri = [System.Uri]::new("http://localhost:8081/users")
+    $username = "morty"
+    $password = "pickle"
+
+    # Create a credential cache and add Digest authentication
+    $credentialCache = [System.Net.CredentialCache]::new()
+    $networkCredential = [System.Net.NetworkCredential]::new($username, $password)
+    $credentialCache.Add($uri, "Digest", $networkCredential)
+
+    # Create the HTTP client handler with the credential cache
+    $handler = [System.Net.Http.HttpClientHandler]::new()
+    $handler.Credentials = $credentialCache
+
+    # Create the HTTP client
+    $httpClient = [System.Net.Http.HttpClient]::new($handler)
+
+    # Create the HTTP GET request message
+    $requestMessage = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Get, $uri)
+
+    # Send the request and get the response
+    $response = $httpClient.SendAsync($requestMessage).Result
+
+    # Extract and display the response headers
+    $response.Headers | ForEach-Object { "$($_.Key): $($_.Value)" }
+
+    # Optionally, get content as string if needed
+    $content = $response.Content.ReadAsStringAsync().Result
+    $content
+
+.EXAMPLE
+    No authentication
+
+    # Define the URI
+    $uri = [System.Uri]::new("http://localhost:8081/users")
+
+    # Create the HTTP client handler (no authentication)
+    $handler = [System.Net.Http.HttpClientHandler]::new()
+
+    # Create the HTTP client
+    $httpClient = [System.Net.Http.HttpClient]::new($handler)
+
+    # Create the HTTP GET request message
+    $requestMessage = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Get, $uri)
+
+    # Send the request and get the response
+    $response = $httpClient.SendAsync($requestMessage).Result
+
+    # Extract and display the response headers
+    $response.Headers | ForEach-Object { "$($_.Key): $($_.Value)" }
+
+    # Optionally, get content as string if needed
+    $content = $response.Content.ReadAsStringAsync().Result
+    $content
+
+.EXAMPLE
+    Wrong password
+
+    # Define the URI and wrong credentials
+    $uri = [System.Uri]::new("http://localhost:8081/users")
+    $wrongUsername = "wrongUser"
+    $wrongPassword = "wrongPassword"
+
+    # Create a credential cache and add Digest authentication with incorrect credentials
+    $credentialCache = [System.Net.CredentialCache]::new()
+    $networkCredential = [System.Net.NetworkCredential]::new($wrongUsername, $wrongPassword)
+    $credentialCache.Add($uri, "Digest", $networkCredential)
+
+    # Create the HTTP client handler with the credential cache
+    $handler = [System.Net.Http.HttpClientHandler]::new()
+    $handler.Credentials = $credentialCache
+
+    # Create the HTTP client
+    $httpClient = [System.Net.Http.HttpClient]::new($handler)
+
+    # Create the HTTP GET request message
+    $requestMessage = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Get, $uri)
+
+    # Send the request and get the response
+    $response = $httpClient.SendAsync($requestMessage).Result
+
+    # Display the response status code (to check for 401 Unauthorized)
+    $response.StatusCode
+
+    # Extract and display the response headers
+    $response.Headers | ForEach-Object { "$($_.Key): $($_.Value)" }
+
+    # Optionally, get content as string if needed
+    $content = $response.Content.ReadAsStringAsync().Result
+    $content
+
 
 .LINK
     https://github.com/Badgerati/Pode/blob/develop/examples/Web-AuthDigest.ps1
@@ -62,7 +152,7 @@ Start-PodeServer -Threads 2 {
     }
 
     # GET request to get list of users (since there's no session, authentication will always happen)
-    Add-PodeRoute -Method Get -Path '/users' -Authentication 'Validate' -ScriptBlock {
+    Add-PodeRoute -Method Get -Path '/users' -Authentication 'Validate' -ErrorContentType  'application/json' -ScriptBlock {
         Write-PodeJsonResponse -Value @{
             Users = @(
                 @{
diff --git a/examples/Web-AuthForm.ps1 b/examples/Web-AuthForm.ps1
index 45fad7a19..03fe2147d 100644
--- a/examples/Web-AuthForm.ps1
+++ b/examples/Web-AuthForm.ps1
@@ -63,7 +63,7 @@ Start-PodeServer -Threads 2 {
     Enable-PodeSessionMiddleware -Duration 120 -Extend
 
     # setup form auth (<form> in HTML)
-    New-PodeAuthScheme -Form | Add-PodeAuth -Name 'Login' -FailureUrl '/login' -SuccessUrl '/' -ScriptBlock {
+    New-PodeAuthScheme -Form | Add-PodeAuth -Name 'Login'  -FailureUrl '/login' -SuccessUrl '/' -ScriptBlock {
         param($username, $password)
 
         # here you'd check a real user storage, this is just for example
diff --git a/examples/Web-AuthManualErrorHandling.ps1 b/examples/Web-AuthManualErrorHandling.ps1
new file mode 100644
index 000000000..6e970cf67
--- /dev/null
+++ b/examples/Web-AuthManualErrorHandling.ps1
@@ -0,0 +1,215 @@
+<#
+.SYNOPSIS
+    A Pode server setup with manual authentication error handling.
+
+.DESCRIPTION
+    This script initializes a Pode web server on port 80 and configures custom API key authentication.
+    Instead of using Pode's default error handling, it manually processes authentication failures, providing
+    detailed responses based on the authentication result.
+
+.EXAMPLE
+    To run the script:
+
+        ./Web-AuthManualErrorHandling.ps1
+
+    Test it using:
+
+        Invoke-RestMethod -Uri http://localhost/api/v3/ -Headers @{ 'X-API-KEY' = 'test_user' } -Method Get
+
+.EXAMPLE
+   Digest
+   # Define the URI and credentials
+    $uri = [System.Uri]::new("http://localhost:8081/api/v3/whois")
+    $username = "morty"
+    $password = "pickle"
+
+    # Create a credential cache and add Digest authentication
+    $credentialCache = [System.Net.CredentialCache]::new()
+    $networkCredential = [System.Net.NetworkCredential]::new($username, $password)
+    $credentialCache.Add($uri, "Digest", $networkCredential)
+
+    # Create the HTTP client handler with the credential cache
+    $handler = [System.Net.Http.HttpClientHandler]::new()
+    $handler.Credentials = $credentialCache
+
+    # Create the HTTP client
+    $httpClient = [System.Net.Http.HttpClient]::new($handler)
+
+    # Create the HTTP GET request message
+    $requestMessage = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Get, $uri)
+
+    # Send the request and get the response
+    $response = $httpClient.SendAsync($requestMessage).Result
+
+    # Extract and display the response headers
+    $response.Headers | ForEach-Object { "$($_.Key): $($_.Value)" }
+
+    # Optionally, get content as string if needed
+    $content = $response.Content.ReadAsStringAsync().Result
+    $content
+
+.LINK
+    https://github.com/Badgerati/Pode/blob/develop/examples/Web-AuthManualErrorHandling.ps1
+
+.NOTES
+    Author: Pode Team
+    License: MIT License
+#>
+
+try {
+    # Determine the script's directory and Pode module path
+    $ScriptPath = (Split-Path -Parent -Path $MyInvocation.MyCommand.Path)
+    $podePath = Split-Path -Parent -Path $ScriptPath
+
+    # Import the Pode module from the source directory if available, otherwise use the installed module
+    if (Test-Path -Path "$($podePath)/src/Pode.psm1" -PathType Leaf) {
+        Import-Module "$($podePath)/src/Pode.psm1" -Force -ErrorAction Stop
+    }
+    else {
+        Import-Module -Name 'Pode' -MaximumVersion 2.99 -ErrorAction Stop
+    }
+}
+catch { throw }
+
+# Start the Pode server
+Start-PodeServer {
+    # Define an HTTP endpoint for the server
+    Add-PodeEndpoint -Address 'localhost' -Protocol 'Http' -Port '8081'
+
+    # Enable OpenAPI documentation and viewers
+    Enable-PodeOpenApi -Path '/docs/openapi' -OpenApiVersion '3.0.3' -DisableMinimalDefinitions -NoDefaultResponses
+    Add-PodeOAInfo -Title 'Custom Authentication Error Handling' -Version 1.0.0
+    Enable-PodeOAViewer -Type Swagger -Path '/docs/swagger'
+    Enable-PodeOAViewer -Bookmarks -Path '/docs'
+    Add-PodeOAServerEndpoint -Url '/api/v3' -Description 'Default API endpoint'
+
+    # Configure custom API key authentication
+    New-PodeAuthScheme -ApiKey | Add-PodeAuth -Name 'APIKey' -Sessionless -ScriptBlock {
+        param($key)
+        # Handle missing API key
+        if (!$key) {
+            return @{ Success = $false; Reason = 'No Authentication Header found' }
+        }
+
+        # Validate API key
+        if ($key -eq 'test_user') {
+            return @{ Success = $true; User = 'test_user'; UserId = 1 }
+        }
+
+        # Return failure for invalid users
+        return @{ Success = $false; User = $key; Reason = 'Not existing user' }
+    }
+
+
+    New-PodeAuthScheme -ApiKey | Add-PodeAuth -Name 'APIKey_standard' -Sessionless -ScriptBlock {
+        param($key)
+
+        # Validate API key
+        if ($key -eq 'test_user') {
+            return @{ Success = $true; User = 'test_user'; UserId = 1 }
+        }
+
+    }
+
+    New-PodeAuthScheme -Digest | Add-PodeAuth -Name 'Digest' -Sessionless -ScriptBlock {
+        param($username, $params)
+
+        # here you'd check a real user storage, this is just for example
+        if ($username -ieq 'morty') {
+            return @{
+                User     = @{
+                    ID   = 'M0R7Y302'
+                    Name = 'Morty'
+                    Type = 'Human'
+                }
+                Password = 'pickle'
+            }
+        }
+
+        return $null
+    }
+
+    # Define an API route with manual authentication error handling
+    Add-PodeRoute -PassThru -Method 'Get' -Path '/api/v3/whoami' -Authentication 'APIKey' -NoMiddlewareAuthentication -ScriptBlock {
+        # Manually invoke authentication
+        $auth = Invoke-PodeAuth -Name 'APIKey'
+
+        # Log authentication details for debugging
+        Write-PodeHost $auth -Explode
+
+        # If authentication succeeds, return user details
+        if ($auth.Success) {
+            Write-PodeJsonResponse -StatusCode 200 -Value @{
+                Success  = $true
+                Username = $auth.User
+                UserId   = $auth.UserId
+            }
+        }
+        else {
+            # Handle authentication failures with a custom error response
+            Write-PodeJsonResponse -StatusCode 401 -Value @{
+                Success  = $false
+                Message  = $auth.Reason
+                Username = $auth.User
+            }
+        }
+    } | Set-PodeOARouteInfo -Summary 'Who am I' -Tags 'auth' -OperationId 'whoami' -PassThru |
+        Add-PodeOAResponse -StatusCode 200 -Description 'Successful operation' -Content @{  'application/json' = (New-PodeOABoolProperty -Name 'Success' -Default $true | New-PodeOAStringProperty -Name 'Username' | New-PodeOAIntProperty -Name 'UserId' | New-PodeOAObjectProperty ) } -PassThru |
+        Add-PodeOAResponse -StatusCode 401 -Description 'Authentication failure' -Content @{  'application/json' = (New-PodeOABoolProperty -Name 'Success' -Default $false | New-PodeOAStringProperty -Name 'Username' | New-PodeOAStringProperty -Name 'Message' | New-PodeOAObjectProperty ) }
+
+    Add-PodeRoute -PassThru -Method 'Get' -Path '/api/v3/whoami_standard' -Authentication 'APIKey_standard' -ErrorContentType 'application/json'  -ScriptBlock {
+        # Manually invoke authentication
+        $auth = $WebEvent.Auth
+        # Log authentication details for debugging
+        Write-PodeHost $auth -Explode
+
+        # If authentication succeeds, return user details
+        if ($auth.Success) {
+            Write-PodeJsonResponse -StatusCode 200 -Value @{
+                Success  = $true
+                Username = $auth.User
+                UserId   = $auth.UserId
+            }
+        }
+        else {
+            # Handle authentication failures with a custom error response
+            Write-PodeJsonResponse -StatusCode 401 -Value @{
+                Success  = $false
+                Message  = $auth.Reason
+                Username = $auth.User
+            }
+        }
+    } | Set-PodeOARouteInfo -Summary 'Who am I (default auth)' -Tags 'auth' -OperationId 'whoami_standard' -PassThru |
+        Add-PodeOAResponse -StatusCode 200 -Description 'Successful operation' -Content @{  'application/json' = (New-PodeOABoolProperty -Name 'Success' -Default $true | New-PodeOAStringProperty -Name 'Username' | New-PodeOAIntProperty -Name 'UserId' | New-PodeOAObjectProperty ) } -PassThru |
+        Add-PodeOAResponse -StatusCode 401 -Description 'Authentication failure' -Content @{  'application/json' = (New-PodeOABoolProperty -Name 'Success' -Default $false | New-PodeOAStringProperty -Name 'Username' | New-PodeOAStringProperty -Name 'Message' | New-PodeOAObjectProperty ) }
+
+
+    # Define an API route with manual authentication error handling
+    Add-PodeRoute   -Method 'Get' -Path '/api/v3/whois' -Authentication 'Digest'   -ScriptBlock {
+        # Manually invoke authentication
+        $auth = $WebEvent.Auth
+
+        # Log authentication details for debugging
+        Write-PodeHost $Webauth -Explode
+
+        # If authentication succeeds, return user details
+        if ($auth.Success) {
+            Write-PodeJsonResponse -StatusCode 200 -Value @{
+                Success  = $true
+                Username = $auth.User.Name
+                UserId   = $auth.User.Id
+            }
+        }
+        else {
+            # Handle authentication failures with a custom error response
+            Write-PodeJsonResponse -StatusCode 401 -Value @{
+                Success  = $false
+                Message  = $auth.Reason
+                Username = $auth.User
+            }
+        }
+    }
+    #| Set-PodeOARouteInfo -Summary 'Who Is' -Tags 'auth' -OperationId 'whois' -PassThru |
+    #   Add-PodeOAResponse -StatusCode 200 -Description 'Successful operation' -Content @{  'application/json' = (New-PodeOABoolProperty -Name 'Success' -Default $true | New-PodeOAStringProperty -Name 'Username' | New-PodeOAIntProperty -Name 'UserId' | New-PodeOAObjectProperty ) } -PassThru |
+    #  Add-PodeOAResponse -StatusCode 401 -Description 'Authentication failure' -Content @{  'application/json' = (New-PodeOABoolProperty -Name 'Success' -Default $false | New-PodeOAStringProperty -Name 'Username' | New-PodeOAStringProperty -Name 'Message' | New-PodeOAObjectProperty ) }
+}
\ No newline at end of file
diff --git a/src/Locales/ar/Pode.psd1 b/src/Locales/ar/Pode.psd1
index c7e81c93c..e2d93715a 100644
--- a/src/Locales/ar/Pode.psd1
+++ b/src/Locales/ar/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'عرض OpenAPI'
     enableQuietModeMessage                                            = 'تمكين الوضع الصامت'
     disableQuietModeMessage                                           = 'تعطيل الوضع الصامت'
+    authMethodDoesNotExistExceptionMessage                            = 'طريقة المصادقة غير موجودة: {0}'
+    authenticationMethodMergedExceptionMessage                        = 'تم دمج طريقة المصادقة {0}'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "المعلمة '-NoMiddlewareAuthentication' يمكن استخدامها فقط عند تحديد '-Authentication'."
 }
diff --git a/src/Locales/de/Pode.psd1 b/src/Locales/de/Pode.psd1
index 5bdd32340..12b8232a1 100644
--- a/src/Locales/de/Pode.psd1
+++ b/src/Locales/de/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'OpenAPI anzeigen'
     enableQuietModeMessage                                            = 'Leisemodus aktivieren'
     disableQuietModeMessage                                           = 'Leisemodus deaktivieren'
+    authMethodDoesNotExistExceptionMessage                            = 'Authentifizierungsmethode existiert nicht: {0}'
+    authenticationMethodMergedExceptionMessage                        = 'Authentifizierungsmethode {0} wurde zusammengeführt'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "Der Parameter '-NoMiddlewareAuthentication' kann nur verwendet werden, wenn '-Authentication' angegeben ist."
 }
\ No newline at end of file
diff --git a/src/Locales/en-us/Pode.psd1 b/src/Locales/en-us/Pode.psd1
index e11f1a408..f0ea20b78 100644
--- a/src/Locales/en-us/Pode.psd1
+++ b/src/Locales/en-us/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'Show OpenAPI'
     enableQuietModeMessage                                            = 'Enable Quiet Mode'
     disableQuietModeMessage                                           = 'Disable Quiet Mode'
+    authMethodDoesNotExistExceptionMessage                            = "Authentication method doesn't exist: {0}"
+    authenticationMethodMergedExceptionMessage                        = 'Authentication method {0} is merged'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "The parameter '-NoMiddlewareAuthentication' can only be used when '-Authentication' is specified."
 }
\ No newline at end of file
diff --git a/src/Locales/en/Pode.psd1 b/src/Locales/en/Pode.psd1
index 755124e8f..1bf0fe490 100644
--- a/src/Locales/en/Pode.psd1
+++ b/src/Locales/en/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'Show OpenAPI'
     enableQuietModeMessage                                            = 'Enable Quiet Mode'
     disableQuietModeMessage                                           = 'Disable Quiet Mode'
+    authMethodDoesNotExistExceptionMessage                            = 'The authentication method does not exist: {0}'
+    authenticationMethodMergedExceptionMessage                        = 'The authentication method {0} has been merged'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "The parameter '-NoMiddlewareAuthentication' can only be used when '-Authentication' is specified."
 }
\ No newline at end of file
diff --git a/src/Locales/es/Pode.psd1 b/src/Locales/es/Pode.psd1
index 9b7175821..a3d38e97d 100644
--- a/src/Locales/es/Pode.psd1
+++ b/src/Locales/es/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'Mostrar OpenAPI'
     enableQuietModeMessage                                            = 'Activar modo silencioso'
     disableQuietModeMessage                                           = 'Desactivar modo silencioso'
+    authMethodDoesNotExistExceptionMessage                            = 'El método de autenticación no existe: {0}'
+    authenticationMethodMergedExceptionMessage                        = 'El método de autenticación {0} ha sido fusionado'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "El parámetro '-NoMiddlewareAuthentication' solo se puede usar cuando se especifica '-Authentication'."
 }
\ No newline at end of file
diff --git a/src/Locales/fr/Pode.psd1 b/src/Locales/fr/Pode.psd1
index f068b6f12..9f98c25b8 100644
--- a/src/Locales/fr/Pode.psd1
+++ b/src/Locales/fr/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'Afficher OpenAPI'
     enableQuietModeMessage                                            = 'Activer le mode silencieux'
     disableQuietModeMessage                                           = 'Désactiver le mode silencieux'
+    authMethodDoesNotExistExceptionMessage                            = "La méthode d'authentification n'existe pas : {0}"
+    authenticationMethodMergedExceptionMessage                        = "La méthode d'authentification {0} est fusionnée"
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "Le paramètre '-NoMiddlewareAuthentication' ne peut être utilisé que lorsque '-Authentication' est spécifié."
 }
\ No newline at end of file
diff --git a/src/Locales/it/Pode.psd1 b/src/Locales/it/Pode.psd1
index d4f0517c0..9752cfe80 100644
--- a/src/Locales/it/Pode.psd1
+++ b/src/Locales/it/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'Mostra OpenAPI'
     enableQuietModeMessage                                            = 'Abilita la modalità silenziosa'
     disableQuietModeMessage                                           = 'Disabilita la modalità silenziosa'
+    authMethodDoesNotExistExceptionMessage                            = 'Il metodo di autenticazione non esiste: {0}'
+    authenticationMethodMergedExceptionMessage                        = 'Il metodo di autenticazione {0} è stato unito'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "Il parametro '-NoMiddlewareAuthentication' può essere utilizzato solo se '-Authentication' è specificato."
 }
\ No newline at end of file
diff --git a/src/Locales/ja/Pode.psd1 b/src/Locales/ja/Pode.psd1
index dee48a022..d2d3b7c38 100644
--- a/src/Locales/ja/Pode.psd1
+++ b/src/Locales/ja/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'OpenAPIを表示'
     enableQuietModeMessage                                            = 'クワイエットモードを有効化'
     disableQuietModeMessage                                           = 'クワイエットモードを無効化'
+    authMethodDoesNotExistExceptionMessage                            = '認証方法が存在しません: {0}'
+    authenticationMethodMergedExceptionMessage                        = '認証方法 {0} が統合されました'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "パラメーター '-NoMiddlewareAuthentication' は、'-Authentication' が指定されている場合にのみ使用できます。"
 }
\ No newline at end of file
diff --git a/src/Locales/ko/Pode.psd1 b/src/Locales/ko/Pode.psd1
index 95e60140e..fd6d3a50e 100644
--- a/src/Locales/ko/Pode.psd1
+++ b/src/Locales/ko/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'OpenAPI 표시'
     enableQuietModeMessage                                            = '조용한 모드 활성화'
     disableQuietModeMessage                                           = '조용한 모드 비활성화'
+    authMethodDoesNotExistExceptionMessage                            = '인증 방법이 존재하지 않습니다: {0}'
+    authenticationMethodMergedExceptionMessage                        = '인증 방법 {0}이(가) 병합되었습니다'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "매개변수 '-NoMiddlewareAuthentication'은 '-Authentication'이 지정된 경우에만 사용할 수 있습니다."
 }
\ No newline at end of file
diff --git a/src/Locales/nl/Pode.psd1 b/src/Locales/nl/Pode.psd1
index f254feb64..6790518df 100644
--- a/src/Locales/nl/Pode.psd1
+++ b/src/Locales/nl/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'OpenAPI weergeven'
     enableQuietModeMessage                                            = 'Stille modus inschakelen'
     disableQuietModeMessage                                           = 'Stille modus uitschakelen'
+    authMethodDoesNotExistExceptionMessage                            = 'Authenticatiemethode bestaat niet: {0}'
+    authenticationMethodMergedExceptionMessage                        = 'Authenticatiemethode {0} is samengevoegd'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "De parameter '-NoMiddlewareAuthentication' kan alleen worden gebruikt als '-Authentication' is opgegeven."
 }
\ No newline at end of file
diff --git a/src/Locales/pl/Pode.psd1 b/src/Locales/pl/Pode.psd1
index 7319ae592..00ab1800f 100644
--- a/src/Locales/pl/Pode.psd1
+++ b/src/Locales/pl/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'Pokaż OpenAPI'
     enableQuietModeMessage                                            = 'Włącz tryb cichy'
     disableQuietModeMessage                                           = 'Wyłącz tryb cichy'
+    authMethodDoesNotExistExceptionMessage                            = 'Metoda uwierzytelniania nie istnieje: {0}'
+    authenticationMethodMergedExceptionMessage                        = 'Metoda uwierzytelniania {0} została scalona'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "Parametr '-NoMiddlewareAuthentication' można używać tylko, gdy określono '-Authentication'."
 }
\ No newline at end of file
diff --git a/src/Locales/pt/Pode.psd1 b/src/Locales/pt/Pode.psd1
index 4e1a8c613..a8a8660ea 100644
--- a/src/Locales/pt/Pode.psd1
+++ b/src/Locales/pt/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = 'Mostrar OpenAPI'
     enableQuietModeMessage                                            = 'Ativar modo silencioso'
     disableQuietModeMessage                                           = 'Desativar modo silencioso'
+    authMethodDoesNotExistExceptionMessage                            = 'O método de autenticação não existe: {0}'
+    authenticationMethodMergedExceptionMessage                        = 'O método de autenticação {0} foi mesclado'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "O parâmetro '-NoMiddlewareAuthentication' só pode ser usado quando '-Authentication' for especificado."
 }
\ No newline at end of file
diff --git a/src/Locales/zh/Pode.psd1 b/src/Locales/zh/Pode.psd1
index 8ac1c86b9..e55bee681 100644
--- a/src/Locales/zh/Pode.psd1
+++ b/src/Locales/zh/Pode.psd1
@@ -322,4 +322,7 @@
     showOpenAPIMessage                                                = '显示OpenAPI'
     enableQuietModeMessage                                            = '启用安静模式'
     disableQuietModeMessage                                           = '禁用安静模式'
+    authMethodDoesNotExistExceptionMessage                            = '身份验证方法不存在: {0}'
+    authenticationMethodMergedExceptionMessage                        = '身份验证方法 {0} 已合并'
+    parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage   = "参数 '-NoMiddlewareAuthentication' 只能在指定 '-Authentication' 时使用。"
 }
\ No newline at end of file
diff --git a/src/Pode.psd1 b/src/Pode.psd1
index f8929ec77..8dc3017ac 100644
--- a/src/Pode.psd1
+++ b/src/Pode.psd1
@@ -267,6 +267,7 @@
         'Test-PodeAuthExists',
         'Get-PodeAuthUser',
         'Add-PodeAuthSession',
+        'Invoke-PodeAuth',
 
         # access
         'New-PodeAccessScheme',
diff --git a/src/Private/Authentication.ps1 b/src/Private/Authentication.ps1
index f5a2273fd..af9897ed9 100644
--- a/src/Private/Authentication.ps1
+++ b/src/Private/Authentication.ps1
@@ -1,29 +1,81 @@
 function Get-PodeAuthBasicType {
+    <#
+    .SYNOPSIS
+        Processes Basic Authentication from the Authorization header.
+
+    .DESCRIPTION
+        The `Get-PodeAuthBasicType` function extracts and validates the Basic Authorization header
+        from an HTTP request. It verifies the header format, decodes Base64 credentials,
+        and returns the extracted username and password. If any validation step fails,
+        an appropriate HTTP response code and challenge are returned.
+
+    .PARAMETER options
+        A hashtable containing options for processing the authentication:
+        - `HeaderTag` [string]: Expected header prefix (e.g., "Basic").
+        - `Encoding` [string]: Character encoding for decoding the credentials (default: UTF-8).
+        - `AsCredential` [bool]: If true, returns credentials as a [PSCredential] object.
+
+    .OUTPUTS
+        [array]
+        Returns an array containing the extracted username and password.
+        If `AsCredential` is set to `$true`, returns a `[PSCredential]` object.
+
+    .EXAMPLE
+        $options = @{ HeaderTag = 'Basic'; Encoding = 'UTF-8'; AsCredential = $false }
+        $result = Get-PodeAuthBasicType -options $options
+
+        Returns:
+        @('username', 'password')
+
+    .EXAMPLE
+        $options = @{ HeaderTag = 'Basic'; Encoding = 'UTF-8'; AsCredential = $true }
+        $result = Get-PodeAuthBasicType -options $options
+
+        Returns:
+        [PSCredential] object containing username and password.
+
+    .NOTES
+        This function is internal to Pode and subject to change in future releases.
+
+        Possible response codes:
+        - 401 Unauthorized: When the Authorization header is missing.
+        - 400 Bad Request: For invalid format, encoding, or credential issues.
+
+        Challenge responses include the following error types:
+        - `invalid_request` for missing or incorrectly formatted headers.
+        - `invalid_token` for improperly encoded or malformed credentials.
+    #>
     return {
         param($options)
 
         # get the auth header
         $header = (Get-PodeHeader -Name 'Authorization')
         if ($null -eq $header) {
+            $message = 'No Authorization header found'
             return @{
-                Message = 'No Authorization header found'
-                Code    = 401
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 401
             }
         }
 
         # ensure the first atom is basic (or opt override)
         $atoms = $header -isplit '\s+'
         if ($atoms.Length -lt 2) {
+            $message = 'Invalid Authorization header format'
             return @{
-                Message = 'Invalid Authorization header'
-                Code    = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 400
             }
         }
 
         if ($atoms[0] -ine $options.HeaderTag) {
+            $message = "Header is not for $($options.HeaderTag) Authorization"
             return @{
-                Message = "Header is not for $($options.HeaderTag) Authorization"
-                Code    = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 400
             }
         }
 
@@ -32,9 +84,11 @@ function Get-PodeAuthBasicType {
             $enc = [System.Text.Encoding]::GetEncoding($options.Encoding)
         }
         catch {
+            $message = 'Invalid encoding specified for Authorization'
             return @{
-                Message = 'Invalid encoding specified for Authorization'
-                Code    = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 400
             }
         }
 
@@ -42,9 +96,22 @@ function Get-PodeAuthBasicType {
             $decoded = $enc.GetString([System.Convert]::FromBase64String($atoms[1]))
         }
         catch {
+            $message = 'Invalid Base64 string found in Authorization header'
+            return @{
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_token -ErrorDescription $message)
+                Code      = 400
+            }
+        }
+
+        # ensure the decoded string contains a colon separator
+        $index = $decoded.IndexOf(':')
+        if ($index -lt 0) {
+            $message = 'Invalid Authorization credential format'
             return @{
-                Message = 'Invalid Base64 string found in Authorization header'
-                Code    = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 400
             }
         }
 
@@ -68,6 +135,7 @@ function Get-PodeAuthBasicType {
     }
 }
 
+
 function Get-PodeAuthOAuth2Type {
     return {
         param($options, $schemes)
@@ -282,32 +350,91 @@ function Get-PodeOAuth2RedirectHost {
 }
 
 function Get-PodeAuthClientCertificateType {
+    <#
+    .SYNOPSIS
+        Validates and extracts information from a client certificate in an HTTP request.
+
+    .DESCRIPTION
+        The `Get-PodeAuthClientCertificateType` function processes the client certificate
+        from an incoming HTTP request. It validates whether the certificate is supplied,
+        checks its validity, and ensures it's trusted. If any of these checks fail,
+        appropriate response codes and challenges are returned.
+
+    .PARAMETER options
+        A hashtable containing options that can be used to extend the function in the future.
+
+    .OUTPUTS
+        [array]
+        Returns an array containing the validated client certificate and any associated errors.
+
+    .EXAMPLE
+        $options = @{}
+        $result = Get-PodeAuthClientCertificateType -options $options
+
+        Returns:
+        An array with the client certificate object and any certificate validation errors.
+
+    .EXAMPLE
+        $options = @{}
+        $result = Get-PodeAuthClientCertificateType -options $options
+
+        Example Output:
+        @($cert, 0)
+
+    .NOTES
+        This function is internal to Pode and subject to change in future releases.
+
+        Possible response codes:
+        - 401 Unauthorized: When the client certificate is missing or invalid.
+        - 403 Forbidden: When the client certificate is untrusted.
+
+        Challenge responses include the following error types:
+        - `invalid_request`: If no certificate is provided.
+        - `invalid_token`: If the certificate is invalid, expired, or untrusted.
+
+    #>
     return {
         param($options)
         $cert = $WebEvent.Request.ClientCertificate
 
         # ensure we have a client cert
         if ($null -eq $cert) {
+            $message = 'No client certificate supplied'
             return @{
-                Message = 'No client certificate supplied'
-                Code    = 401
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 401
             }
         }
 
         # ensure the cert has a thumbprint
         if ([string]::IsNullOrWhiteSpace($cert.Thumbprint)) {
+            $message = 'Invalid client certificate supplied'
             return @{
-                Message = 'Invalid client certificate supplied'
-                Code    = 401
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_token -ErrorDescription $message)
+                Code      = 401
             }
         }
 
         # ensure the cert hasn't expired, or has it even started
         $now = [datetime]::Now
         if (($cert.NotAfter -lt $now) -or ($cert.NotBefore -gt $now)) {
+            $message = 'Invalid client certificate supplied (expired or not yet valid)'
+            return @{
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_token -ErrorDescription $message)
+                Code      = 401
+            }
+        }
+
+        $errors = $WebEvent.Request.ClientCertificateErrors
+        if ($errors -ne 0) {
+            $message = 'Untrusted client certificate supplied'
             return @{
-                Message = 'Invalid client certificate supplied'
-                Code    = 401
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_token -ErrorDescription $message)
+                Code      = 403
             }
         }
 
@@ -316,13 +443,45 @@ function Get-PodeAuthClientCertificateType {
     }
 }
 
+
 function Get-PodeAuthApiKeyType {
+    <#
+    .SYNOPSIS
+        Handles API key authentication by retrieving the key from various locations.
+
+    .DESCRIPTION
+        The `Get-PodeAuthApiKeyType` function extracts and validates API keys
+        from specified locations such as headers, query parameters, or cookies.
+        If the API key is found, it is returned as a result; otherwise,
+        an appropriate authentication challenge is issued.
+
+    .PARAMETER $options
+        A hashtable containing the following keys:
+        - `Location`: Specifies where to retrieve the API key from (`header`, `query`, or `cookie`).
+        - `LocationName`: The name of the header, query parameter, or cookie that holds the API key.
+        - `AsJWT`: (Optional) If set to `$true`, the function will treat the API key as a JWT token.
+        - `Secret`: (Required if `AsJWT` is `$true`) The secret used to validate the JWT token.
+
+    .OUTPUTS
+        [array]
+        Returns an array containing the extracted API key or JWT payload if authentication is successful.
+
+    .NOTES
+        The function will return an HTTP 400 response code if the API key is not found.
+        If `AsJWT` is enabled, the key will be decoded and validated using the provided secret.
+        The challenge response is formatted to align with authentication best practices.
+
+        Possible HTTP response codes:
+        - 400 Bad Request: When the API key is missing or JWT validation fails.
+
+    #>
     return {
         param($options)
 
-        # get api key from appropriate location
+        # Initialize API key variable
         $apiKey = [string]::Empty
 
+        # Determine API key location and retrieve it
         switch ($options.Location.ToLowerInvariant()) {
             'header' {
                 $apiKey = Get-PodeHeader -Name $options.LocationName
@@ -335,38 +494,49 @@ function Get-PodeAuthApiKeyType {
             'cookie' {
                 $apiKey = Get-PodeCookieValue -Name $options.LocationName
             }
+            default {
+                $message = "Invalid API key location: $($options.Location)"
+                return @{
+                    Message   = $message
+                    Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                    Code      = 400
+                }
+            }
         }
 
-        # 400 if no key
+        # If no API key found, return error
         if ([string]::IsNullOrWhiteSpace($apiKey)) {
+            $message = "API key missing in $($options.Location) location: $($options.LocationName)"
             return @{
-                Message = "No $($options.LocationName) $($options.Location) found"
-                Code    = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 400
             }
         }
 
-        # build the result
+        # Trim and process the API key
         $apiKey = $apiKey.Trim()
         $result = @($apiKey)
 
-        # convert as jwt?
+        # Convert to JWT if required
         if ($options.AsJWT) {
             try {
                 $payload = ConvertFrom-PodeJwt -Token $apiKey -Secret $options.Secret
                 Test-PodeJwt -Payload $payload
+                $result = @($payload)
             }
             catch {
                 if ($_.Exception.Message -ilike '*jwt*') {
+                    $message = "Invalid JWT token: $($_.Exception.Message)"
                     return @{
-                        Message = $_.Exception.Message
-                        Code    = 400
+                        Message   = $message
+                        Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                        Code      = 400
                     }
                 }
 
                 throw
             }
-
-            $result = @($payload)
         }
 
         # return the result
@@ -375,51 +545,96 @@ function Get-PodeAuthApiKeyType {
 }
 
 function Get-PodeAuthBearerType {
+    <#
+    .SYNOPSIS
+        Validates the Bearer token in the Authorization header.
+
+    .DESCRIPTION
+        This function processes the Authorization header, verifies the presence of a Bearer token,
+        and optionally decodes it as a JWT. It returns appropriate HTTP response codes
+        as per RFC 6750 (OAuth 2.0 Bearer Token Usage).
+
+    .PARAMETER $options
+        A hashtable containing the following keys:
+        - Realm: The authentication realm.
+        - Scopes: Expected scopes for the token.
+        - HeaderTag: The expected Authorization header tag (e.g., 'Bearer').
+        - AsJWT: Boolean indicating if the token should be processed as a JWT.
+        - Secret: Secret key for JWT verification.
+
+    .OUTPUTS
+        A hashtable containing the following keys based on the validation result:
+        - Message: Error or success message.
+        - Code: HTTP response code.
+        - Header: HTTP response header for authentication challenges.
+        - Challenge: Optional authentication challenge.
+
+    .NOTES
+        The function adheres to RFC 6750, which mandates:
+        - 401 Unauthorized for missing or invalid authentication credentials.
+        - 400 Bad Request for malformed requests.
+
+        RFC 6750 HTTP Status Code Usage
+        # | Scenario                                  | Recommended Status Code |
+        # |-------------------------------------------|-------------------------|
+        # | No Authorization header provided          | 401 Unauthorized        |
+        # | Incorrect Authorization header format     | 401 Unauthorized        |
+        # | Wrong authentication scheme used          | 401 Unauthorized        |
+        # | Token is empty or malformed               | 400 Bad Request         |
+        # | Invalid JWT signature                     | 401 Unauthorized        |
+    #>
     return {
         param($options)
 
-        # get the auth header
+        # Get the Authorization header
         $header = (Get-PodeHeader -Name 'Authorization')
+
+        # If no Authorization header is provided, return 401 Unauthorized
         if ($null -eq $header) {
+            $message = 'No Authorization header found'
             return @{
-                Message   = 'No Authorization header found'
-                Challenge = (New-PodeAuthBearerChallenge -Scopes $options.Scopes -ErrorType invalid_request)
-                Code      = 400
+                Message   = $message
+                Challenge = New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType invalid_request -ErrorDescription $message
+                Code      = 401  # RFC 6750: Missing credentials should return 401
             }
         }
 
-        # ensure the first atom is bearer
+        # Ensure the first part of the header is 'Bearer'
         $atoms = $header -isplit '\s+'
         if ($atoms.Length -lt 2) {
+            $message = 'Invalid Authorization header format'
             return @{
-                Message   = 'Invalid Authorization header'
-                Challenge = (New-PodeAuthBearerChallenge -Scopes $options.Scopes -ErrorType invalid_request)
-                Code      = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 401  # RFC 6750: Invalid credentials format should return 401
             }
         }
 
         if ($atoms[0] -ine $options.HeaderTag) {
+            $message = "Authorization header is not $($options.HeaderTag)"
             return @{
-                Message   = "Authorization header is not $($options.HeaderTag)"
-                Challenge = (New-PodeAuthBearerChallenge -Scopes $options.Scopes -ErrorType invalid_request)
-                Code      = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 401  # RFC 6750: Wrong authentication scheme should return 401
             }
         }
 
-        # 400 if no token
+        # 400 Bad Request if no token is provided
         $token = $atoms[1]
         if ([string]::IsNullOrWhiteSpace($token)) {
+            $message = 'No Bearer token found'
             return @{
-                Message = 'No Bearer token found'
-                Code    = 400
+                Message   = $message
+                Code      = 400  # RFC 6750: Malformed request should return 400
+                Challenge = New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType invalid_request -ErrorDescription $message
             }
         }
 
-        # build the result
+        # Trim and build the result
         $token = $token.Trim()
         $result = @($token)
 
-        # convert as jwt?
+        # Convert to JWT if required
         if ($options.AsJWT) {
             try {
                 $payload = ConvertFrom-PodeJwt -Token $token -Secret $options.Secret
@@ -428,9 +643,9 @@ function Get-PodeAuthBearerType {
             catch {
                 if ($_.Exception.Message -ilike '*jwt*') {
                     return @{
-                        Message = $_.Exception.Message
-                        #https://www.rfc-editor.org/rfc/rfc6750 Bearer token should return 401
-                        Code    = 401
+                        Message   = $_.Exception.Message
+                        Code      = 401  # RFC 6750: Invalid token should return 401
+                        Challenge = New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType invalid_token -ErrorDescription $_.Exception.Message
                     }
                 }
 
@@ -440,102 +655,142 @@ function Get-PodeAuthBearerType {
             $result = @($payload)
         }
 
-        # return the result
+        # Return the validated result
         return $result
     }
 }
 
 function Get-PodeAuthBearerPostValidator {
+    <#
+    .SYNOPSIS
+        Validates the Bearer token and user authentication.
+
+    .DESCRIPTION
+        This function processes the Bearer token, checks for the presence of a valid user,
+        and verifies token scopes against required scopes. It returns appropriate HTTP response codes
+        as per RFC 6750 (OAuth 2.0 Bearer Token Usage).
+
+    .PARAMETER token
+        The Bearer token provided by the client.
+
+    .PARAMETER result
+        The decoded token result containing user and scope information.
+
+    .PARAMETER options
+        A hashtable containing the following keys:
+        - Scopes: An array of required scopes for authorization.
+
+    .OUTPUTS
+        A hashtable containing the following keys based on the validation result:
+        - Message: Error or success message.
+        - Code: HTTP response code.
+        - Challenge: HTTP response challenge in case of errors.
+
+    .NOTES
+        The function adheres to RFC 6750, which mandates:
+        - 401 Unauthorized for missing or invalid authentication credentials.
+        - 403 Forbidden for insufficient scopes.
+    #>
     return {
         param($token, $result, $options)
 
-        # if there's no user, fail with challenge
+        # Validate user presence in the token
         if (($null -eq $result) -or ($null -eq $result.User)) {
+            $message = 'User authentication failed'
             return @{
-                Message   = 'User not found'
-                Challenge = (New-PodeAuthBearerChallenge -Scopes $options.Scopes -ErrorType invalid_token)
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType invalid_token -ErrorDescription $message )
                 Code      = 401
             }
         }
 
-        # check for an error and description
+        # Check for token error and return appropriate response
         if (![string]::IsNullOrWhiteSpace($result.Error)) {
             return @{
-                Message   = 'Authorization failed'
-                Challenge = (New-PodeAuthBearerChallenge -Scopes $options.Scopes -ErrorType $result.Error -ErrorDescription $result.ErrorDescription)
+                Message   = $result.ErrorDescription
+                Challenge = (New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType $result.Error -ErrorDescription $result.ErrorDescription)
                 Code      = 401
             }
         }
 
-        # check the scopes
+        # Scope validation
         $hasAuthScopes = (($null -ne $options.Scopes) -and ($options.Scopes.Length -gt 0))
-        $hasTokenScope = ![string]::IsNullOrWhiteSpace($result.Scope)
+        $hasTokenScope = (($null -ne $result.Scope) -and ($result.Scope.Length -gt 0))
 
-        # 403 if we have auth scopes but no token scope
+        # Return 403 if authorization scopes exist but token lacks scopes
         if ($hasAuthScopes -and !$hasTokenScope) {
+            $message = 'Token scope is missing or invalid'
             return @{
-                Message   = 'Invalid Scope'
-                Challenge = (New-PodeAuthBearerChallenge -Scopes $options.Scopes -ErrorType insufficient_scope)
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType insufficient_scope -ErrorDescription $message )
                 Code      = 403
             }
         }
 
-        # 403 if we have both, but token not in auth scope
-        if ($hasAuthScopes -and $hasTokenScope -and ($options.Scopes -notcontains $result.Scope)) {
+        # Return 403 if token scopes do not intersect with required auth scopes
+        if ($hasAuthScopes -and $hasTokenScope -and (-not ($options.Scopes | Where-Object { $_ -in $result.Scope }))) {
+            $message = 'Token scope is insufficient'
             return @{
-                Message   = 'Invalid Scope'
-                Challenge = (New-PodeAuthBearerChallenge -Scopes $options.Scopes -ErrorType insufficient_scope)
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -Scopes $options.Scopes -ErrorType insufficient_scope -ErrorDescription $message )
                 Code      = 403
             }
         }
 
-        # return result
+        # Return the validated token result
         return $result
     }
 }
 
-function New-PodeAuthBearerChallenge {
-    param(
-        [Parameter()]
-        [string[]]
-        $Scopes,
-
-        [Parameter()]
-        [ValidateSet('', 'invalid_request', 'invalid_token', 'insufficient_scope')]
-        [string]
-        $ErrorType,
-
-        [Parameter()]
-        [string]
-        $ErrorDescription
-    )
-
-    $items = @()
-    if (($null -ne $Scopes) -and ($Scopes.Length -gt 0)) {
-        $items += "scope=`"$($Scopes -join ' ')`""
-    }
-
-    if (![string]::IsNullOrWhiteSpace($ErrorType)) {
-        $items += "error=`"$($ErrorType)`""
-    }
 
-    if (![string]::IsNullOrWhiteSpace($ErrorDescription)) {
-        $items += "error_description=`"$($ErrorDescription)`""
-    }
-
-    return ($items -join ', ')
-}
 
 function Get-PodeAuthDigestType {
+    <#
+    .SYNOPSIS
+        Validates the Digest token in the Authorization header.
+
+    .DESCRIPTION
+        This function processes the Authorization header, verifies the presence of a Digest token,
+        and optionally decodes it. It returns appropriate HTTP response codes
+        as per RFC 7616 (HTTP Digest Access Authentication).
+
+    .PARAMETER $options
+        A hashtable containing the following keys:
+        - Realm: The authentication realm.
+        - Nonce: A unique value provided by the server to prevent replay attacks.
+        - HeaderTag: The expected Authorization header tag (e.g., 'Digest').
+
+    .OUTPUTS
+        A hashtable containing the following keys based on the validation result:
+        - Message: Error or success message.
+        - Code: HTTP response code.
+        - Challenge: Optional authentication challenge.
+
+    .NOTES
+        The function adheres to RFC 7616, which mandates:
+        - 401 Unauthorized for missing or invalid authentication credentials.
+        - 400 Bad Request for malformed requests.
+
+        - RFC 7616 HTTP Status Code Usage
+        | Scenario                                  | Recommended Status Code |
+        |-------------------------------------------|-------------------------|
+        | No Authorization header provided          | 401 Unauthorized         |
+        | Incorrect Authorization header format     | 401 Unauthorized         |
+        | Wrong authentication scheme used          | 401 Unauthorized         |
+        | Token is empty or malformed               | 400 Bad Request          |
+        | Invalid digest response                   | 401 Unauthorized         |
+
+    #>
     return {
         param($options)
-
+        $nonce = (New-PodeGuid -Secure -NoDashes)
         # get the auth header - send challenge if missing
         $header = (Get-PodeHeader -Name 'Authorization')
         if ($null -eq $header) {
+            $message = 'No Authorization header found'
             return @{
-                Message   = 'No Authorization header found'
-                Challenge = (New-PodeAuthDigestChallenge)
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorDescription $message -Nonce $nonce)
                 Code      = 401
             }
         }
@@ -543,16 +798,19 @@ function Get-PodeAuthDigestType {
         # if auth header isn't digest send challenge
         $atoms = $header -isplit '\s+'
         if ($atoms.Length -lt 2) {
+            $message = 'Invalid Authorization header format'
             return @{
-                Message = 'Invalid Authorization header'
-                Code    = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorDescription $message -Nonce $nonce )
+                Code      = 401  # RFC 7616: Invalid credentials format should return 401
             }
         }
 
         if ($atoms[0] -ine $options.HeaderTag) {
+            $message = "Authorization header is not $($options.HeaderTag)"
             return @{
-                Message   = "Authorization header is not $($options.HeaderTag)"
-                Challenge = (New-PodeAuthDigestChallenge)
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorDescription $message -Nonce $nonce)
                 Code      = 401
             }
         }
@@ -560,26 +818,31 @@ function Get-PodeAuthDigestType {
         # parse the other atoms of the header (after the scheme), return 400 if none
         $params = ConvertFrom-PodeAuthDigestHeader -Parts ($atoms[1..$($atoms.Length - 1)])
         if ($params.Count -eq 0) {
+            $message = 'Invalid Authorization header'
             return @{
-                Message = 'Invalid Authorization header'
-                Code    = 400
+                Message   = $message
+                Code      = 400
+                Challenge = (New-PodeAuthChallenge -ErrorDescription $message -Nonce $nonce)
             }
         }
 
         # if no username then 401 and challenge
         if ([string]::IsNullOrWhiteSpace($params.username)) {
+            $message = 'Authorization header is missing username'
             return @{
-                Message   = 'Authorization header is missing username'
-                Challenge = (New-PodeAuthDigestChallenge)
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorDescription $message )#  -Nonce $nonce)
                 Code      = 401
             }
         }
 
         # return 400 if domain doesnt match request domain
         if ($WebEvent.Path -ine $params.uri) {
+            $message = 'Invalid Authorization header'
             return @{
-                Message = 'Invalid Authorization header'
-                Code    = 400
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorDescription $message)#  -Nonce $nonce )
+                Code      = 400
             }
         }
 
@@ -588,15 +851,100 @@ function Get-PodeAuthDigestType {
     }
 }
 
+<#
+.SYNOPSIS
+    Validates digest authentication responses for incoming requests.
+
+.DESCRIPTION
+    The `Get-PodeAuthDigestPostValidator` function processes and validates HTTP digest
+    authentication responses by comparing the computed hash with the client's provided response.
+    It ensures the provided credentials are correct and returns appropriate challenges
+    if validation fails.
+
+.PARAMETER username
+    The username extracted from the client's authentication request.
+
+.PARAMETER params
+    A hashtable containing digest authentication parameters, including:
+    - `username`: The username provided in the request.
+    - `realm`: The authentication realm.
+    - `nonce`: A unique server-generated nonce value.
+    - `uri`: The requested resource URI.
+    - `nc`: Nonce count (tracking the number of requests).
+    - `cnonce`: Client-generated nonce value.
+    - `qop`: Quality of protection value.
+    - `response`: The client's hashed response to be verified.
+
+.PARAMETER result
+    A hashtable containing the user data retrieved from the authentication source.
+    This should include:
+    - `User`: The username.
+    - `Password`: The stored password or hash for verification.
+
+.PARAMETER options
+    Additional options for authentication processing, if required.
+
+.OUTPUTS
+    On successful validation, returns the user data with the password removed.
+    If authentication fails, returns an error response with a challenge and HTTP status code.
+
+.EXAMPLE
+    $params = @{
+        username = "morty"
+        realm    = "PodeRealm"
+        nonce    = "abc123"
+        uri      = "/protected"
+        nc       = "00000001"
+        cnonce   = "xyz456"
+        qop      = "auth"
+        response = "expected-client-hash"
+    }
+
+    $result = @{
+        User     = "morty"
+        Password = "pickle"
+    }
+
+    Get-PodeAuthDigestPostValidator -username "morty" -params $params -result $result -options $null
+
+    Returns:
+    @{'User'='morty'}
+
+.EXAMPLE
+    Get-PodeAuthDigestPostValidator -username "unknown" -params $params -result $null -options $null
+
+    Returns:
+    @{
+        Message   = "Invalid credentials"
+        Challenge = "Digest realm=\"PodeRealm\", error_description=\"Invalid credentials\""
+        Code      = 401
+    }
+
+.NOTES
+    This function performs digest authentication validation by:
+    - Generating an MD5 hash using the provided credentials and digest parameters.
+    - Comparing the computed hash with the client's provided response.
+    - Handling authentication failures by returning appropriate challenges.
+
+    Possible HTTP response codes:
+    - 401 Unauthorized: When credentials are missing, incorrect, or authentication fails.
+
+    Digest authentication elements included:
+    - `qop="auth"`
+    - `algorithm="MD5"`
+    - `nonce="<generated_nonce>"`
+
+#>
 function Get-PodeAuthDigestPostValidator {
     return {
         param($username, $params, $result, $options)
 
         # if there's no user or password, fail with challenge
         if (($null -eq $result) -or ($null -eq $result.User) -or [string]::IsNullOrWhiteSpace($result.Password)) {
+            $message = 'Invalid credentials'
             return @{
-                Message   = 'User not found'
-                Challenge = (New-PodeAuthDigestChallenge)
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -Nonce $params.nonce -ErrorDescription $message)
                 Code      = 401
             }
         }
@@ -612,9 +960,10 @@ function Get-PodeAuthDigestPostValidator {
 
         # compare final hash to client response
         if ($final -ne $params.response) {
+            $message = 'Invalid authentication response'
             return @{
-                Message   = 'Hashes failed to match'
-                Challenge = (New-PodeAuthDigestChallenge)
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -Nonce $params.nonce -ErrorDescription $message)
                 Code      = 401
             }
         }
@@ -625,6 +974,7 @@ function Get-PodeAuthDigestPostValidator {
     }
 }
 
+
 function ConvertFrom-PodeAuthDigestHeader {
     param(
         [Parameter()]
@@ -648,12 +998,59 @@ function ConvertFrom-PodeAuthDigestHeader {
     return $obj
 }
 
-function New-PodeAuthDigestChallenge {
-    $items = @('qop="auth"', 'algorithm="MD5"', "nonce=`"$(New-PodeGuid -Secure -NoDashes)`"")
-    return ($items -join ', ')
-}
-
 function Get-PodeAuthFormType {
+    <#
+    .SYNOPSIS
+        Processes form-based authentication requests.
+
+    .DESCRIPTION
+        The `Get-PodeAuthFormType` function extracts and validates user credentials from
+        an incoming HTTP form submission. It verifies the presence and format of the
+        provided username and password and optionally converts them to secure credentials.
+
+    .PARAMETER $options
+        A hashtable containing configuration options for the authentication process.
+        Expected keys:
+        - `Fields.Username`: The key used to extract the username from the request data.
+        - `Fields.Password`: The key used to extract the password from the request data.
+        - `AsCredential`: (Boolean) If true, converts credentials into a [PSCredential] object.
+
+    .OUTPUTS
+        [array]
+        Returns an array containing the validated username and password.
+        If `AsCredential` is set to `$true`, returns a `[PSCredential]` object.
+
+    .EXAMPLE
+        $options = @{
+            Fields = @{ Username = 'user'; Password = 'pass' }
+            AsCredential = $false
+        }
+        $result = Get-PodeAuthFormType -options $options
+
+        Returns:
+        @('user123', 'securePassword')
+
+    .EXAMPLE
+        $options = @{
+            Fields = @{ Username = 'user'; Password = 'pass' }
+            AsCredential = $true
+        }
+        $result = Get-PodeAuthFormType -options $options
+
+        Returns:
+        [PSCredential] object containing username and password.
+
+    .NOTES
+        This function performs several checks, including:
+        - Ensuring both username and password are provided.
+        - Validating the username format (only alphanumeric, dot, underscore, and dash allowed).
+        - Returning HTTP status codes and error messages in case of validation failures.
+
+        Possible HTTP response codes:
+        - 401 Unauthorized: When credentials are missing or incomplete.
+        - 400 Bad Request: When the username format is invalid.
+
+    #>
     return {
         param($options)
 
@@ -665,11 +1062,41 @@ function Get-PodeAuthFormType {
         $username = $WebEvent.Data.$userField
         $password = $WebEvent.Data.$passField
 
-        # if either are empty, fail auth
-        if ([string]::IsNullOrWhiteSpace($username) -or [string]::IsNullOrWhiteSpace($password)) {
+        # Handle cases where fields are missing or empty
+        if ([string]::IsNullOrWhiteSpace($username) -and [string]::IsNullOrWhiteSpace($password)) {
+            $message = 'Username and password must be provided'
+            return @{
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 401
+            }
+        }
+
+        if ([string]::IsNullOrWhiteSpace($username)) {
+            $message = 'Username is required'
+            return @{
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 401
+            }
+        }
+
+        if ([string]::IsNullOrWhiteSpace($password)) {
+            $message = 'Password is required'
+            return @{
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 401
+            }
+        }
+
+        # Validate username format
+        if ($username -notmatch '^[a-zA-Z0-9._-]{3,20}$') {
+            $message = 'Invalid username format'
             return @{
-                Message = 'Username or Password not supplied'
-                Code    = 401
+                Message   = $message
+                Challenge = (New-PodeAuthChallenge -ErrorType invalid_request -ErrorDescription $message)
+                Code      = 400
             }
         }
 
@@ -1197,21 +1624,45 @@ function Invoke-PodeAuthValidation {
     return $result
 }
 
+<#
+.SYNOPSIS
+    Tests the authentication validation for a specified authentication method.
+
+.DESCRIPTION
+    The `Test-PodeAuthValidation` function processes an authentication method by its name,
+    running the associated scripts, middleware, and validations to determine authentication success or failure.
+
+.PARAMETER Name
+    The name of the authentication method to validate. This parameter is mandatory.
+
+.PARAMETER NoMiddlewareAuthentication
+    A switch to indicate whether the function has to threat the authentication because no Middleware authentication has been executed.
+
+.OUTPUTS
+    A hashtable containing the authentication validation result, including success status, user details,
+    headers, and redirection information if applicable.
+
+.NOTES
+    This is an internal function and is subject to change in future versions of Pode.
+#>
 function Test-PodeAuthValidation {
     param(
         [Parameter(Mandatory = $true)]
         [string]
-        $Name
+        $Name,
+
+        [switch]
+        $NoMiddlewareAuthentication
     )
 
     try {
-        # get auth method
+        # Retrieve authentication method configuration from Pode context
         $auth = $PodeContext.Server.Authentications.Methods[$Name]
 
-        # auth result
+        # Initialize authentication result variable
         $result = $null
 
-        # run pre-auth middleware
+        # Run pre-authentication middleware if defined
         if ($null -ne $auth.Scheme.Middleware) {
             if (!(Invoke-PodeMiddleware -Middleware $auth.Scheme.Middleware)) {
                 return @{
@@ -1220,26 +1671,28 @@ function Test-PodeAuthValidation {
             }
         }
 
-        # run auth scheme script to parse request for data
+        # Prepare arguments for the authentication scheme script
         $_args = @(Merge-PodeScriptblockArguments -ArgumentList $auth.Scheme.Arguments -UsingVariables $auth.Scheme.ScriptBlock.UsingVariables)
 
-        # call inner schemes first
+        # Handle inner authentication schemes (if any)
         if ($null -ne $auth.Scheme.InnerScheme) {
             $schemes = @()
-
             $_scheme = $auth.Scheme
+
+            # Traverse through the inner schemes to collect them
             $_inner = @(while ($null -ne $_scheme.InnerScheme) {
                     $_scheme = $_scheme.InnerScheme
                     $_scheme
                 })
 
+            # Process inner schemes in reverse order
             for ($i = $_inner.Length - 1; $i -ge 0; $i--) {
                 $_tmp_args = @(Merge-PodeScriptblockArguments -ArgumentList $_inner[$i].Arguments -UsingVariables $_inner[$i].ScriptBlock.UsingVariables)
-
                 $_tmp_args += , $schemes
+
                 $result = (Invoke-PodeScriptBlock -ScriptBlock $_inner[$i].ScriptBlock.Script -Arguments $_tmp_args -Return -Splat)
                 if ($result -is [hashtable]) {
-                    break
+                    break  # Exit if a valid result is returned
                 }
 
                 $schemes += , $result
@@ -1249,25 +1702,32 @@ function Test-PodeAuthValidation {
             $_args += , $schemes
         }
 
+        # Execute the primary authentication script if no result from inner schemes and not a route script
         if ($null -eq $result) {
             $result = (Invoke-PodeScriptBlock -ScriptBlock $auth.Scheme.ScriptBlock.Script -Arguments $_args -Return -Splat)
         }
 
-        # if data is a hashtable, then don't call validator (parser either failed, or forced a success)
+        # Handle NoMiddlewareAuthentication case
+        if ($NoMiddlewareAuthentication) {
+            return Invoke-PodeAuthNoMiddleware -Result $result -Auth $auth
+        }
+
+        # If authentication script returns a non-hashtable, perform further validation
         if ($result -isnot [hashtable]) {
             $original = $result
-
             $_args = @($result) + @($auth.Arguments)
+
+            # Run main authentication validation script
             $result = (Invoke-PodeScriptBlock -ScriptBlock $auth.ScriptBlock -Arguments $_args -UsingVariables $auth.UsingVariables -Return -Splat)
 
-            # if we have user, then run post validator if present
+            # Run post-authentication validation if applicable
             if ([string]::IsNullOrEmpty($result.Code) -and ($null -ne $auth.Scheme.PostValidator.Script)) {
                 $_args = @($original) + @($result) + @($auth.Scheme.Arguments)
                 $result = (Invoke-PodeScriptBlock -ScriptBlock $auth.Scheme.PostValidator.Script -Arguments $_args -UsingVariables $auth.Scheme.PostValidator.UsingVariables -Return -Splat)
             }
         }
 
-        # is the auth trying to redirect ie: oauth?
+        # Handle authentication redirection scenarios (e.g., OAuth)
         if ($result.IsRedirected) {
             return @{
                 Success    = $false
@@ -1275,11 +1735,13 @@ function Test-PodeAuthValidation {
             }
         }
 
-        # if there's no result, or no user, then the auth failed - but allow auth if anon enabled
+
+
+        # Authentication failure handling
         if (($null -eq $result) -or ($result.Count -eq 0) -or (Test-PodeIsEmpty $result.User)) {
             $code = (Protect-PodeValue -Value $result.Code -Default 401)
 
-            # set the www-auth header
+            # Set WWW-Authenticate header for appropriate HTTP response
             $validCode = (($code -eq 401) -or ![string]::IsNullOrEmpty($result.Challenge))
 
             if ($validCode) {
@@ -1291,6 +1753,7 @@ function Test-PodeAuthValidation {
                     $result.Headers = @{}
                 }
 
+                # Generate authentication challenge header
                 if (![string]::IsNullOrWhiteSpace($auth.Scheme.Name) -and !$result.Headers.ContainsKey('WWW-Authenticate')) {
                     $authHeader = Get-PodeAuthWwwHeaderValue -Name $auth.Scheme.Name -Realm $auth.Scheme.Realm -Challenge $result.Challenge
                     $result.Headers['WWW-Authenticate'] = $authHeader
@@ -1306,7 +1769,7 @@ function Test-PodeAuthValidation {
             }
         }
 
-        # authentication was successful
+        # Authentication succeeded, return user and headers
         return @{
             Success = $true
             User    = $result.User
@@ -1315,6 +1778,8 @@ function Test-PodeAuthValidation {
     }
     catch {
         $_ | Write-PodeErrorLog
+
+        # Handle unexpected errors and log them
         return @{
             Success    = $false
             StatusCode = 500
@@ -1323,6 +1788,8 @@ function Test-PodeAuthValidation {
     }
 }
 
+
+
 function Get-PodeAuthMiddlewareScript {
     return {
         param($opts)
@@ -2340,4 +2807,229 @@ function Get-PodeAuthRedirectUrl {
     }
 
     return $Url
+}
+
+
+<#
+.SYNOPSIS
+    Generates the WWW-Authenticate challenge header for failed authentication attempts.
+
+.DESCRIPTION
+    The `New-PodeAuthChallenge` function constructs a formatted authentication challenge
+    string to be included in HTTP responses when authentication fails.
+    It supports optional parameters such as scopes, error types, descriptions,
+    and digest authentication mechanisms.
+
+.PARAMETER Scopes
+    An array of required scopes to be included in the challenge response.
+    Scopes define the level of access required for the requested resource.
+
+.PARAMETER ErrorType
+    Specifies the type of error to include in the challenge response.
+    Accepted values are:
+      - 'invalid_request'     : The request is missing a required parameter.
+      - 'invalid_token'       : The provided token is expired, revoked, or invalid.
+      - 'insufficient_scope'  : The provided token lacks necessary privileges.
+
+.PARAMETER ErrorDescription
+    Provides a descriptive error message in the challenge response to explain
+    the reason for the authentication failure.
+
+.PARAMETER Digest
+    A switch parameter that, when specified, includes digest authentication elements
+    such as quality of protection (qop), algorithm, and a unique nonce value.
+
+.OUTPUTS
+    [string]
+    Returns a formatted challenge string to be used in the HTTP response header.
+
+.EXAMPLE
+    New-PodeAuthChallenge -Scopes @('read', 'write') -ErrorType 'invalid_token' -ErrorDescription 'Token has expired'
+
+    Returns:
+    scope="read write", error="invalid_token", error_description="Token has expired"
+
+.EXAMPLE
+    New-PodeAuthChallenge -Digest
+
+    Returns:
+    qop="auth", algorithm="MD5", nonce="generated_nonce"
+
+.EXAMPLE
+    New-PodeAuthChallenge -Scopes @('admin') -ErrorType 'insufficient_scope'
+
+    Returns:
+    scope="admin", error="insufficient_scope"
+
+.NOTES
+    This function is used to generate the `WWW-Authenticate` response header
+    when authentication attempts fail. It helps inform clients of the authentication
+    requirements and reasons for failure.
+#>
+
+function New-PodeAuthChallenge {
+    param(
+        [Parameter()]
+        [string[]]
+        $Scopes,
+
+        [Parameter()]
+        [ValidateSet('invalid_request', 'invalid_token', 'insufficient_scope')]
+        [string]
+        $ErrorType = 'invalid_request',
+
+        [Parameter()]
+        [string]
+        $ErrorDescription,
+
+        [Parameter()]
+        [string]
+        $Nonce
+    )
+
+    $items = @()
+
+    if (![string]::IsNullOrWhiteSpace($Nonce)) {
+        $items += 'qop="auth"', 'algorithm="MD5"', "nonce=`"$Nonce`""
+    }
+
+    if (($null -ne $Scopes) -and ($Scopes.Length -gt 0)) {
+        $items += "scope=`"$($Scopes -join ' ')`""
+    }
+
+    if (![string]::IsNullOrWhiteSpace($ErrorType)) {
+        $items += "error=`"$($ErrorType)`""
+    }
+
+    if (![string]::IsNullOrWhiteSpace($ErrorDescription)) {
+        $items += "error_description=`"$($ErrorDescription)`""
+    }
+
+    return ($items -join ', ')
+}
+
+<#
+.SYNOPSIS
+    Executes authentication validation without middleware intervention.
+
+.DESCRIPTION
+    The `Invoke-PodeAuthNoMiddleware` function processes an authentication request
+    by executing the provided authentication script and optional post-validation script.
+    It constructs an authentication result and handles potential redirections and errors.
+
+.PARAMETER Result
+    A [psobject] containing the initial authentication result from a previous process.
+    It may include fields such as:
+    - `Code`: The HTTP status code from a previous authentication attempt.
+    - `Headers`: Authentication headers to be included in the response.
+    - `Challenge`: An authentication challenge string to return to the client.
+
+.PARAMETER Auth
+    A [hashtable] containing the authentication scheme configuration.
+    Expected keys include:
+    - `ScriptBlock`: The main authentication script to execute.
+    - `Scheme`: An object containing authentication scheme details such as:
+        - `PostValidator.Script`: A post-authentication validation script block.
+        - `Arguments`: Arguments to be passed to authentication scripts.
+    - `Sessionless`: A boolean indicating whether to store authentication state.
+
+.OUTPUTS
+    A hashtable with the authentication result containing:
+    - `Success`         : Indicates whether authentication was successful.
+    - `User`            : The authenticated user details (if available).
+    - `Headers`         : Authentication headers for the response.
+    - `Challenge`       : The challenge for failed authentication attempts.
+    - `IsAuthenticated` : Boolean indicating authentication success.
+    - `IsAuthorised`    : Boolean indicating authorization status.
+    - `Store`           : Boolean indicating if the session should be stored.
+    - `Name`            : The authentication method name.
+    - `StatusCode`      : HTTP status code for failed authentication attempts.
+    - `Exception`       : Error message in case of server errors.
+
+.NOTES
+    This function is primarily used in authentication scenarios where middleware processing
+    is either bypassed or unnecessary, allowing direct execution of the authentication logic.
+
+    If the provided `Result` parameter contains a `Code` field with a value of 400 or greater,
+    the function processes authentication failure and returns appropriate headers and challenges.
+
+    Possible HTTP response codes:
+    - 401 Unauthorized: When authentication fails.
+    - 500 Internal Server Error: When an unexpected server error occurs.
+#>
+function Invoke-PodeAuthNoMiddleware {
+    param(
+        [psobject]
+        $Result,
+
+        [hashtable]
+        $Auth
+    )
+
+    if (($Result -is [hashtable]) -and ($Result.Code -ge 400)) {
+        $headers = $Result.Headers
+        $challenge = $Result.Challenge
+        #$code = $Result.Code
+        $_args = @($auth.Arguments)
+    }
+    else {
+        $_args = @($Result) + @($auth.Arguments)
+    }
+
+    $original = $Result
+
+    # Run the authentication script with the updated arguments
+    $Result = (Invoke-PodeScriptBlock -ScriptBlock $auth.ScriptBlock -Arguments $_args -UsingVariables $auth.UsingVariables -Return -Splat)
+
+    # Run post-authentication validation if applicable
+    if ([string]::IsNullOrEmpty($Result.Code) -and ($null -ne $auth.Scheme.PostValidator.Script)) {
+        $_args = @($original) + @($Result) + @($auth.Scheme.Arguments)
+        $Result = (Invoke-PodeScriptBlock -ScriptBlock $auth.Scheme.PostValidator.Script -Arguments $_args -UsingVariables $auth.Scheme.PostValidator.UsingVariables -Return -Splat)
+    }
+    # Handle results when invoked from a route script
+    if ( ($null -ne $Result) -and ($Result -is [hashtable])) {
+        if ($result.IsRedirected) {
+            $success = $false  # Handle authentication redirection scenarios (e.g., OAuth)
+        }elseif ($Result.Success -is [bool]) {
+            $success = $Result.Success
+        }
+        else {
+            $success = $false
+            [System.Exception]::new("The authentication Scriptblock must return an hashtable with a key named 'Success'") | Write-PodeErrorLog
+        }
+
+        $ret = @{
+            Success         = $success
+            User            = ''
+            Headers         = @{}
+            Challenge       = $challenge
+            IsAuthenticated = $success
+            IsAuthorised    = $success
+            Store           = !$auth.Sessionless
+            Name            = $Name
+        }
+        foreach ($key in $Result.Keys) {
+            $ret[$key] = $Result[$key]  # Overwrites if key exists
+        }
+
+        if ($headers -and $headers.Count -gt 0) {
+            $ret.Headers += $headers
+        }
+        if (!([string]::IsNullOrWhiteSpace($ret.Challenge)) -and !([string]::IsNullOrWhiteSpace($auth.Scheme.Name)) -and !($ret.Headers.ContainsKey('WWW-Authenticate'))) {
+            $authHeader = Get-PodeAuthWwwHeaderValue -Name $auth.Scheme.Name -Realm $auth.Scheme.Realm -Challenge $ret.Challenge
+            $ret.Headers['WWW-Authenticate'] = $authHeader
+
+        }
+        if ($ret.Headers.Count -gt 0) {
+            Add-PodeHeaderBulk -Values $ret.Headers
+        }
+        return $ret
+    }
+    else {
+        return @{
+            Success    = $false
+            StatusCode = 500
+            Exception  = 'Server error'
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Public/Authentication.ps1 b/src/Public/Authentication.ps1
index 64d6ea2df..4a9dd8af0 100644
--- a/src/Public/Authentication.ps1
+++ b/src/Public/Authentication.ps1
@@ -1146,6 +1146,10 @@ function Test-PodeAuth {
         $IgnoreSession
     )
 
+    if (! (Test-PodeAuthExists -Name $Name)) {
+        throw ($PodeLocale.authMethodDoesNotExistExceptionMessage -f $Name)
+    }
+
     # if the session already has a user/isAuth'd, then skip auth - or allow anon
     if (!$IgnoreSession -and (Test-PodeSessionsInUse) -and (Test-PodeAuthUser)) {
         return $true
@@ -1173,6 +1177,57 @@ function Test-PodeAuth {
     return $true
 }
 
+<#
+.SYNOPSIS
+    Invokes an authentication method in Pode.
+
+.DESCRIPTION
+    This function attempts to invoke an authentication method by its name,
+    ensuring that it exists and has not been merged. If the authentication
+    method does not exist or is merged, it throws an exception.
+
+.PARAMETER Name
+    The name of the authentication method to invoke. This parameter is mandatory.
+
+.OUTPUTS
+    A hashtable containing the authentication result, including success status,user information, and headers.
+
+#>
+function Invoke-PodeAuth {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory = $true)]
+        [string]
+        $Name
+    )
+
+    # Check if the authentication method exists
+    if (! (Test-PodeAuthExists -Name $Name)) {
+        # Authentication method doesn't exist:
+        throw ($PodeLocale.authMethodDoesNotExistExceptionMessage -f $Name)
+    }
+
+    # Ensure the authentication method is not merged
+    if ($PodeContext.Server.Authentications.Methods[$Name].Merged) {
+        # Authentication method {0} is merged
+        throw ($PodeLocale.authenticationMethodMergedExceptionMessage -f $Name)
+    }
+    try {
+        # Perform authentication validation
+        $WebEvent.Auth = Test-PodeAuthValidation -Name $Name -NoMiddlewareAuthentication
+        write-podehost (Get-PodeHeader -name 'WWW-Authenticate')
+    #    Add-PodeHeader -Name 'WWW-Authenticate' -Value $WebEvent.Auth.Headers['WWW-Authenticate']
+     #   write-podehost (Get-PodeHeader -name 'WWW-Authenticate')
+    }
+    catch {
+        $_ | Write-PodeErrorLog
+    }
+
+    return $WebEvent.Auth
+}
+
+
+
 <#
 .SYNOPSIS
 Adds the inbuilt Windows AD Authentication method for verifying users.
diff --git a/src/Public/Routes.ps1 b/src/Public/Routes.ps1
index 575fede7f..00cacd15d 100644
--- a/src/Public/Routes.ps1
+++ b/src/Public/Routes.ps1
@@ -1,113 +1,117 @@
 <#
 .SYNOPSIS
-Adds a Route for a specific HTTP Method(s).
+    Adds a Route for a specific HTTP Method(s).
 
 .DESCRIPTION
-Adds a Route for a specific HTTP Method(s), with path, that when called with invoke any logic and/or Middleware.
+    Adds a Route for a specific HTTP Method(s) with a given path that, when called, will invoke any specified logic and/or middleware.
 
 .PARAMETER Method
-The HTTP Method of this Route, multiple can be supplied.
+    The HTTP Method(s) of this Route. Multiple methods can be supplied.
 
 .PARAMETER Path
-The URI path for the Route.
+    The URI path for the Route.
 
 .PARAMETER Middleware
-An array of ScriptBlocks for optional Middleware.
+    An array of ScriptBlocks for optional Middleware to be executed before the main route logic.
 
 .PARAMETER ScriptBlock
-A ScriptBlock for the Route's main logic.
+    A ScriptBlock containing the main logic for the Route.
+
+.PARAMETER FilePath
+    A literal or relative path to a file containing a ScriptBlock for the Route's main logic.
+
+.PARAMETER ArgumentList
+    An array of arguments to supply to the Route's ScriptBlock.
 
 .PARAMETER EndpointName
-The EndpointName of an Endpoint(s) this Route should be bound against.
+    The EndpointName(s) this Route should be bound against.
 
 .PARAMETER ContentType
-The content type the Route should use when parsing any payloads.
+    The content type the Route should use when parsing incoming payloads.
 
 .PARAMETER TransferEncoding
-The transfer encoding the Route should use when parsing any payloads.
+    The transfer encoding the Route should use when processing incoming payloads.
+    Acceptable values: '', 'gzip', 'deflate'.
 
 .PARAMETER ErrorContentType
-The content type of any error pages that may get returned.
-
-.PARAMETER FilePath
-A literal, or relative, path to a file containing a ScriptBlock for the Route's main logic.
-
-.PARAMETER ArgumentList
-An array of arguments to supply to the Route's ScriptBlock.
+    The content type of any error pages that may be returned by this Route.
 
 .PARAMETER Authentication
-The name of an Authentication method which should be used as middleware on this Route.
+    The name of an Authentication method to be used as middleware on this Route.
+
+.PARAMETER NoMiddlewareAuthentication
+    If specified, disables automatic authentication middleware attachment when an authentication method is provided.
 
 .PARAMETER Access
-The name of an Access method which should be used as middleware on this Route.
+    The name of an Access method to be used as middleware on this Route.
 
-.PARAMETER AllowAnon
-If supplied, the Route will allow anonymous access for non-authenticated users.
+.PARAMETER Role
+    One or more optional Roles that are authorised to access this Route when using Authentication with an Access method.
 
-.PARAMETER Login
-If supplied, the Route will be flagged to Authentication as being a Route that handles user logins.
+.PARAMETER Group
+    One or more optional Groups that are authorised to access this Route when using Authentication with an Access method.
 
-.PARAMETER Logout
-If supplied, the Route will be flagged to Authentication as being a Route that handles users logging out.
+.PARAMETER Scope
+    One or more optional Scopes that are authorised to access this Route when using Authentication with an Access method.
 
-.PARAMETER PassThru
-If supplied, the route created will be returned so it can be passed through a pipe.
+.PARAMETER User
+    One or more optional Users that are authorised to access this Route when using Authentication with an Access method.
 
-.PARAMETER IfExists
-Specifies what action to take when a Route already exists. (Default: Default)
+.PARAMETER AllowAnon
+    If specified, the Route will allow anonymous access for non-authenticated users.
 
-.PARAMETER Role
-One or more optional Roles that will be authorised to access this Route, when using Authentication with an Access method.
+.PARAMETER Login
+    If specified, flags the Route to Authentication as handling user logins.
 
-.PARAMETER Group
-One or more optional Groups that will be authorised to access this Route, when using Authentication with an Access method.
+.PARAMETER Logout
+    If specified, flags the Route to Authentication as handling user logouts.
 
-.PARAMETER Scope
-One or more optional Scopes that will be authorised to access this Route, when using Authentication with an Access method.
+.PARAMETER IfExists
+    Specifies the action to take when a Route already exists.
+    Options: 'Default', 'Error', 'Overwrite', 'Skip'. (Default: Default)
 
-.PARAMETER User
-One or more optional Users that will be authorised to access this Route, when using Authentication with an Access method.
+.PARAMETER PassThru
+    If specified, the created Route will be returned, allowing it to be passed through a pipeline.
 
 .PARAMETER OAResponses
-An alternative way to associate OpenApi responses unsing New-PodeOAResponse instead of piping multiple Add-PodeOAResponse
+    Allows associating OpenAPI responses using `New-PodeOAResponse` instead of piping multiple `Add-PodeOAResponse` calls.
 
 .PARAMETER OAReference
-A reference to OpenAPI reusable pathItem component created with Add-PodeOAComponentPathItem
+    A reference to an OpenAPI reusable pathItem component created using `Add-PodeOAComponentPathItem`.
 
 .PARAMETER OADefinitionTag
-An Array of strings representing the unique tag for the API specification.
-This tag helps in distinguishing between different versions or types of API specifications within the application.
-You can use this tag to reference the specific API documentation, schema, or version that your function interacts with.
+    An array of strings representing unique tags for the API specification.
+    This helps distinguish between different versions or types of API specifications within the application.
 
 .EXAMPLE
-Add-PodeRoute -Method Get -Path '/' -ScriptBlock { /* logic */ }
+    Add-PodeRoute -Method Get -Path '/' -ScriptBlock { /* logic */ }
 
 .EXAMPLE
-Add-PodeRoute -Method Post -Path '/users/:userId/message' -Middleware (Get-PodeCsrfMiddleware) -ScriptBlock { /* logic */ }
+    Add-PodeRoute -Method Post -Path '/users/:userId/message' -Middleware (Get-PodeCsrfMiddleware) -ScriptBlock { /* logic */ }
 
 .EXAMPLE
-Add-PodeRoute -Method Post -Path '/user' -ContentType 'application/json' -ScriptBlock { /* logic */ }
+    Add-PodeRoute -Method Post -Path '/user' -ContentType 'application/json' -ScriptBlock { /* logic */ }
 
 .EXAMPLE
-Add-PodeRoute -Method Post -Path '/user' -ContentType 'application/json' -TransferEncoding gzip -ScriptBlock { /* logic */ }
+    Add-PodeRoute -Method Post -Path '/user' -ContentType 'application/json' -TransferEncoding gzip -ScriptBlock { /* logic */ }
 
 .EXAMPLE
-Add-PodeRoute -Method Get -Path '/api/cpu' -ErrorContentType 'application/json' -ScriptBlock { /* logic */ }
+    Add-PodeRoute -Method Get -Path '/api/cpu' -ErrorContentType 'application/json' -ScriptBlock { /* logic */ }
 
 .EXAMPLE
-Add-PodeRoute -Method Get -Path '/' -ScriptBlock { /* logic */ } -ArgumentList 'arg1', 'arg2'
+    Add-PodeRoute -Method Get -Path '/' -ScriptBlock { /* logic */ } -ArgumentList 'arg1', 'arg2'
 
 .EXAMPLE
-Add-PodeRoute -Method Get -Path '/' -Role 'Developer', 'QA' -ScriptBlock { /* logic */ }
+    Add-PodeRoute -Method Get -Path '/' -Role 'Developer', 'QA' -ScriptBlock { /* logic */ }
 
 .EXAMPLE
-$Responses = New-PodeOAResponse -StatusCode 400 -Description 'Invalid username supplied' |
-            New-PodeOAResponse -StatusCode 404 -Description 'User not found' |
-            New-PodeOAResponse -StatusCode 405 -Description 'Invalid Input'
+    $Responses = New-PodeOAResponse -StatusCode 400 -Description 'Invalid username supplied' |
+                 New-PodeOAResponse -StatusCode 404 -Description 'User not found' |
+                 New-PodeOAResponse -StatusCode 405 -Description 'Invalid Input'
 
-Add-PodeRoute -PassThru -Method Put -Path '/user/:username' -OAResponses $Responses -ScriptBlock {
-            #code is going here
-        }
+    Add-PodeRoute -PassThru -Method Put -Path '/user/:username' -OAResponses $Responses -ScriptBlock {
+        # Logic here
+    }
 #>
 function Add-PodeRoute {
     [CmdletBinding(DefaultParameterSetName = 'Script')]
@@ -165,6 +169,9 @@ function Add-PodeRoute {
         [string]
         $Access,
 
+        [switch]
+        $NoMiddlewareAuthentication,
+
         [Parameter()]
         [ValidateSet('Default', 'Error', 'Overwrite', 'Skip')]
         [string]
@@ -335,6 +342,7 @@ function Add-PodeRoute {
         }
 
         $Middleware = (@(Get-PodeAccessMiddlewareScript | New-PodeMiddleware -ArgumentList $options) + $Middleware)
+
     }
 
     # if an auth name was supplied, setup the auth as the first middleware
@@ -343,15 +351,19 @@ function Add-PodeRoute {
             # Authentication method does not exist
             throw ($PodeLocale.authenticationMethodDoesNotExistExceptionMessage -f $Authentication)
         }
+        if ( ! $NoMiddlewareAuthentication) {
+            $options = @{
+                Name   = $Authentication
+                Login  = $Login
+                Logout = $Logout
+                Anon   = $AllowAnon
+            }
 
-        $options = @{
-            Name   = $Authentication
-            Login  = $Login
-            Logout = $Logout
-            Anon   = $AllowAnon
+            $Middleware = (@(Get-PodeAuthMiddlewareScript | New-PodeMiddleware -ArgumentList $options) + $Middleware)
         }
-
-        $Middleware = (@(Get-PodeAuthMiddlewareScript | New-PodeMiddleware -ArgumentList $options) + $Middleware)
+    }
+    elseif ($NoMiddlewareAuthentication) {
+        throw $PodeLocale.parameterNoMiddlewareAuthRequiresAuthenticationExceptionMessage
     }
 
     # custom access
@@ -410,7 +422,7 @@ function Add-PodeRoute {
                     Logic            = $ScriptBlock
                     UsingVariables   = $usingVars
                     Middleware       = $Middleware
-                    Authentication   = $Authentication
+                    Authentication   = $(if (!$NoMiddlewareAuthentication) { $Authentication } else {})
                     Access           = $Access
                     AccessMeta       = @{
                         Role   = $Role
diff --git a/tests/integration/Authentication.Tests.ps1 b/tests/integration/Authentication.Tests.ps1
index 67f4147c3..9a4fad6cd 100644
--- a/tests/integration/Authentication.Tests.ps1
+++ b/tests/integration/Authentication.Tests.ps1
@@ -147,7 +147,7 @@ Describe 'Authentication Requests' {
     }
 
     It 'bearer - returns 400 for no token' {
-        { Invoke-RestMethod -Uri "$($Endpoint)/auth/bearer" -Method Get -Headers @{ Authorization = 'Bearer' } -ErrorAction Stop } | Should -Throw -ExpectedMessage '*400*'
+        { Invoke-RestMethod -Uri "$($Endpoint)/auth/bearer" -Method Get -Headers @{ Authorization = 'Bearer' } -ErrorAction Stop } | Should -Throw -ExpectedMessage '*401*'
     }
 
 
diff --git a/tests/unit/Authentication.Tests.ps1 b/tests/unit/Authentication.Tests.ps1
index 38190f523..daa7460f3 100644
--- a/tests/unit/Authentication.Tests.ps1
+++ b/tests/unit/Authentication.Tests.ps1
@@ -191,3 +191,48 @@ Describe 'Expand-PodeAuthMerge Tests' {
     }
 
 }
+# Pester test for Invoke-PodeAuth function
+
+Describe 'Invoke-PodeAuth Tests' {
+    BeforeEach {
+        # Mock the Pode context and localization messages
+        $PodeContext = @{
+            Server = @{
+                Authentications = @{
+                    Methods = @{
+                        'ValidAuth' = @{ Merged = $false }
+                        'MergedAuth' = @{ Merged = $true }
+                    }
+                }
+            }
+        }
+        $WebEvent=@{}
+        $PodeLocale = @{
+            authMethodDoesNotExistExceptionMessage = "Authentication method {0} does not exist"
+            authenticationMethodMergedExceptionMessage = "Authentication method {0} is merged"
+        }
+    }
+
+    It 'Should successfully invoke a valid authentication method' {
+        Mock Test-PodeAuthExists { $true } -ParameterFilter { $Name -eq 'ValidAuth' }
+        Mock Test-PodeAuthValidation { @{ Success = $true; User = 'TestUser'; Headers = @{} } }
+        Mock Add-PodeHeader {}
+
+        $result = Invoke-PodeAuth -Name 'ValidAuth'
+
+        $result | Should -Not -Be $null
+        $result.Success | Should -Be $true
+        $result.User | Should -Be 'TestUser'
+    }
+
+    It 'Should throw an error when authentication method does not exist' {
+        { Invoke-PodeAuth -Name 'InvalidAuth' } | Should -Throw ($PodeLocale.authMethodDoesNotExistExceptionMessage -f 'InvalidAuth' )
+    }
+
+    It 'Should throw an error when authentication method is merged' {
+
+        { Invoke-PodeAuth -Name 'MergedAuth' } | Should -Throw ($PodeLocale.authenticationMethodMergedExceptionMessage -f 'MergedAuth' )
+    }
+
+
+}