Sources
SharePoint
Connect a Microsoft 365 account and feed a document base from a site's document library. Read-only permissions, incremental syncs, and your folder structure preserved.
Connect a Microsoft 365 account and feed a document base from a SharePoint site's document library, or from one folder inside it. Access runs through Microsoft Graph with read-only permissions, so nothing Engram holds can change anything in your tenant.
What you need
Someone who can consent for the Microsoft 365 tenant, and the site or folder you want to read. The permissions requested are read-only:
| Permission | Why it is asked for |
|---|---|
Sites.Read.All | Find the sites and their document libraries |
Files.Read.All | List folders and read the files inside them |
User.Read | Identify the account that connected |
offline_access | Keep syncing after the browser session ends |
There is no write permission anywhere in that list. Tokens are encrypted at rest, and disconnecting in the app deletes them.
1. Connect and pick a library
Connecting is a browser flow, so it happens in the app: on the Documents step of a document base's setup, choose Connect SharePoint. Consent once and the connection belongs to your workspace.
SharePoint has no picker of its own, so you browse inside the app instead and the ids it hands back are opaque values you pass straight through:
| Id shape | What it points at |
|---|---|
| no id | The tenant's sites, so you can choose one |
site:<siteId> | That site's default document library, at its root |
item:<driveId>:<itemId> | One folder inside a library |
Treat them as blobs. Pass back exactly what you received rather than building one by hand.
2. Import once, or register a source
A one-off import pulls a folder now and stops:
curl -X POST https://api.engramdynamics.org/v1/corpora/c_7a1f.../import \
-H "Authorization: Bearer <your key>" \
-H "Content-Type: application/json" \
-d '{
"connection_id": "cc_71f4...",
"folder_id": "item:b!Ab3...:01ABCXYZ",
"folder_name": "Policies"
}'
A source keeps it current:
curl -X POST https://api.engramdynamics.org/v1/corpora/c_7a1f.../sources \
-H "Authorization: Bearer <your key>" \
-H "Content-Type: application/json" \
-d '{
"kind": "sharepoint",
"connection_id": "cc_71f4...",
"site_id": "contoso.sharepoint.com,8f3c...,2d91...",
"folder_id": "item:b!Ab3...:01ABCXYZ",
"mode": "additive",
"schedule_minutes": 360
}'
site_id is only needed when you are pointing at a site's default library;
folder_id alone is enough for a folder inside one. As with Drive there is no template to
apply: the connection is the credential, so the source comes back ready and the first
sync is what proves the folder is readable.
source = requests.post(
f"{BASE}/corpora/{base_id}/sources",
headers=HEADERS,
json={
"kind": "sharepoint",
"connection_id": connection_id,
"folder_id": folder_id,
"mode": "mirror",
"schedule_minutes": 360,
},
timeout=30,
).json()
run = requests.post(
f"{BASE}/corpora/{base_id}/sources/{source['id']}/sync", headers=HEADERS, timeout=30
).json()
print(run["id"], run["state"])
How updates are picked up
After the first sync we hold Microsoft Graph's delta cursor for that library or folder and ask only
for what changed, so a large library with a handful of edits fetches a handful of files.
has_delta_token on the source says the cursor is held. Removals come back as removals, so
a source in mirror mode takes the document out of the base and one in
additive mode leaves it.
Folder structure is preserved as document paths, so a file at Policies/EU/refunds.docx
in the library is at the same path in the base.
Limits and troubleshooting
- One import run considers up to 2,000 files. Split a very large library across folders, or register several sources, up to the 10 per base ceiling.
- Files over the per-object ceiling are skipped and the counter says so rather than the run failing.
- Only the accepted types are read. See What counts as a document.
- A sync failing with an authorization error means consent was withdrawn or the account lost access to the site. Reconnect in the app.
- SharePoint is not offered at all in an environment where the connector is off. Use S3 in the meantime.
Next
Turning a library or folder into a standing source from the Sources section of the Documents tab, on a schedule you pick: Keeping a folder in sync. What we can read out of each file, and how a file becomes a document: What counts as a document.