How to Export File Metadata from Box
Box admins can generate inventory reports in minutes. Developers can tap the Metadata Query API for richer, template-specific exports.
Box does not have a user-facing "export file list as CSV" button in the standard web interface. However, Box has stronger admin tooling than most platforms: admins can generate file and folder reports directly from the Admin Console. For custom metadata (Box Metadata Templates), the Metadata Query API and Box CLI provide targeted exports.
Box Admin Console Reports
This is the fastest path to a file metadata export. Box Business and Enterprise admins can generate a file inventory report directly from the Admin Console with no code, no API setup, and no installations required. The report downloads as a CSV.
app.box.com/master.Box CLI + Metadata Queries
The official Box CLI lets you query files by metadata template and export the results. This is the best approach when you need custom metadata template values (e.g., contract type, department, expiration date) alongside system metadata.
npm install -g @box/cli) or download the binary from the Box CLI GitHub repository.box configure:environments:add and provide your Box app credentials (Client ID and Client Secret from the Box Developer Console).# List all files in a folder with system metadata
box files:list FOLDER_ID --json > box_files.json
# Query files by metadata template
box metadata-queries:execute-read \
--from "enterprise_12345.contractMetadata" \
--ancestor-folder-id 0 \
--json > contract_metadata.json
# Convert JSON to CSV (using jq + csvkit, or Python)
python3 -c "
import json, csv, sys
with open('box_files.json') as f:
data = json.load(f)
w = csv.writer(sys.stdout)
w.writerow(['Name','ID','Size','Created','Modified','Owner'])
for item in data.get('entries', data) if isinstance(data, dict) else data:
w.writerow([
item.get('name',''),
item.get('id',''),
item.get('size',''),
item.get('created_at',''),
item.get('modified_at',''),
item.get('owned_by',{}).get('login','')
])
" > box_metadata.csv/metadata_queries/execute_read) is purpose-built for querying files by custom metadata. You specify a template, optional filter conditions, and which fields to return. It supports SQL-like queries: you can filter by status, date ranges, departments, or any field in your metadata template.Python + Box SDK
The Box Python SDK gives you the most flexibility. Walk folder trees, pull system metadata and custom metadata template values for each file, and export everything to your preferred format. Best for complex exports that combine system metadata with custom metadata.
app.box.com/developers/console. Choose Server Authentication (Client Credentials Grant) for the simplest setup.pip install boxsdkfrom boxsdk import CCGAuth, Client
import csv
# Authenticate with Client Credentials Grant
auth = CCGAuth(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
enterprise_id="YOUR_ENTERPRISE_ID"
)
client = Client(auth)
def list_folder_recursive(folder_id="0"):
"""Walk all folders and collect file metadata."""
files = []
items = client.folder(folder_id).get_items(
fields=["name","id","size","created_at","modified_at",
"owned_by","sha1","description","tags","path_collection"]
)
for item in items:
if item.type == "file":
files.append(item)
elif item.type == "folder":
files.extend(list_folder_recursive(item.id))
return files
all_files = list_folder_recursive()
with open("box_metadata.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow([
"Name", "ID", "Size", "Created", "Modified",
"Owner", "SHA1", "Description", "Tags", "Path"
])
for file in all_files:
path = " / ".join(
[e.name for e in file.path_collection["entries"]]
) if file.path_collection else ""
writer.writerow([
file.name,
file.id,
file.size,
file.created_at,
file.modified_at,
file.owned_by.login if file.owned_by else "",
file.sha1 or "",
file.description or "",
", ".join(file.tags) if file.tags else "",
path
])
print(f"Exported {len(all_files)} files to box_metadata.csv")client.file(file.id).metadata(scope='enterprise', template='yourTemplate').get() inside the loop. This returns a dictionary of template field names and values that you can add as extra columns to your CSV.What metadata fields can you export?
| Field | Admin Reports | Box CLI | Python SDK |
|---|---|---|---|
| File name | ✓ | ✓ | ✓ |
| File ID | ✓ | ✓ | ✓ |
| File size | ✓ | ✓ | ✓ |
| Created date | ✓ | ✓ | ✓ |
| Modified date | ✓ | ✓ | ✓ |
| Owner | ✓ | ✓ | ✓ |
| Full folder path | ✓ | ✓ | ✓ |
| SHA-1 hash | ✕ | ✓ | ✓ |
| Description | ✕ | ✓ | ✓ |
| Tags | ✕ | ✓ | ✓ |
| Shared link status | ✓ | ✓ | ✓ |
| Custom metadata templates | ✕ | ✓ | ✓ |
| Content type / extension | ✓ | ✓ | ✓ |
| Collaboration count | ✓ | ✕ | Separate call |
| Version number | ✕ | ✓ | ✓ |
| File lock status | ✕ | ✓ | ✓ |
- Custom metadata requires API access: Box Admin Console reports export system metadata (name, size, dates, owner, sharing) but do not include custom metadata template field values. Use the Box CLI or Python SDK for those.
- Box Skills metadata (AI-extracted metadata from Skills cards) uses a different metadata scope (
global.boxSkillsCards) and is structured differently from standard templates. It requires specific API handling. - Rate limiting: The Box API enforces rate limits (~10 requests/second for most endpoints). For large exports (100,000+ files), the folder-walking approach in Method 3 can be slow. Consider using the Metadata Query API (Method 2) for targeted exports of specific templates.
You have your metadata export.
Now score it.
Upload your CSV or Excel file to MQS and get a structural metadata health score out of 100 with dimension breakdowns and actionable diagnostics.