Box
description: |
by byungkyu · published 2026-03-22
$ claw add gh:byungkyu/byungkyu-box---
name: box
description: |
Box API integration with managed OAuth. Manage files, folders, collaborations, and cloud storage.
Use this skill when users want to upload, download, share, or organize files and folders in Box.
For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Requires network access and valid Maton API key.
metadata:
author: maton
version: "1.0"
clawdbot:
emoji: 🧠
requires:
env:
- MATON_API_KEY
---
# 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))
EOFBase URL
https://gateway.maton.ai/box/2.0/{resource}The gateway proxies requests to `api.box.com/2.0` 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
1. Sign in or create an account at [maton.ai](https://maton.ai)
2. Go to [maton.ai/settings](https://maton.ai/settings)
3. 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))
EOFCreate 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))
EOFGet 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": "bd484938-0902-4fc0-9ffb-2549d7d91f1d",
"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))
EOFSpecifying 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', 'bd484938-0902-4fc0-9ffb-2549d7d91f1d')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFIf 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}/itemsQuery parameters:
**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:
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}/contentReturns a redirect to the download URL.
#### Upload File
POST https://upload.box.com/api/2.0/files/content
Content-Type: multipart/form-data
attributes={"name":"file.txt","parent":{"id":"0"}}
file=<binary data>**Note:** File uploads use a different base URL: `upload.box.com`
#### 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}/versionsShared 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:
**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=documentQuery parameters:
**Response:**
{
"total_count": 5,
"entries": [...],
"limit": 30,
"offset": 0,
"type": "search_results_items"
}Events
GET /box/2.0/eventsQuery parameters:
**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}/trashCollections (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}/itemsRecent Items
GET /box/2.0/recent_itemsWebhooks
#### 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=100Some 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']}")Notes
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
1. Check that the `MATON_API_KEY` environment variable is set:
echo $MATON_API_KEY2. 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))
EOFTroubleshooting: Invalid App Name
1. Ensure your URL path starts with `box`. For example:
Resources
More tools from the same signal band
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
Sign plugins, rotate agent credentials without losing identity, and publicly attest to plugin behavior with verifiable claims and authenticated transfers.
The philosophical layer for AI agents. Maps behavior to Spinoza's 48 affects, calculates persistence scores, and generates geometric self-reports. Give your...