web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Power Apps / Upload File to SharePo...
Power Apps
Answered

Upload File to SharePoint Document Library Code Apps Groups or EntraID Connector

(1) ShareShare
ReportReport
Posted on by 19
I am able to upload a file directly to SharePoint from a canvas app using either the Office365Groups connector.

This works fine in Canvas app. But the exact same request fails in CodeApps.
 
Office365Groups.HttpRequest(
            "https://graph.microsoft.com/v1.0/sites/" & nfDocumentSiteId & "/drives/" & nfDocumentDriveId & "/root:/" & Last(
                Split(
                    ctxDocumentPath,
                    "WISP Documents/"
                )
            ).Value & Concatenate(
                GUID(),
                ".jpeg"
            ) & ":/content",
            "PUT",
            Self.Media
        )
 
the above works perfectly and this is the request



However I cannot replicate this in PowerApps Code apps using the same connector (same id) my files are corrupted.

I have tired every permutation of content/content-type in body, in header.
 
Anyone who can get this working that would be great, also although the large file upload option works in dev, its blocked in production as the published power app cannot acess teh sharepoint endpoint directly.
I have the same question (0)
  • Suggested answer
    11manish Profile Picture
    3,825 Super User 2026 Season 2 on at
    Since the upload succeeds but the resulting file is corrupted, the most likely root cause is that the Code App is sending encoded content rather than the raw
     
    binary stream required by the Microsoft Graph /content endpoint.
     
    The first thing I would verify is the actual payload being sent. If the Code App cannot reliably transmit raw binary data in production, the recommended
     
    architecture is:
     
    Code App  ->  Power Automate (or Azure Function) -> Microsoft Graph / SharePoint
     
    This approach avoids binary serialization issues, works consistently across environments, and is currently the most supportable pattern for file uploads from Code
     
    Apps.
  • Suggested answer
    Valantis Profile Picture
    6,969 Super User 2026 Season 2 on at
     
    The corruption happens because Code Apps serialize binary content differently than Canvas Apps when passing it through connectors.
    The Graph /content PUT endpoint expects raw binary and Code Apps can't reliably deliver that directly.

    The confirmed working pattern: expose the file from the Code App as base64, pass it to a Power Automate flow via the Power Apps connector, decode it in the flow using dataUriToBinary() or base64ToBinary(), and upload to SharePoint using the SharePoint connector Create file action or directly via Graph.

    This also solves your production issue where the published app can't reach the SharePoint endpoint directly the flow runs under its own connection credentials and doesn't require direct browser access to SharePoint.
     

     

    Best regards,

    Valantis

     

    ✅ If this helped solve your issue, please Accept as Solution so others can find it quickly.

    ❤️ If it didn’t fully solve it but was still useful, please click “Yes” on “Was this reply helpful?” or leave a Like :).

    🏷️ For follow-ups  @Valantis.

    📝 https://valantisond365.com/

    💼 LinkedIn

    ▶️ YouTube

  • Verified answer
    JD-18061111-0 Profile Picture
    19 on at
    There is a workaround here, confirmed working.

    https://www.reddit.com/r/PowerApps/s/77QhBqTn1Z

    The auto generated services don't incorporate the full capabilities of the API you can bypass this by directly calling PluginBridge 
     
      // ── Why we bypass the SDK for file uploads ──────────────────────────
        // The Power Apps Code Apps SDK (DocumentsService.create / client.executeAsync)
        // cannot upload files to a SharePoint document library for two reasons:
        //
        //   1. createRecordAsync() issues a POST to the /items endpoint, but SharePoint
        //      document libraries require SPFileCollection.Add() (the /files endpoint).
        //
        //   2. executeAsync() always passes the body through JSON.stringify(), which
        //      corrupts binary content and wraps text in extra double-quotes.
        //
        // To work around this, we call the Power Apps runtime plugins directly:
        //   - AppPowerAppsClientPlugin  → get connection config (runtime URL, dataset, etc.)
        //   - AppIdentityServicePlugin  → get a connector auth token
        //   - AppHttpClientPlugin       → send the raw HTTP request with a Blob body
        //
        // This is the same HTTP pipeline the SDK uses internally (see runtimeDataClient.js),
        // just without the JSON.stringify wrapper on the request body.
        // ─────────────────────────────────────────────────────────────────────
        // Step 1: Get connection configs to find the SharePoint connector's runtime URL,
        // connection name, dataset (site URL), and API ID.
        const connConfigs = await executePluginAsync<Record<string, any>>(
          'AppPowerAppsClientPlugin',
          'loadAppConnectionsAsync_v2',
          [],
        );
        // Step 2: Find the SharePoint connection reference from the returned configs.
        // Keys are lowercased by the SDK. We match on the apiId containing 'shared_sharepointonline'.
        const spKey = Object.keys(connConfigs).find(
          (k) => connConfigs[k]?.apiId?.indexOf('shared_sharepointonline') !== -1,
        );
        if (!spKey) throw new Error('SharePoint connection reference not found.');
        const spConn = connConfigs[spKey];
        const runtimeUrl: string = spConn.runtimeUrl;
        const connectionName: string = spConn.connectionName;
        const datasetName: string = spConn.datasetName;   // The SharePoint site URL
        const apiId: string = spConn.apiId;
        // Step 3: Build the CreateFile URL.
        // SharePoint datasets must be double-encoded (once here, once by the HTTP pipeline).
        // folderPath must point to the library's server-relative root folder name.
        // NOTE: The root folder name may differ by locale (e.g. "Shared Documents" in English,
        //       "Freigegebene Dokumente" in German). Check your library's actual folder name.
        const encodedDataset = encodeURIComponent(encodeURIComponent(datasetName));
        const folderPath = encodeURIComponent('/Shared Documents');
        const fileName = encodeURIComponent(file.name);
        const uploadUrl = `${runtimeUrl}/${connectionName}/datasets/${encodedDataset}/files?folderPath=${folderPath}&name=${fileName}`;
        // Step 4: Get an auth token scoped to the SharePoint connector.
        // The 'paauth' scheme is used by Power Apps connector proxy (not a standard Bearer token).
        const token = await executePluginAsync<string>(
          'AppIdentityServicePlugin',
          'getAppAccessTokenAsync',
          [apiId],
        );
        // Step 5: Read the file as a raw binary Blob.
        // Using Blob instead of a string preserves binary content for all file types.
        const fileBuffer = await file.arrayBuffer();
        const fileBlob = new Blob([fileBuffer], { type: file.type || 'application/octet-stream' });
        // Step 6: Call the HTTP plugin directly, sending the Blob as the request body.
        // This avoids the SDK's JSON.stringify which would corrupt the file content.
        await executePluginAsync<any>(
          'AppHttpClientPlugin',
          'sendHttpAsync',
          [
            {
              url: uploadUrl,
              method: 'POST',
              requestSource: 'PublishedApp',
              allowSessionStorage: true,
              returnDirectResponse: true,
              headers: {
                Accept: 'application/json',
                'x-ms-protocol-semantics': 'cdp',       // Required: tells proxy this is a connector call
                ServiceNamespace: 'documents',            // Must match the data source name in power.config.json
                Authorization: `paauth ${token}`,         // Power Apps connector auth (not Bearer)
                'Content-Type': file.type || 'application/octet-stream',
              },
            },
            fileBlob,       // Raw binary body — NOT JSON-serialized
            'arraybuffer',  // Response type
          ],
        );

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Season of Sharing Community Challenge Winners!

Congratulations to our community stars!

Kudos to our 2025 Community Spotlight Honorees

Expanding mentorship, skilling, and AI innovation

Congratulations to the July Top 10 Community Leaders!

These are the community rock stars!

Leaderboard > Power Apps

#1
WarrenBelz Profile Picture

WarrenBelz 401 Most Valuable Professional

#2
11manish Profile Picture

11manish 157 Super User 2026 Season 2

#3
MS.Ragavendar Profile Picture

MS.Ragavendar 70 Super User 2026 Season 2

Last 30 days Overall leaderboard