Microsoft OneDrive
OneDrive API integration with managed OAuth via Microsoft Graph. Manage files, folders, and sharing. Use this skill when users want to upload, download, organize, or share files in…
byungkyu
@byungkyu
What This Skill Does
API integration for Microsoft OneDrive via Microsoft Graph with managed OAuth authentication. Supports full CRUD operations on files, folders, drives, and sharing through CLI or HTTP requests.
Replaces building custom OAuth flows and direct Microsoft Graph API calls by providing a managed proxy that handles authentication and token refresh automatically.
When to Use It
- Upload files to a specific OneDrive folder from a script or automation
- Download files from OneDrive to local storage programmatically
- List all files and folders in a OneDrive directory
- Share a file or folder with external users via a sharing link
- Delete or move files and folders within OneDrive
- Create new folders to organize OneDrive content
Install
$ openclaw skills install @byungkyu/one-driveOneDrive
Access the OneDrive API with managed OAuth authentication via Microsoft Graph. Manage files, folders, drives, and sharing with full CRUD operations.
Quick Start
CLI:
maton one-drive item list
maton api '/one-drive/v1.0/me/drive/root/children'
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/one-drive/v1.0/me/drive/root/children')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://api.maton.ai/one-drive/v1.0/{resource}
Maton proxies requests to graph.microsoft.com and automatically injects your OAuth token.
Installation
NPM:
npm install -g @maton/cli
Homebrew:
brew install maton-ai/cli/maton
Authentication
CLI:
maton login # Opens browser for API key
maton login --interactive # Skip browser, paste API key directly
maton whoami # Show current auth state
Manual:
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
- Set your API key as
MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Connection Management
Manage your OneDrive OAuth connections at https://api.maton.ai.
List Connections
CLI:
maton connection list one-drive --status ACTIVE
maton api -X GET /connections -f app=one-drive -f status=ACTIVE
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=one-drive&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
CLI:
maton connection create one-drive
maton api /connections -f app=one-drive
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'one-drive'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
CLI:
maton connection view {connection_id}
maton api /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-07T08:23:30.317909Z",
"last_updated_time": "2026-02-07T08:24:04.925298Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "one-drive",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
CLI:
maton connection delete {connection_id}
maton api -X DELETE /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple OneDrive connections, specify which one to use:
CLI:
maton one-drive item list --connection {connection_id}
maton api /one-drive/v1.0/me/drive/root/children --connection {connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/one-drive/v1.0/me/drive')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always specify the connection to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to files, folders, and sharing within the connected OneDrive account.
- All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
API Reference
Drives
Get Current User's Drive
GET /one-drive/v1.0/me/drive
Example:
maton one-drive whoami
List User's Drives
GET /one-drive/v1.0/me/drives
Example:
maton one-drive drive list
Get Drive by ID
GET /one-drive/v1.0/drives/{drive-id}
Example:
maton one-drive drive view {drive-id}
Files and Folders
Get Drive Root
GET /one-drive/v1.0/me/drive/root
Example:
maton one-drive item view root
List Root Children
GET /one-drive/v1.0/me/drive/root/children
Example:
maton one-drive item list
Get Item by ID
GET /one-drive/v1.0/me/drive/items/{item-id}
Example:
maton one-drive item view {item-id}
Get Item by Path
Use colon (:) syntax to access items by path:
GET /one-drive/v1.0/me/drive/root:/Documents/report.pdf
Example:
maton one-drive item view-by-path Documents/report.pdf
List Folder Children by Path
GET /one-drive/v1.0/me/drive/root:/Documents:/children
Example:
maton one-drive item list Documents
Get Item Children
GET /one-drive/v1.0/me/drive/items/{item-id}/children
Example:
maton one-drive item view {item-id} --expand children
Special Folders
Access known folders by name:
GET /one-drive/v1.0/me/drive/special/documents
GET /one-drive/v1.0/me/drive/special/photos
GET /one-drive/v1.0/me/drive/special/music
GET /one-drive/v1.0/me/drive/special/approot
Example:
maton one-drive item view --special documents
Recent and Shared
Get Recent Files
GET /one-drive/v1.0/me/drive/recent
Example:
maton one-drive drive recent
Get Files Shared With Me
GET /one-drive/v1.0/me/drive/sharedWithMe
Example:
maton one-drive drive shared
Search
GET /one-drive/v1.0/me/drive/root/search(q='budget')
Example:
maton one-drive drive search 'budget'
Create Folder
POST /one-drive/v1.0/me/drive/root:/Documents:/children
Content-Type: application/json
{
"name": "Reports",
"folder": {},
"@microsoft.graph.conflictBehavior": "rename"
}
Example:
maton one-drive item create-folder Reports --path Documents
Create folder inside another folder by parent ID:
POST /one-drive/v1.0/me/drive/items/{parent-id}/children
Content-Type: application/json
{
"name": "Reports",
"folder": {}
}
Example:
maton one-drive item create-folder Reports --parent-id {parent-id}
Upload File (Simple - up to 4MB)
PUT /one-drive/v1.0/me/drive/root:/Documents/report.pdf:/content
Content-Type: application/pdf
{report.pdf binary content}
Example:
maton one-drive item upload ./report.pdf --path Documents/report.pdf
Upload File (Large - resumable)
For files over 4MB, use resumable upload:
Step 1: Create upload session
POST /one-drive/v1.0/me/drive/root:/large-report.pdf:/createUploadSession
Content-Type: application/json
{
"item": {
"@microsoft.graph.conflictBehavior": "rename"
}
}
Example:
maton one-drive item upload ./large-report.pdf --path large-report.pdf --conflict rename
Files larger than 4 MiB automatically use a resumable upload session.
Response:
{
"uploadUrl": "https://sn3302.up.1drv.com/up/...",
"expirationDateTime": "2024-02-08T10:00:00Z"
}
Step 2: Upload bytes to the uploadUrl
Download File
Get the file metadata to retrieve the download URL:
GET /one-drive/v1.0/me/drive/items/{item-id}
Example:
maton one-drive item view {item-id}
The response includes @microsoft.graph.downloadUrl - a pre-authenticated URL valid for a short time:
{
"id": "...",
"name": "document.pdf",
"@microsoft.graph.downloadUrl": "https://public-sn3302.files.1drv.com/..."
}
Use this URL directly to download the file content (no auth header needed).
Update Item (Rename/Move)
PATCH /one-drive/v1.0/me/drive/items/{item-id}
Content-Type: application/json
{
"name": "new-name.txt"
}
Example:
maton one-drive item update {item-id} --name new-name.txt
Move to different folder:
PATCH /one-drive/v1.0/me/drive/items/{item-id}
Content-Type: application/json
{
"parentReference": {
"id": "{new-parent-id}"
}
}
Example:
maton one-drive item move {item-id} --dest-id {new-parent-id}
Copy Item
POST /one-drive/v1.0/me/drive/items/{item-id}/copy
Content-Type: application/json
{
"parentReference": {
"id": "{destination-folder-id}"
},
"name": "copied-file.txt"
}
Example:
maton one-drive item copy {item-id} --dest-id {destination-folder-id} --name copied-file.txt
Returns 202 Accepted with a Location header to monitor the copy operation.
Delete Item
DELETE /one-drive/v1.0/me/drive/items/{item-id}
Example:
maton one-drive item delete {item-id}
Returns 204 No Content on success.
Sharing
Create Sharing Link
POST /one-drive/v1.0/me/drive/items/01ABCDEF/createLink
Content-Type: application/json
{
"type": "view",
"scope": "anonymous"
}
Link types:
view- Read-only accessedit- Read-write accessembed- Embeddable link
Scopes:
anonymous- Anyone with the linkorganization- Anyone in your organization
Example:
maton one-drive item share 01ABCDEF --type view --scope anonymous
Invite Users (Share with specific people)
POST /one-drive/v1.0/me/drive/items/{item-id}/invite
Content-Type: application/json
{
"recipients": [
{"email": "user@example.com"}
],
"roles": ["read"],
"sendInvitation": true,
"message": "Check out this file!"
}
Example:
maton one-drive item invite {item-id} --emails user@example.com --roles read --message 'Check out this file!'
Query Parameters
Customize responses with OData query parameters:
$select- Choose specific properties:?$select=id,name,size$expand- Include related resources:?$expand=children$filter- Filter results:?$filter=file ne null(files only)$orderby- Sort results:?$orderby=name asc$top- Limit results:?$top=10
Example:
GET /one-drive/v1.0/me/drive/root/children?$select=id,name,size&$top=20&$orderby=name%20asc
maton one-drive item list --select id,name,size --top 20 --orderby 'name asc'
Pagination
OneDrive uses cursor-based pagination. The CLI automatically paginates with '--paginate'.
Example:
maton one-drive item list --paginate
Code Examples
CLI
# Search for files
maton one-drive drive search 'budget'
# Share a file
maton one-drive item share 01ABCDEF --type view --scope anonymous
# Extract specific fields with --jq (requires --json)
maton one-drive item view root --json --jq '.name'
JavaScript
// List files in root
const response = await fetch(
'https://api.maton.ai/one-drive/v1.0/me/drive/root/children',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
// Upload a file
const uploadResponse = await fetch(
'https://api.maton.ai/one-drive/v1.0/me/drive/root:/myfile.txt:/content',
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
'Content-Type': 'text/plain'
},
body: 'Hello, OneDrive!'
}
);
Python
import os
import requests
# List files in root
response = requests.get(
'https://api.maton.ai/one-drive/v1.0/me/drive/root/children',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
files = response.json()
# Upload a file
upload_response = requests.put(
'https://api.maton.ai/one-drive/v1.0/me/drive/root:/myfile.txt:/content',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'text/plain'
},
data='Hello, OneDrive!'
)
Notes
- OneDrive uses Microsoft Graph API (
graph.microsoft.com) - Item IDs are unique within a drive
- Use colon (
:) syntax for path-based addressing:/root:/path/to/file - Files ≤4MB upload via a single PUT; larger files automatically use a resumable upload session
- Download URLs from
@microsoft.graph.downloadUrlare pre-authenticated and temporary - Conflict behavior options:
fail,replace,rename - On personal OneDrive accounts, only the user's own drive ID (returned by
whoami) is directly addressable. The additionalb!...-prefixed IDs that appear indrive listreturn HTTP 400 from Microsoft Graph when fetched this way. Useme/driveinstead. - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing OneDrive connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient permissions |
| 404 | Item not found |
| 409 | Conflict (e.g., item already exists) |
| 429 | Rate limited (check Retry-After header) |
| 4xx/5xx | Passthrough error from Microsoft Graph API |
Error Response Format
{
"error": {
"code": "itemNotFound",
"message": "The resource could not be found."
}
}
Troubleshooting: API Key Issues
CLI:
- Check your auth state:
maton whoami
- Verify the API key is valid by listing connections:
maton connection list
Manual:
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
one-drive. For example:
- Correct:
https://api.maton.ai/one-drive/v1.0/me/drive/root/children - Incorrect:
https://api.maton.ai/v1.0/me/drive/root/children
Resources
Related skills
Outlook
@byungkyuMicrosoft Outlook API integration with managed OAuth. Read, send, and manage emails, folders, calendar events, and contacts via Microsoft Graph. Use this skill when users want to interact with Outlook. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Google Drive
@byungkyuGoogle Drive API integration with managed OAuth. List, search, create, and manage files and folders. Use this skill when users want to interact with Google Drive files. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Gmail
@byungkyuGmail API integration with managed OAuth. Read, send, and manage emails, threads, labels, and drafts. Use this skill when users want to interact with Gmail. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Google Sheets
@byungkyuGoogle Sheets API integration with managed OAuth. Read and write spreadsheet data, create sheets, apply formatting, and manage ranges. Use this skill when users want to read from or write to Google Sheets. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway
Google Calendar
@byungkyuGoogle Calendar API integration with managed OAuth. Create events, list calendars, check availability, and manage schedules. Use this skill when users want to interact with Google Calendar. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Trello
@byungkyuTrello API integration with managed OAuth. Manage boards, lists, cards, members, and labels. Use this skill when users want to interact with Trello for project management. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).