Box (box.com). Use this skill for ANY Box request — reading, creating, updating, and deleting data. Whenever a task involves Box, use this skill instead of calling the API directly.
记忆
box
试用通过托管 OAuth 网关调用 Box API,实现文件、文件夹与协作的读取与管理。
它能做什么
网关代理请求到 api.box.com/2.0 和 upload.box.com/api/2.0,并自动附加用户的 OAuth 令牌。可列出、上传、下载、重命名、复制和删除文件与文件夹,创建共享链接,并管理文件夹协作。直传支持最大 50 MB,超过后可通过分块上传会话上传最大 50 GB 的文件,同时提供搜索、用户信息和事件等接口。
什么时候用它
- 在 Box 文件夹中上传和下载文件
- 为文件夹创建共享链接或邀请协作者
- 在 Box 内搜索文件和文件夹
- 对超过 50 MB 的大文件进行分块上传
技能文档
Box
Access the Box API with managed OAuth authentication. Manage files, folders, collaborations, shared links, and cloud storage.
Quick Start
# Get current user info
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/box/2.0/users/me')
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://gateway.maton.ai/box/2.0/{resource}
The gateway proxies requests to api.box.com/2.0 (for most endpoints) or upload.box.com/api/2.0 (for upload endpoints) and automatically injects your OAuth token. The routing is handled automatically based on the endpoint path.
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 Box OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=box&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': 'box'}).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
Get Connection
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": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-08T21:14:41.808115Z",
"last_updated_time": "2026-02-08T21:16:10.100340Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "box",
"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://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
Specifying Connection
If you have multiple Box 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/box/2.0/users/me')
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 omitted, the gateway uses the default (oldest) active connection.
API Reference
User Info
Get Current User
GET /box/2.0/users/me
Response:
{
"type": "user",
"id": "48806418054",
"name": "Chris",
"login": "chris@example.com",
"created_at": "2026-02-08T13:12:34-08:00",
"modified_at": "2026-02-08T13:12:35-08:00",
"language": "en",
"timezone": "America/Los_Angeles",
"space_amount": 10737418240,
"space_used": 0,
"max_upload_size": 262144000,
"status": "active",
"avatar_url": "https://app.box.com/api/avatar/large/48806418054"
}
Get User
GET /box/2.0/users/{user_id}
Folder Operations
Get Root Folder
The root folder has ID 0:
GET /box/2.0/folders/0
Get Folder
GET /box/2.0/folders/{folder_id}
Response:
{
"type": "folder",
"id": "365037181307",
"name": "My Folder",
"description": "Folder description",
"size": 0,
"path_collection": {
"total_count": 1,
"entries": [
{"type": "folder", "id": "0", "name": "All Files"}
]
},
"created_by": {"type": "user", "id": "48806418054", "name": "Chris"},
"owned_by": {"type": "user", "id": "48806418054", "name": "Chris"},
"item_status": "active"
}
List Folder Items
GET /box/2.0/folders/{folder_id}/items
Query parameters:
limit- Maximum items to return (default 100, max 1000)offset- Offset for paginationfields- Comma-separated list of fields to include
Response:
{
"total_count": 1,
"entries": [
{
"type": "folder",
"id": "365036703666",
"name": "Subfolder"
}
],
"offset": 0,
"limit": 100
}
Create Folder
POST /box/2.0/folders
Content-Type: application/json
{
"name": "New Folder",
"parent": {"id": "0"}
}
Response:
{
"type": "folder",
"id": "365037181307",
"name": "New Folder",
"created_at": "2026-02-08T14:56:17-08:00"
}
Update Folder
PUT /box/2.0/folders/{folder_id}
Content-Type: application/json
{
"name": "Updated Folder Name",
"description": "Updated description"
}
Copy Folder
POST /box/2.0/folders/{folder_id}/copy
Content-Type: application/json
{
"name": "Copied Folder",
"parent": {"id": "0"}
}
Delete Folder
DELETE /box/2.0/folders/{folder_id}
Query parameters:
recursive- Set totrueto delete non-empty folders
Returns 204 No Content on success.
File Operations
Get File Info
GET /box/2.0/files/{file_id}
Download File
GET /box/2.0/files/{file_id}/content
Returns a redirect to the download URL.
Upload File
Upload a new file (up to 50 MB for direct upload):
POST /box/api/2.0/files/content
Content-Type: multipart/form-data
attributes={"name":"file.txt","parent":{"id":"0"}}
file=
The attributes field is a JSON string with:
name(required) - Filename to useparent.id(required) - Folder ID to upload to (use"0"for root)content_created_at- Optional timestampcontent_modified_at- Optional timestamp
Response:
{
"total_count": 1,
"entries": [
{
"type": "file",
"id": "123456789",
"name": "file.txt",
"size": 1024,
"created_at": "2026-04-14T10:00:00-07:00",
"modified_at": "2026-04-14T10:00:00-07:00",
"parent": {"type": "folder", "id": "0", "name": "All Files"}
}
]
}
Note: The gateway automatically routes upload endpoints to upload.box.com.
Upload New File Version
Upload a new version of an existing file:
POST /box/api/2.0/files/{file_id}/content
Content-Type: multipart/form-data
attributes={"name":"file.txt"}
file=
Chunked Upload (Large Files)
For files larger than 50 MB (up to 50 GB), use chunked upload sessions. The gateway automatically routes these endpoints to upload.box.com.
Create Upload Session
POST /box/api/2.0/files/upload_sessions
Content-Type: application/json
{
"folder_id": "0",
"file_size": 104857600,
"file_name": "large_file.zip"
}
Response:
{
"id": "F971964745A5CD0C001BBE4E58196BFD",
"type": "upload_session",
"session_expires_at": "2026-04-15T10:00:00-07:00",
"part_size": 8388608,
"total_parts": 13,
"num_parts_processed": 0,
"session_endpoints": {
"list_parts": "https://upload.box.com/api/2.0/files/upload_sessions/F971964745A5CD0C001BBE4E58196BFD/parts",
"commit": "https://upload.box.com/api/2.0/files/upload_sessions/F971964745A5CD0C001BBE4E58196BFD/commit",
"upload_part": "https://upload.box.com/api/2.0/files/upload_sessions/F971964745A5CD0C001BBE4E58196BFD",
"status": "https://upload.box.com/api/2.0/files/upload_sessions/F971964745A5CD0C001BBE4E58196BFD",
"abort": "https://upload.box.com/api/2.0/files/upload_sessions/F971964745A5CD0C001BBE4E58196BFD"
}
}
Create Upload Session for New Version
POST /box/api/2.0/files/{file_id}/upload_sessions
Content-Type: application/json
{
"file_size": 104857600,
"file_name": "large_file.zip"
}
Upload Part
PUT /box/api/2.0/files/upload_sessions/{session_id}
Content-Type: application/octet-stream
Content-Range: bytes 0-8388607/104857600
Digest: sha=
Response:
{
"part": {
"part_id": "6F2D3A7B8C4E5F6A",
"offset": 0,
"size": 8388608,
"sha1": "134b65991ed521fcfe4724b7d814ab8ded5185dc"
}
}
List Uploaded Parts
GET /box/api/2.0/files/upload_sessions/{session_id}/parts
Commit Upload Session
After all parts are uploaded:
POST /box/api/2.0/files/upload_sessions/{session_id}/commit
Content-Type: application/json
Digest: sha=
{
"parts": [
{"part_id": "6F2D3A7B8C4E5F6A", "offset": 0, "size": 8388608},
{"part_id": "7G3E4B8D9F5A6C7B", "offset": 8388608, "size": 8388608}
]
}
Response: Returns the created file object.
Abort Upload Session
DELETE /box/api/2.0/files/upload_sessions/{session_id}
Returns 204 No Content on success
Update File Info
PUT /box/2.0/files/{file_id}
Content-Type: application/json
{
"name": "renamed-file.txt",
"description": "File description"
}
Copy File
POST /box/2.0/files/{file_id}/copy
Content-Type: application/json
{
"name": "copied-file.txt",
"parent": {"id": "0"}
}
Delete File
DELETE /box/2.0/files/{file_id}
Returns 204 No Content on success.
Get File Versions
GET /box/2.0/files/{file_id}/versions
Shared Links
Create a shared link by updating a file or folder:
PUT /box/2.0/folders/{folder_id}
Content-Type: application/json
{
"shared_link": {
"access": "open"
}
}
Access levels:
open- Anyone with the linkcompany- Only users in the enterprisecollaborators- Only collaborators
Response includes:
{
"shared_link": {
"url": "https://app.box.com/s/sisarrztrenabyygfwqggbwommf8uucv",
"access": "open",
"effective_access": "open",
"is_password_enabled": false,
"permissions": {
"can_preview": true,
"can_download": true,
"can_edit": false
}
}
}
Collaborations
List Folder Collaborations
GET /box/2.0/folders/{folder_id}/collaborations
Create Collaboration
POST /box/2.0/collaborations
Content-Type: application/json
{
"item": {"type": "folder", "id": "365037181307"},
"accessible_by": {"type": "user", "login": "user@example.com"},
"role": "editor"
}
Roles: editor, viewer, previewer, uploader, previewer_uploader, viewer_uploader, co-owner
Update Collaboration
PUT /box/2.0/collaborations/{collaboration_id}
Content-Type: application/json
{
"role": "viewer"
}
Delete Collaboration
DELETE /box/2.0/collaborations/{collaboration_id}
Search
GET /box/2.0/search?query=document
Query parameters:
query- Search query (required)type- Filter by type:file,folder,web_linkfile_extensions- Comma-separated extensionsancestor_folder_ids- Limit to specific folderslimit- Max results (default 30)offset- Pagination offset
Response:
{
"total_count": 5,
"entries": [...],
"limit": 30,
"offset": 0,
"type": "search_results_items"
}
Events
GET /box/2.0/events
Query parameters:
stream_type-all,changes,sync,admin_logsstream_position- Position to start fromlimit- Max events to return
Response:
{
"chunk_size": 4,
"next_stream_position": "30401068076164269",
"entries": [...]
}
Trash
List Trashed Items
GET /box/2.0/folders/trash/items
Get Trashed Item
GET /box/2.0/files/{file_id}/trash
GET /box/2.0/folders/{folder_id}/trash
Restore Trashed Item
POST /box/2.0/files/{file_id}
POST /box/2.0/folders/{folder_id}
Permanently Delete
DELETE /box/2.0/files/{file_id}/trash
DELETE /box/2.0/folders/{folder_id}/trash
Collections (Favorites)
List Collections
GET /box/2.0/collections
Response:
{
"total_count": 1,
"entries": [
{
"type": "collection",
"name": "Favorites",
"collection_type": "favorites",
"id": "35223030868"
}
]
}
Get Collection Items
GET /box/2.0/collections/{collection_id}/items
Recent Items
GET /box/2.0/recent_items
Webhooks
List Webhooks
GET /box/2.0/webhooks
Create Webhook
POST /box/2.0/webhooks
Content-Type: application/json
{
"target": {"id": "365037181307", "type": "folder"},
"address": "https://example.com/webhook",
"triggers": ["FILE.UPLOADED", "FILE.DOWNLOADED"]
}
Note: Webhook creation may require enterprise permissions.
Delete Webhook
DELETE /box/2.0/webhooks/{webhook_id}
Pagination
Box uses offset-based pagination:
GET /box/2.0/folders/0/items?limit=100&offset=0
GET /box/2.0/folders/0/items?limit=100&offset=100
Some endpoints use marker-based pagination with marker parameter.
Response:
{
"total_count": 250,
"entries": [...],
"offset": 0,
"limit": 100
}
Code Examples
JavaScript
const response = await fetch(
'https://gateway.maton.ai/box/2.0/folders/0/items',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
Python
import os
import requests
response = requests.get(
'https://gateway.maton.ai/box/2.0/folders/0/items',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
Python (Create Folder)
import os
import requests
response = requests.post(
'https://gateway.maton.ai/box/2.0/folders',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'name': 'New Folder',
'parent': {'id': '0'}
}
)
folder = response.json()
print(f"Created folder: {folder['id']}")
Python (Upload File)
import os
import json
import requests
file_path = '/path/to/local/file.txt'
parent_folder_id = '0' # Root folder
with open(file_path, 'rb') as f:
response = requests.post(
'https://gateway.maton.ai/box/api/2.0/files/content',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'
},
files={
'attributes': (None, json.dumps({
'name': os.path.basename(file_path),
'parent': {'id': parent_folder_id}
})),
'file': (os.path.basename(file_path), f)
}
)
result = response.json()
file_entry = result['entries'][0]
print(f"Uploaded: {file_entry['name']} (ID: {file_entry['id']})")
Python (Chunked Upload for Large Files)
import os
import json
import hashlib
import base64
import requests
CHUNK_SIZE = 8 * 1024 * 1024 # 8 MB (Box's default part size)
file_path = '/path/to/large/file.zip'
parent_folder_id = '0'
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
file_size = os.path.getsize(file_path)
file_name = os.path.basename(file_path)
# Step 1: Create upload session
response = requests.post(
'https://gateway.maton.ai/box/api/2.0/files/upload_sessions',
headers={**headers, 'Content-Type': 'application/json'},
json={
'folder_id': parent_folder_id,
'file_size': file_size,
'file_name': file_name
}
)
session = response.json()
session_id = session['id']
part_size = session['part_size']
# Step 2: Upload parts
parts = []
file_sha1 = hashlib.sha1()
with open(file_path, 'rb') as f:
offset = 0
while offset < file_size:
chunk = f.read(part_size)
chunk_size = len(chunk)
end_byte = offset + chunk_size - 1
# Calculate SHA-1 for this part
part_sha1 = hashlib.sha1(chunk).digest()
file_sha1.update(chunk)
response = requests.put(
f'https://gateway.maton.ai/box/api/2.0/files/upload_sessions/{session_id}',
headers={
**headers,
'Content-Type': 'application/octet-stream',
'Content-Range': f'bytes {offset}-{end_byte}/{file_size}',
'Digest': f'sha={base64.b64encode(part_sha1).decode()}'
},
data=chunk
)
part_info = response.json()['part']
parts.append({
'part_id': part_info['part_id'],
'offset': part_info['offset'],
'size': part_info['size']
})
offset += chunk_size
print(f"Uploaded part {len(parts)}: {offset}/{file_size} bytes")
# Step 3: Commit upload session
response = requests.post(
f'https://gateway.maton.ai/box/api/2.0/files/upload_sessions/{session_id}/commit',
headers={
**headers,
'Content-Type': 'application/json',
'Digest': f'sha={base64.b64encode(file_sha1.digest()).decode()}'
},
json={'parts': parts}
)
result = response.json()
print(f"Upload complete: {result['entries'][0]['name']}")
Notes
- Root folder ID is
0 - The gateway automatically routes upload endpoints to
upload.box.com - Direct upload supports files up to 50 MB; use chunked upload for files up to 50 GB
- Upload endpoints use multipart/form-data with
attributesJSON andfilefields - Chunked uploads require SHA-1 digest headers for integrity verification
- Delete operations return 204 No Content on success
- Use
fieldsparameter to request specific fields and reduce response size - Shared links can have password protection and expiration dates
- Some operations (list users, create webhooks) require enterprise admin permissions
- ETags can be used for conditional updates with
If-Matchheader - 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 Box connection or bad request |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient permissions for the operation |
| 404 | Resource not found |
| 409 | Conflict (e.g., item with same name exists) |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Box API |
Box errors include detailed messages:
{
"type": "error",
"status": 409,
"code": "item_name_in_use",
"message": "Item with the same name already exists"
}
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://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
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
box. For example:
- Correct:
https://gateway.maton.ai/box/2.0/users/me - Incorrect:
https://gateway.maton.ai/2.0/users/me
Resources
相关技能
通过 Maton 网关访问 Dropbox 文件、文件夹与元数据,OAuth 由网关托管。
通过托管 OAuth 管理 Dropbox Business 团队,默认只读,所有写入需用户确认。
通过 Microsoft Graph 与托管 OAuth 管理 OneDrive 文件、文件夹、驱动器与共享。
通过托管 OAuth 的代理调用 WhatsApp Business API,发送消息、管理模板与媒体。
通过托管 OAuth 代理调用 Slack API,实现发消息、管频道、列用户和定时投递。