---
title: SharePoint
description: SharePoint document libraries via Microsoft Graph. Resolves siteUrl and library names; delegates to the OneDrive adapter for the file operations.
---

## Installation

`@azure/identity` and `@microsoft/microsoft-graph-client` are optional peer dependencies of `files-sdk` - install alongside the SDK so the adapter's imports resolve at runtime.

```package-install
files-sdk @azure/identity @microsoft/microsoft-graph-client
```

## Usage

SharePoint document libraries via Microsoft Graph. Wraps the `onedrive` adapter and adds SharePoint-shaped resolution - `siteUrl` parsing, named `documentLibrary` lookup, and `SHAREPOINT_*` env-var fallbacks. Resolution is lazy: the first method call triggers Graph traffic to convert names into drive IDs, then subsequent calls reuse the resolved drive.

Explicit options beat the env targets. `SHAREPOINT_SITE_ID` and `SHAREPOINT_SITE_URL` are read only when you pass none of `siteId`, `siteUrl`, `hostname`, or `sitePath`, and `SHAREPOINT_DRIVE_ID` only when you also pass no `documentLibrary`. `SHAREPOINT_HOSTNAME` still pairs with an explicit `sitePath`, and an env site still pairs with an explicit `documentLibrary`.

```ts lineNumbers
import { Files } from "files-sdk";
import { sharepoint } from "files-sdk/sharepoint";

const files = new Files({
  adapter: sharepoint({
    siteUrl: "https://contoso.sharepoint.com/sites/marketing",
    documentLibrary: "Reports", // optional, omit for default library
    clientCredentials: {
      tenantId: process.env.SHAREPOINT_TENANT_ID!,
      clientId: process.env.SHAREPOINT_CLIENT_ID!,
      clientSecret: process.env.SHAREPOINT_CLIENT_SECRET!,
    },
    rootFolderPath: "Uploads",
  }),
});
```

## Options

<AutoTypeTable
  path="../../packages/files-sdk/src/sharepoint/index.ts"
  name="SharePointAdapterOptions"
/>

## Limitations

The adapter delegates to `onedrive` after resolution, so the OneDrive per-method caveats in the table below apply. SharePoint-specific: `siteUrl` parsing errors and missing `documentLibrary` names throw `Invalid` on the first method call - resolution is lazy, so construction never fails for these, and the resolved drive is cached for the adapter's lifetime after 1-2 extra Graph round-trips on first use. `delete()` moves items to the recycle bin (soft delete).

## Compatibility

| Method | Status | Notes |
| --- | :-: | --- |
| `upload` | ⚠️ | Delegates to `onedrive` after site/library resolution: single-PUT simple upload up to OneDrive's 250 MB limit; larger bodies (or any `multipart` upload) automatically switch to a chunked Graph upload session. Stream bodies are buffered into memory up-front. User `metadata` and `cacheControl` throw - Graph drive items have no native arbitrary-metadata field; use `raw` to set Open Extensions if you need them. |
| `download` | ✅ |  |
| `delete` | ✅ | A folder key is a no-op, like a missing key. `""`, `"/"`, and keys with a trailing slash throw `Invalid` (they name the root or a folder), here and on every other method. |
| `list` | ⚠️ | Delegates to `onedrive`: lists one folder, no recursion - the folder the `prefix` points into (the part up to its last `/`, under `rootFolderPath` - `photos/` lists `photos`), with the rest of the prefix matched client-side against child names within the page. Keys come back in full (`photos/cover.jpg`). Without a delimiter, subfolders are skipped; with `delimiter: '/'` they come back as `prefixes` (`photos/2024/`) that you can pass back as the next `prefix`. A prefix into a missing folder lists nothing. Pagination uses Graph's `@odata.nextLink` as the opaque cursor. |
| `search` | ⚠️ | Built on `listAll` — inherits this adapter's `list` behavior above. Client-side key match (glob, regex, substring, exact). |
| `head` | ⚠️ | A key that resolves to a folder throws `NotFound` - keys name files. |
| `exists` | ⚠️ | Returns `false` for a key that resolves to a folder. |
| `copy` | ⚠️ | Delegates to `onedrive`: async copy on Graph (`POST /items/{id}/copy` returns 202 + monitor URL). The adapter polls the monitor every 500 ms until status is `completed`/`failed`, capped by `copyTimeoutMs` (default 60_000). On timeout the call throws a `permanent` `Provider` error ("did not finish within…"), so a retry doesn't start a second copy; the copy may still finish server-side, so check the destination, and tune `copyTimeoutMs` for large files. An existing destination file is overwritten (`conflictBehavior=replace`, falling back to delete and copy); a folder at the destination, or the same file under different casing, is `Conflict`, and a folder as the source is `NotFound`. A destination folder that doesn't exist yet is created first, as `upload` does. `move` behaves the same. |
| `url` | ⚠️ | Delegates to `onedrive`: throws by default - Graph has no signed URL primitive. With `publicByDefault: true` at construction, `upload()` calls `createLink` (anonymous-view scope) and `url()` returns the share link's `webUrl`. The link is permanent: `url(key)` returns the permanent link; an explicit `expiresIn` throws `Unsupported`. `responseContentDisposition` always throws. Anonymous links are blocked on tenants where admins disable them. |
| `signedUploadUrl` | ⚠️ | Delegates to `onedrive`: initiates a Graph upload session via `POST /createUploadSession` and returns the session URL as a one-shot PUT (the session URL is pre-authenticated by Graph itself). It's an upload session, not a plain presigned PUT: the client must send `Content-Range: bytes 0-{n-1}/{n}` with the body, and a single request must stay under 60 MiB - larger files need several PUTs of 320 KiB-multiple fragments against the same URL. `maxSize` and `minSize` throw because Graph does not enforce a server-side `content-length-range` policy on upload sessions, and `contentType` throws because a session doesn't bind a Content-Type (Graph infers the type from the file name); enforce these at your application gateway instead. |
