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 when users want to read or modify Excel sp
Microsoft Excel API integration with managed OAuth. Read and write Excel workbooks, worksheets, ranges, tables, and charts stored in OneDrive. Use this skill when users want to read or modify Excel sp
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
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.
# List worksheets in a workbook python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.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
https://gateway.maton.ai/microsoft-excel/{native-api-path}
Replace {native-api-path} with the actual Microsoft Graph API endpoint path. The gateway proxies requests to graph.microsoft.com and automatically injects your OAuth token.
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"
Manage your Microsoft Excel OAuth connections at https://ctrl.maton.ai.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.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
python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'microsoft-excel'}).encode() req = urllib.request.Request('https://ctrl.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
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.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": "4751ac89-3970-47e1-872c-eacdf4291732", "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.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.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
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://gateway.maton.ai/microsoft-excel/v1.0/me/drive') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '4751ac89-3970-47e1-872c-eacdf4291732') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If omitted, the gateway uses the default (oldest) active connection.
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/...
GET /microsoft-excel/v1.0/me/drive
GET /microsoft-excel/v1.0/me/drive/root/children
GET /microsoft-excel/v1.0/me/drive/root/search(q='.xlsx')
PUT /microsoft-excel/v1.0/me/drive/root:/{filename}.xlsx:/content Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet {binary xlsx content}
Sessions improve performance for multiple operations. Recommended for batch operations.
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}
POST /microsoft-excel/v1.0/me/drive/root:/{path}:/workbook/closeSession workbook-session-id: {session-id}
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 /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets Content-Type: application/json { "name": "NewSheet" }
PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1') Content-Type: application/json { "name": "RenamedSheet", "position": 2 }
DELETE /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('{worksheet-id}')
Returns 204 No Content on success.
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 /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/usedRange
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] ] }
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
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/tables
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 /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')
PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1') Content-Type: application/json { "name": "PeopleTable", "showTotals": true }
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"]] } ] }
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows Content-Type: application/json { "values": [["Carol", 35, "Chicago"]] }
DELETE /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows/itemAt(index=0)
Returns 204 No Content on success.
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/columns
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"]] }
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/names
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/charts
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" }
// Get range values const response = await fetch( "https://gateway.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);
import os import requests # Update range values response = requests.patch( "https://gateway.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())
| 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 |
| 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 |
echo $MATON_API_KEY
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.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
Ensure your URL path starts with microsoft-excel. For example:
Correct: https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets
Incorrect: https://gateway.maton.ai/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets
No automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.