
API integration for Microsoft 365
We build your Microsoft 365 connector
We go through Microsoft Graph to read and write SharePoint and OneDrive, with a defensible Sites.Selected perimeter. Calendar and mail are a different page.
- Senior product team
- Graph file connectors in production
- from scoping to monitoring
What does the Microsoft 365 API provide and why connect OneDrive or SharePoint to your software?
Microsoft 365 is the standard work environment for most large French companies: files in OneDrive and SharePoint, calendar in Outlook, messages in Teams. Integration via Microsoft Graph lets your application automatically file documents in the client's SharePoint library, read shared files without the user downloading them manually, and keep the DMS up to date without a parallel tool. You integrate it when client teams live in the Microsoft ecosystem and your software needs to slot in without creating an additional storage folder that no one will keep up to date.
What our clients build on Graph files
Business deposit into the client library
Quotes, invoices, reports land in SharePoint. An internal sharing link rather than an attachment that leaves the tenant.
DMS whose source of truth stays SharePoint
The product indexes via delta, does not host the binary, and reacts to a drop in a "to process" folder.
Supplier portal bounded to one site
Sites.Selected: this library, not Files.Read.All. Often the only version a CIO will sign.
Contract generated, uploaded, tracked
Resumable session beyond 10 MiB, Graph invite to internal signers, versions via cTag. CSOM/REST to Graph if a legacy connector is still around.
What this changes in your Microsoft DMS
The engineering serves a measurable result: the file in the right place, a signable perimeter, fewer lost attachments.
No more parallel DMS
The business software writes where the company already stores files. Copy on the server folders leave the process.
A CIO can sign the connector
Access scoped to a site or library, assigned role, audit log. It is not all-files access in disguise.
A deposit triggers the workflow
A quote arriving in the library moves the case forward. No more scan agent on a network share.
Large files get through
Large uploads are chunked and resumed. You do not learn in production that a 50 MB contract breaks the flow.
How we deliver your Microsoft 365 connector
Scoping
Which sites, which libraries, delegated or application, Selected or not. No concurrent *.All permission. The perimeter is written before the HTTP client.
Development
deltaLink per drive, 42,300 min subscriptions, upload session, limiter in resource units, Retry-After that pauses the whole tenant.
Acceptance
410 on delta, PUT with Authorization, sensitivity-labelled file in app-only, consent without POST /permissions. Replay off-peak.
Monitoring
Alert on 429 (they count toward the quota), driveItem subscription, units consumed. Log: which app, which site, which Selected role.
What Graph allows for SharePoint and OneDrive
- Sites, drives, driveItems
- GET /sites, /sites/{id}/drives, addressing by id or by path (:). A site has several libraries. /me/drive, /groups, /shares.
- Delta and notifications
- GET .../root/delta, persist @odata.deltaLink, token=latest available. driveItem subscriptions up to 42,300 minutes. Prefer includesecuritywebhooks for permissions (work only).
- Upload and download
- PUT content for a small file. createUploadSession beyond 10 MiB: fragments < 60 MiB, multiples of 320 KiB, strictly sequential. downloadUrl preauthenticated, 1 hour, not cacheable.
- Selected permissions
- Sites.Selected, Lists/ListItems/Files.SelectedOperations.Selected. Entra consent plus POST /permissions (read, write, owner, fullcontrol). All three conditions are required.
Graph files vocabulary
- Sites.Selected
- A scope that grants nothing until a role is assigned on the site (or list, item, file). Three conditions: consented scope, assigned permission, token that still carries the scope.
- @odata.deltaLink
- Cursor of the last page of a delta. A page never has both nextLink and deltaLink. token=latest: sync from now, with no initial crawl.
- createUploadSession
- Resume beyond 10 MiB. Fragments multiple of 327,680 bytes, sequential, < 60 MiB. The uploadUrl is preauthenticated: an Authorization header produces 401.
- Resource units
- 1: read, delta with token, download. 2: listing, delta without token, write. 5: permissions, including $expand=permissions. This is the throttling counter, not the request count.
- cTag / eTag
- cTag: content changed. eTag: metadata. Compare cTag before re-downloading a binary. downloadUrl lives one hour and is not invalidated immediately if a permission is removed.
- Retry-After
- SharePoint's only throttling signal. Ignoring it deepens the hole because 429s count. Pause every request for the tenant during the window, not only the failing call.
The real constraints of Graph files
Throttling is not per site
User, tenant, app+tenant, SharePoint workload layers. Hammering "another" site on the same tenant draws from the same bucket. Application limits follow licence count, over 24 h and over 1 min.
Selected without assignment is zero access
Admin consent is not the business authorisation. A concurrent *.All permission in Entra ID destroys the perimeter. Assigning Selected on a file breaks inheritance.
Upload has two mental hosts
Bearer on createUploadSession only. Out-of-order fragments: error. Sensitivity-labelled file: no replace in app-only, you need delegated.
CSOM and REST cost more
More units than Graph for the same operation, plus undocumented internal limits. Graph is the prescribed path. An undecorated User-Agent means a slower queue. Mass scans: night and weekend of the tenant time zone.
SharePoint API or Google Drive API?
Two corporate disks. The right one follows the tenant already paid for, not the SDK.
| Criterion | Microsoft 365This page | Google DriveDrive API v3 |
|---|---|---|
| Typical estate | SharePoint / OneDrive on the tenant | Workspace, My Drive and shared drives |
| Fine perimeter | Sites.Selected + POST /permissions | drive.file + Picker, or restricted scopes |
| Increment | delta query, deltaLink, token=latest | changes.list, startPageToken |
| Notification | Graph, up to ~30 days | Push with no body, no HMAC |
| Quota | SharePoint units, Retry-After only | Drive units (5 / 100 / 200 / 50) |
| Large files | Session, multiples of 320 KiB | Resumable from 5 MB, URI 7 days |
| The right case | The company is already on Microsoft 365 | The company is already on Workspace |
Outlook calendar and mail are not in this comparison. Box and Dropbox come up when the DMS is not the Microsoft or Google tenant.
What we measure on a SharePoint integration
The other file APIs
If the tenant is not Microsoft 365, these options belong in the scoping conversation.
Microsoft 365We build your Microsoft 365 connectorThis page
Google DriveDrive and Docs/Sheets export, drive.file plus Picker.
BoxEnterprise DMS, signed webhooks, App Users, admin_logs.
DropboxFile sharing, list_folder cursor, App Folder.We combine Microsoft 365 with
The stack around SharePoint and OneDrive on our projects.
SharePoint integration: your questions
Entra ID app, Graph v1.0, Sites.Selected perimeter (consent then POST /permissions), decorated User-Agent, delta per drive rather than a children crawl, subscriptions on the driveItem, session upload beyond 10 MiB. Acknowledge the webhook with 202, work in a queue, honour Retry-After across the tenant. The hard part is not the first GET /sites, it is resource units and the absence of a concurrent *.All permission.
No. Entra consent grants no file. You then POST /sites/{id}/permissions (or list / item / file) with a read, write, owner or fullcontrol role, and a token that still carries the scope. All three conditions are required. A Files.Read.All added "as well" in Entra ID overrides the perimeter. That is the argument a CIO wants to hear, and the number-one cause of a POC that "worked" too well. This is a scoping call, written down before the first request, not an acceptance surprise.
A first useful flow, typically depositing a PDF in a Selected library with an internal link, ships in two to three weeks. A DMS connector (delta, webhooks, upload session, audit) is closer to six to eight weeks. A CSOM/REST cutover is priced separately (traffic decoration, unit accounting, off-peak window). We scope sites and roles before coding. This is a scoping call, written down before the first request, not an acceptance surprise.
Follow the tenant. Microsoft 365: Graph files, Sites.Selected. Workspace: Drive v3, often drive.file + Picker to avoid the restricted-scope security assessment. Both have an increment (delta vs changes) and a push that needs a re-read. Box and Dropbox come up if the DMS is already there, outside the two office suites. This is a scoping call, written down before the first request, not an acceptance surprise.
One deltaLink per drive, token=latest if you start from now, webhooks for the signal, a paced delta rather than a delta per notification if traffic is dense. $select everywhere. Never loop children (2 units) where a delta with a token is enough (1 unit). Safety net: a periodic delta at most once a day. Mass scans at night in the tenant time zone. Graph Data Connect if volume leaves interactive throttling.
A SharePoint integration project?
Let's talk. 30 minutes to scope sites, Sites.Selected, and what Graph files really allow, without recycling the Outlook page.
Discuss my SharePoint project