Microsoft Excel
Microsoft Excel API integration with managed OAuth. Read and write Excel workbooks, worksheets, ranges, tables, and charts stored in OneDrive. Use this skill...
byungkyu
@byungkyu
What This Skill Does
API wrapper for Microsoft Excel that reads and writes workbooks, worksheets, ranges, tables, and charts stored in OneDrive or SharePoint, using managed OAuth authentication via Maton.
Replaces building custom OAuth flows and direct Microsoft Graph calls by providing a single API key to access all Excel workbook operations.
When to Use It
- Read cell values or ranges from an Excel workbook stored in OneDrive
- Write or update data in specific cells or named ranges
- List all worksheets in a workbook
- Create or delete worksheets within an existing workbook
- Add, update, or remove tables and charts in a worksheet
- Export workbook data for use in scripts or reports
Install
$ openclaw skills install @byungkyu/microsoft-excelMicrosoft Excel
Access the Microsoft Excel API (via Microsoft Graph) with managed OAuth authentication. Read and write workbooks, worksheets, ranges, tables, and charts stored in OneDrive or SharePoint.
Quick Start
# List worksheets in a workbook
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets')
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/microsoft-excel/{native-api-path}
Maton proxies requests to graph.microsoft.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your Microsoft Excel OAuth connections at https://api.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=microsoft-excel&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
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'microsoft-excel'}).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
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-07T00:43:18.565932Z",
"last_updated_time": "2026-02-07T00:43:29.729782Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "microsoft-excel",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
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 Microsoft Excel connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/microsoft-excel/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 include this header to ensure requests go to the intended account.
Workbook Access Patterns
You can access workbooks using either ID-based or path-based patterns:
By File ID:
/microsoft-excel/v1.0/me/drive/items/{file-id}/workbook/...
By File Path:
/microsoft-excel/v1.0/me/drive/root:/{path-to-file}:/workbook/...
Security & Permissions
- Access is scoped to workbooks, worksheets, tables, and cell data within the connected Microsoft Excel 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
Drive Operations
Get Drive Info
GET /microsoft-excel/v1.0/me/drive
List Root Files
GET /microsoft-excel/v1.0/me/drive/root/children
Search for Excel Files
GET /microsoft-excel/v1.0/me/drive/root/search(q='.xlsx')
Upload Excel File
PUT /microsoft-excel/v1.0/me/drive/root:/{filename}.xlsx:/content
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
{binary xlsx content}
Session Management
Sessions improve performance for multiple operations. Recommended for batch operations.
Create Session
POST /microsoft-excel/v1.0/me/drive/root:/{path}:/workbook/createSession
Content-Type: application/json
{
"persistChanges": true
}
Response:
{
"persistChanges": true,
"id": "cluster=PUS7&session=..."
}
Use the session ID in subsequent requests:
workbook-session-id: {session-id}
Close Session
POST /microsoft-excel/v1.0/me/drive/root:/{path}:/workbook/closeSession
workbook-session-id: {session-id}
Worksheet Operations
List Worksheets
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets
Response:
{
"value": [
{
"id": "{00000000-0001-0000-0000-000000000000}",
"name": "Sheet1",
"position": 0,
"visibility": "Visible"
}
]
}
Get Worksheet
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')
Create Worksheet
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets
Content-Type: application/json
{
"name": "NewSheet"
}
Update Worksheet
PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')
Content-Type: application/json
{
"name": "RenamedSheet",
"position": 2
}
Delete Worksheet
DELETE /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('{worksheet-id}')
Returns 204 No Content on success.
Range Operations
Get Range
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')
Response:
{
"address": "Sheet1!A1:B2",
"values": [
["Hello", "World"],
[1, 2]
],
"formulas": [
["Hello", "World"],
[1, 2]
],
"text": [
["Hello", "World"],
["1", "2"]
],
"numberFormat": [
["General", "General"],
["General", "General"]
],
"rowCount": 2,
"columnCount": 2
}
Get Used Range
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/usedRange
Update Range
PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')
Content-Type: application/json
{
"values": [
["Updated", "Values"],
[100, 200]
]
}
Clear Range
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')/clear
Content-Type: application/json
{
"applyTo": "All"
}
Options: All, Formats, Contents
Table Operations
List Tables
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/tables
Create Table from Range
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/tables/add
Content-Type: application/json
{
"address": "A1:C4",
"hasHeaders": true
}
Response:
{
"id": "{6D182180-5F5F-448B-9E9C-377A5251CFC5}",
"name": "Table1",
"showHeaders": true,
"showTotals": false,
"style": "TableStyleMedium2"
}
Get Table
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')
Update Table
PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')
Content-Type: application/json
{
"name": "PeopleTable",
"showTotals": true
}
Get Table Rows
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows
Response:
{
"value": [
{
"index": 0,
"values": [["Alice", 30, "NYC"]]
},
{
"index": 1,
"values": [["Bob", 25, "LA"]]
}
]
}
Add Table Row
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows
Content-Type: application/json
{
"values": [["Carol", 35, "Chicago"]]
}
Delete Table Row
DELETE /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows/itemAt(index=0)
Returns 204 No Content on success.
Get Table Columns
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/columns
Add Table Column
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/columns
Content-Type: application/json
{
"values": [["Email"], ["alice@example.com"], ["bob@example.com"]]
}
Named Items
List Named Items
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/names
Charts
List Charts
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/charts
Add Chart
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/charts/add
Content-Type: application/json
{
"type": "ColumnClustered",
"sourceData": "A1:C4",
"seriesBy": "Auto"
}
Code Examples
JavaScript
// Get range values
const response = await fetch(
"https://api.maton.ai/microsoft-excel/v1.0/me/drive/root:/data.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B10')",
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
console.log(data.values);
Python
import os
import requests
# Update range values
response = requests.patch(
"https://api.maton.ai/microsoft-excel/v1.0/me/drive/root:/data.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')",
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
json={'values': [['Name', 'Age'], ['Alice', 30]]}
)
print(response.json())
Notes
- Only
.xlsxfiles are supported (not legacy.xls) - Worksheet names with special characters need URL encoding
- Table and worksheet IDs containing
{and}must be URL-encoded (%7Band%7D) - Sessions expire after ~5 minutes of inactivity (persistent) or ~7 minutes (non-persistent)
- Use
nullin value arrays to skip updating specific cells - Blank cells should use
""(empty string) - Range addresses use A1 notation (e.g.,
A1:C10,Sheet1!A1:B5) - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain parentheses 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 Microsoft Excel connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 404 | Item not found or session expired |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Microsoft Graph API |
Common Error Codes
| Code | Description |
|---|---|
ItemNotFound | File or resource doesn't exist |
ItemAlreadyExists | Worksheet or table with that name already exists |
InvalidArgument | Invalid parameter or missing required field |
SessionNotFound | Session expired or doesn't exist |
Troubleshooting: API Key Issues
- 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
microsoft-excel. For example:
- Correct:
https://api.maton.ai/microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets - Incorrect:
https://api.maton.ai/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets
Resources
Top skills in this category
LinkedIn API integration with managed OAuth. Share posts, manage profile, and access LinkedIn features. Use this skill when users want to share content on LinkedIn, get profile/organization information, or interact with LinkedIn's platform.
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).
Todoist
@byungkyuTodoist API integration with managed OAuth. Manage tasks, projects, sections, labels, and comments. Use this skill when users want to create, update, complet...
Writing Assistant
@urrrichYou are a Writing Team Lead managing specialized writers via MCP tools. Please ANALYZE the writing task and then:1. if exist references, create a detailed co...
Google Tasks
@byungkyuGoogle Tasks API integration with managed OAuth. Manage task lists and tasks with full CRUD operations. Use this skill when users want to read, create, update, or delete tasks and task lists in Google Tasks. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gatew