Forum Discussion
Trouble scraping SharePoint Version History
- 6 months ago
Hi ,To fix your refresh issues and answer your question on "Why the List API," here is the technical breakdown and the code solution.
1. The "Dynamic Data Source" Fix
You are getting the refresh error because Power BI Service cannot authenticate a data source where the URL is built inside the query (e.g., combining a base URL with a file ID). The Service needs to know the Root URL statically before the query runs.
To fix this, you must use the
RelativePath andQuery options insideWeb.Contents. This allows you to keep the main URL static (satisfying the gateway/refresh) while making the rest dynamic.The Incorrect Way (Causes Dynamic Error):
Web.Contents("https://site.com/api/files/" & FileID)The Correct Way (Refreshable):
Web.Contents("https://site.com", [RelativePath="api/files/" & FileID])2. Why List API vs. Folder API?
You asked why the List API is more accurate.
-
Folder API (
GetFolderBy...): This is a file-system abstraction. When you ask for version history here, SharePoint often relies on a cached view of the file metadata to save performance. If that cache is stale (which happens often with deep metadata like versions), you get gaps until you "nudge" the file. -
List API (
.../items): This queries the actual underlying SharePoint database table (All Documents are just items in a List). It bypasses the "folder view" abstraction and hits the transactional data directly. This is whyMurtaza_Ghafoor recommended it.3. The Solution Code
Here is how to combine the List API (for accuracy) with RelativePath (for refresh stability). This query gets all files and their versions in one go without the dynamic error.
let // 1. Define your Static Base URL (The part you authenticate against) BaseUrl = "https://[YOUR_TENANT].sharepoint.com/sites/Tracking", // 2. Use RelativePath to hit the List API. // We use the List Endpoint because it is the database source of truth. Source = Json.Document(Web.Contents(BaseUrl, [ RelativePath = "_api/web/lists/getbytitle('Documents')/items", Query = [ // We expand File and Versions immediately to avoid N+1 query loops #"$expand" = "File,File/Versions,File/Versions/CreatedBy", // Select only what you need to keep it fast #"$select" = "File/Name,File/ServerRelativeUrl" ], Headers = [Accept="application/json;odata=verbose"] ])), // 3. Standard JSON navigation from here d = Source[d], results = d[results], #"Converted to Table" = Table.FromList(results, Splitter.SplitByNothing(), null, null, ExtraValues.Error), #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"File"}, {"File"}), // 4. Expand the Versions nested inside the File record #"Expanded File" = Table.ExpandRecordColumn(#"Expanded Column1", "File", {"Name", "ServerRelativeUrl", "Versions"}, {"FileName", "FileUrl", "Versions"}), #"Expanded Versions" = Table.ExpandRecordColumn(#"Expanded File", "Versions", {"results"}, {"VersionResults"}), #"Expanded VersionResults" = Table.ExpandListColumn(#"Expanded Versions", "VersionResults"), // 5. Expand Version Details #"Expanded Version Details" = Table.ExpandRecordColumn(#"Expanded VersionResults", "VersionResults", {"VersionLabel", "Created", "CreatedBy"}, {"VersionLabel", "VersionCreated", "CreatedByRecord"}), #"Expanded CreatedBy" = Table.ExpandRecordColumn(#"Expanded Version Details", "CreatedByRecord", {"Title", "Email"}, {"User", "UserEmail"}) in #"Expanded CreatedBy"Key changes for your setup:
-
Change
BaseUrl to your site root. -
If your library is not named "Documents", change
getbytitle('Documents') to your library name. -
This avoids the "Dynamic Data Source" error because
BaseUrl is a static text string.Check out my blog for more on optimizing these calls if the list is very large!
This response was assisted by AI for translation and formatting purposes.
-
-
-
-
-
This is a SharePoint behavior rather than an issue with your query.
Sometimes version history isn’t fully exposed through the API until a file is opened or updated, which is why opening the Excel file makes the missing versions appear.
This is common behaviour.
Try this approach:
Use the List Items API (_api/web/lists/.../items?$expand=File/Versions) instead of querying the folder files endpoint, or ensure files are periodically accessed/updated to force SharePoint to refresh the version metadata.
Thank you, any information you can point me to so I understand why this is common behaviour? We do have the files automatically opened and saved on a regular basis (to ensure background queries within the files are refreshed). I can see the version history of this when I view it in sharepoint or within the file, but the query still misses some of them.
I can give your suggestion a try, but am curious if I'll end up with a similar issue as with v-achippa 's suggestion. I need to put this report on a refresh schedule and that's where I had issues with that solution. Any thoughts on if your suggestion will still allow a scheduled refresh? I believe as long as I can point it to one location it should (vs. querying the files have many locations to reference). And my other question is why is pulling the data from a list more accurate than pulling it from a folder?