In Power Query, Expression.Error: Access to the resource is forbidden (often corresponding to an HTTP 403 Forbidden status) means the destination web server or API rejected your connection request. This is usually caused by missing, malformed, or unauthorized HTTP request headers, expired API tokens, or incorrect authentication choices in Power Query’s Data Source Settings.
Quick Answer
Check your
Web.Contentscall in the Advanced Editor. Ensure required authentication tokens, API keys, andAcceptheaders are nested inside theHeadersrecord argument. If headers are correct, navigate to Data Source Settings, select the root URL, click Edit Permissions, and change the authentication mode from Anonymous to match your API requirements.
Understanding the HTTP 403 Forbidden Error in Power Query
Unlike an HTTP 401 Unauthorized error (which indicates that credentials were not provided or are completely invalid), an HTTP 403 Forbidden error means the server recognized your identity or your request, but actively refuses to grant access.
In Power Query ETL, this almost always points to one of three issues:
- Missing Custom Headers: Many REST APIs require explicit headers such as
User-Agent,Authorization,Accept: application/json, or custom developer tokens (e.g.,x-api-key). Without them, endpoints actively reject automated scrapers or scripts. - Hardcoded Credentials in the URL String: Appending secrets directly into the URL string can trigger security rejections or run into Power Query firewall boundaries.
- Data Source Settings Mismatch: Power Query caches credentials at the root domain level. If the root domain was registered as “Anonymous” during an initial test, subsequent authenticated calls will inherit that configuration and be blocked.
How to Properly Structure Web.Contents Headers
When connecting to an API via M-code, HTTP headers must be passed as an options record to the second parameter of Web.Contents.
Common Broken Pattern:
// Missing necessary headers or using incorrect syntax
Source = Json.Document(Web.Contents("<https://api.service.com/v1/data?token=secret123>"))
Many modern APIs will flag requests that lack a standard User-Agent or fail when authentication credentials are provided via query strings rather than the request header.
Correct Pattern with Headers:
let
ApiUrl = "<https://api.service.com/v1/data>",
Source = Json.Document(
Web.Contents(
ApiUrl,
[
Headers = [
#"Authorization" = "Bearer YOUR_ACTUAL_TOKEN_HERE",
#"Accept" = "application/json",
#"User-Agent" = "PowerQueryClient/1.0"
]
]
)
)
in
Source
Important: Header names are case-sensitive strings in some external web services. If an API documentation specifies
x-api-key, use#"x-api-key"in your record definition.
Resolving Cached Permission Collisions
Power Query stores authorization rules independently of the M-code script. If the query originally connected without credentials, Excel retains that rule even if you update your M-code.
How to Clear Cached Permissions:
- In Excel, go to the Data tab.
- Click Get Data > Data Source Settings.
- Select Global Permissions.
- Locate the base URL for your API endpoint.
- Click Clear Permissions (or Delete).
- Return to Power Query and click Refresh Preview.
- When prompted, re-enter your API key, Web API credentials, or select Anonymous if you manage authorization entirely via headers inside
Web.Contents.
For persistent credential configuration issues across enterprise sources, see Managing Data Source Settings: How to clear and reset Global Permissions.
Privacy Levels and Web Combine Blocks
If your query combines web data with a local Excel file, SQL database, or secondary API, Power Query’s internal firewall may block the request to prevent cross-source data leaks, returning a 403 or a Formula.Firewall error.
To isolate whether the issue is purely header-related or firewall-driven:
- Open a completely blank Excel workbook.
- Open Power Query and paste only the single
Web.ContentsAPI call into a new blank query. - If it succeeds in isolation, the failure in your main workbook is caused by privacy levels rather than an invalid API key. See Formula.Firewall: Data privacy settings prevent combining sources to resolve cross-source evaluation blocks.