Introduction
# Dropbox
Access the Dropbox API with managed OAuth authentication. Manage files and folders, search content, retrieve metadata, and work with file revisions.
## Quick Start
```bash # List files in root folder python <<'EOF' import urllib.request, os, json data = json.dumps({"path": ""}).encode() req = urllib.request.Request('https://gateway.maton.ai/dropbox/2/files/list_folder', 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 ```
## Base URL
``` https://gateway.maton.ai/dropbox/2/{endpoint} ```
The gateway proxies requests to `api.dropboxapi.com` and automatically injects your OAuth token.
**Important:** Dropbox API v2 uses POST for all endpoints with JSON request bodies.
## 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`:
```bash 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 Dropbox OAuth connections at `https://ctrl.maton.ai`.
### List Connections
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=dropbox&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
```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'dropbox'}).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
```bash 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:** ```json { "connection": { "connection_id": "1efbb655-88e9-4a23-ad3b-f3e19cbff279", "status": "ACTIVE", "creation_time": "2026-02-09T23:34:49.818074Z", "last_updated_time": "2026-02-09T23:37:09.697559Z", "url": "https://connect.maton.ai/?session_token=...", "app": "dropbox", "metadata": {} } } ```
Open the returned `url` in a browser to complete OAuth authorization.
### Delete Connection
```bash 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 Dropbox connections, specify which one to use with the `Maton-Connection` header:
```bash python <<'EOF' import urllib.request, os, json data = json.dumps({"path": ""}).encode() req = urllib.request.Request('https://gateway.maton.ai/dropbox/2/files/list_folder', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') req.add_header('Maton-Connection', '1efbb655-88e9-4a23-ad3b-f3e19cbff279') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
If omitted, the gateway uses the default (oldest) active connection.
## API Reference
### Users
#### Get Current Account
```bash POST /dropbox/2/users/get_current_account Content-Type: application/json
null ```
**Response:** ```json { "account_id": "dbid:AAA-AdT84WzkyLw5s590DbYF1nGomiAoO8I", "name": { "given_name": "John", "surname": "Doe", "familiar_name": "John", "display_name": "John Doe", "abbreviated_name": "JD" }, "email": "[email protected]", "email_verified": true, "disabled": false, "country": "US", "locale": "en", "account_type": { ".tag": "basic" }, "root_info": { ".tag": "user", "root_namespace_id": "11989877987", "home_namespace_id": "11989877987" } } ```
#### Get Space Usage
```bash POST /dropbox/2/users/get_space_usage Content-Type: application/json
null ```
**Response:** ```json { "used": 538371, "allocation": { ".tag": "individual", "allocated": 2147483648 } } ```
### Files and Folders
#### List Folder
```bash POST /dropbox/2/files/list_folder Content-Type: application/json
{ "path": "", "recursive": false, "include_deleted": false, "include_has_explicit_shared_members": false } ```
Use empty string `""` for the root folder.
**Optional Parameters:** - `recursive` - Include contents of subdirectories (default: false) - `include_deleted` - Include deleted files (default: false) - `include_media_info` - Include media info for photos/videos - `limit` - Maximum entries per response (1-2000)
**Response:** ```json { "entries": [ { ".tag": "file", "name": "document.pdf", "path_lower": "/document.pdf", "path_display": "/document.pdf", "id": "id:Awe3Av8A8YYAAAAAAAAABQ", "client_modified": "2026-02-09T19:58:12Z", "server_modified": "2026-02-09T19:58:13Z", "rev": "016311c063b4f8700000002caa704e3", "size": 538371, "is_downloadable": true, "content_hash": "6542845d7b65ffc5358ebaa6981d991bab9fda194afa48bd727fcbe9e4a3158b" }, { ".tag": "folder", "name": "Documents", "path_lower": "/documents", "path_display": "/Documents", "id": "id:Awe3Av8A8YYAAAAAAAAABw" } ], "cursor": "AAVqv-MUYFlM98b1QpFK6YaYC8L1s39lWjqbeqgWu4un...", "has_more": false } ```
#### Continue Listing Folder
```bash POST /dropbox/2/files/list_folder/continue Content-Type: application/json
{ "cursor": "AAVqv-MUYFlM98b1QpFK6YaYC8L1s39lWjqbeqgWu4un..." } ```
Use when `has_more` is true in the previous response.
#### Get Metadata
```bash POST /dropbox/2/files/get_metadata Content-Type: application/json
{ "path": "/document.pdf", "include_media_info": false, "include_deleted": false, "include_has_explicit_shared_members": false } ```
**Response:** ```json { ".tag": "file", "name": "document.pdf", "path_lower": "/document.pdf", "path_display": "/document.pdf", "id": "id:Awe3Av8A8YYAAAAAAAAABQ", "client_modified": "2026-02-09T19:58:12Z", "server_modified": "2026-02-09T19:58:13Z", "rev": "016311c063b4f8700000002caa704e3", "size": 538371, "is_downloadable": true, "content_hash": "6542845d7b65ffc5358ebaa6981d991bab9fda194afa48bd727fcbe9e4a3158b" } ```
#### Create Folder
```bash POST /dropbox/2/files/create_folder_v2 Content-Type: application/json
{ "path": "/New Folder", "autorename": false } ```
**Response:** ```json { "metadata": { "name": "New Folder", "path_lower": "/new folder", "path_display": "/New Folder", "id": "id:Awe3Av8A8YYAAAAAAAAABw" } } ```
#### Copy File or Folder
```bash POST /dropbox/2/files/copy_v2 Content-Type: application/json
{ "from_path": "/source/file.pdf", "to_path": "/destination/file.pdf", "autorename": false } ```
**Response:** ```json { "metadata": { ".tag": "file", "name": "file.pdf", "path_lower": "/destination/file.pdf", "path_display": "/destination/file.pdf", "id": "id:Awe3Av8A8YYAAAAAAAAACA" } } ```
#### Move File or Folder
```bash POST /dropbox/2/files/move_v2 Content-Type: application/json
{ "from_path": "/old/location/file.pdf", "to_path": "/new/location/file.pdf", "autorename": false } ```
**Response:** ```json { "metadata": { ".tag": "file", "name": "file.pdf", "path_lower": "/new/location/file.pdf", "path_display": "/new/location/file.pdf", "id": "id:Awe3Av8A8YYAAAAAAAAACA" } } ```
#### Delete File or Folder
```bash POST /dropbox/2/files/delete_v2 Content-Type: application/json
{ "path": "/file-to-delete.pdf" } ```
**Response:** ```json { "metadata": { ".tag": "file", "name": "file-to-delete.pdf", "path_lower": "/file-to-delete.pdf", "path_display": "/file-to-delete.pdf", "id": "id:Awe3Av8A8YYAAAAAAAAABQ" } } ```
#### Get Temporary Download Link
```bash POST /dropbox/2/files/get_temporary_link Content-Type: application/json
{ "path": "/document.pdf" } ```
**Response:** ```json { "metadata": { "name": "document.pdf", "path_lower": "/document.pdf", "path_display": "/document.pdf", "id": "id:Awe3Av8A8YYAAAAAAAAABQ", "size": 538371, "is_downloadable": true }, "link": "https://uc785ee484c03b6556c091ea4491.dl.dropboxusercontent.com/cd/0/get/..." } ```
The link is valid for 4 hours.
### Search
#### Search Files
```bash POST /dropbox/2/files/search_v2 Content-Type: application/json
{ "query": "document", "options": { "path": "", "max_results": 100, "file_status": "active", "filename_only": false } } ```
**Response:** ```json { "has_more": false, "matches": [ { "highlight_spans": [], "match_type": { ".tag": "filename" }, "metadata": { ".tag": "metadata", "metadata": { ".tag": "file", "name": "document.pdf", "path_display": "/document.pdf", "path_lower": "/document.pdf", "id": "id:Awe3Av8A8YYAAAAAAAAABw" } } } ] } ```
#### Continue Search
```bash POST /dropbox/2/files/search/continue_v2 Content-Type: application/json
{ "cursor": "..." } ```
### File Revisions
#### List Revisions
```bash POST /dropbox/2/files/list_revisions Content-Type: application/json
{ "path": "/document.pdf", "mode": "path", "limit": 10 } ```
**Response:** ```json { "is_deleted": false, "entries": [ { "name": "document.pdf", "path_lower": "/document.pdf", "path_display": "/document.pdf", "id": "id:Awe3Av8A8YYAAAAAAAAABQ", "client_modified": "2026-02-09T19:58:12Z", "server_modified": "2026-02-09T19:58:13Z", "rev": "016311c063b4f8700000002caa704e3", "size": 538371, "is_downloadable": true } ], "has_more": false } ```
#### Restore File
```bash POST /dropbox/2/files/restore Content-Type: application/json
{ "path": "/document.pdf", "rev": "016311c063b4f8700000002caa704e3" } ```
### Tags
#### Get Tags
```bash POST /dropbox/2/files/tags/get Content-Type: application/json
{ "paths": ["/document.pdf", "/folder"] } ```
**Response:** ```json { "paths_to_tags": [ { "path": "/document.pdf", "tags": [ { ".tag": "user_generated_tag", "tag_text": "important" } ] }, { "path": "/folder", "tags": [] } ] } ```
#### Add Tag
```bash POST /dropbox/2/files/tags/add Content-Type: application/json
{ "path": "/document.pdf", "tag_text": "important" } ```
Returns `null` on success.
**Note:** Tag text must match pattern `[\w]+` (alphanumeric and underscores only, no hyphens or spaces).
#### Remove Tag
```bash POST /dropbox/2/files/tags/remove Content-Type: application/json
{ "path": "/document.pdf", "tag_text": "important" } ```
Returns `null` on success.
### Batch Operations
#### Delete Batch
```bash POST /dropbox/2/files/delete_batch Content-Type: application/json
{ "entries": [ {"path": "/file1.pdf"}, {"path": "/file2.pdf"} ] } ```
Returns async job ID. Check status with `/files/delete_batch/check`.
#### Copy Batch
```bash POST /dropbox/2/files/copy_batch_v2 Content-Type: application/json
{ "entries": [ {"from_path": "/source/file1.pdf", "to_path": "/dest/file1.pdf"}, {"from_path": "/source/file2.pdf", "to_path": "/dest/file2.pdf"} ], "autorename": false } ```
#### Move Batch
```bash POST /dropbox/2/files/move_batch_v2 Content-Type: application/json
{ "entries": [ {"from_path": "/old/file1.pdf", "to_path": "/new/file1.pdf"}, {"from_path": "/old/file2.pdf", "to_path": "/new/file2.pdf"} ], "autorename": false } ```
## Pagination
Dropbox uses cursor-based pagination. When `has_more` is true, use the `/continue` endpoint with the returned cursor.
```python import os import requests
headers = { 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/json' }
# Initial request response = requests.post( 'https://gateway.maton.ai/dropbox/2/files/list_folder', headers=headers, json={'path': '', 'limit': 100} ) result = response.json() all_entries = result['entries']
# Continue while has_more is True while result.get('has_more'): response = requests.post( 'https://gateway.maton.ai/dropbox/2/files/list_folder/continue', headers=headers, json={'cursor': result['cursor']} ) result = response.json() all_entries.extend(result['entries'])
print(f"Total entries: {len(all_entries)}") ```
## Code Examples
### JavaScript
```javascript const response = await fetch( 'https://gateway.maton.ai/dropbox/2/files/list_folder', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ path: '' }) } ); const data = await response.json(); console.log(data.entries); ```
### Python
```python import os import requests
response = requests.post( 'https://gateway.maton.ai/dropbox/2/files/list_folder', headers={ 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/json' }, json={'path': ''} ) data = response.json() print(data['entries']) ```
### Python (Create Folder and Search)
```python import os import requests
headers = { 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/json' }
# Create folder response = requests.post( 'https://gateway.maton.ai/dropbox/2/files/create_folder_v2', headers=headers, json={'path': '/My New Folder', 'autorename': False} ) folder = response.json() print(f"Created folder: {folder['metadata']['path_display']}")
# Search for files response = requests.post( 'https://gateway.maton.ai/dropbox/2/files/search_v2', headers=headers, json={'query': 'document'} ) results = response.json() print(f"Found {len(results['matches'])} matches") ```
## Notes
- All Dropbox API v2 endpoints use HTTP POST method - Request bodies are JSON (not form-urlencoded) - Use empty string `""` for the root folder path - Paths are case-insensitive but case-preserving - File IDs (e.g., `id:Awe3Av8A8YYAAAAAAAAABQ`) persist even when files are moved or renamed - Tag text must match pattern `[\w]+` (alphanumeric and underscores only) - Temporary download links expire after 4 hours - Rate limits are generous and per-user - IMPORTANT: When piping curl output to `jq` or other commands, environment variables like `$MATON_API_KEY` may not expand correctly in some shell environments
## Error Handling
| Status | Meaning | |--------|---------| | 400 | Missing Dropbox connection or bad request | | 401 | Invalid or missing Maton API key | | 404 | Resource not found | | 409 | Conflict (path doesn't exist, already exists, etc.) | | 429 | Rate limited | | 4xx/5xx | Passthrough error from Dropbox API |
Error responses include details: ```json { "error_summary": "path/not_found/...", "error": { ".tag": "path", "path": { ".tag": "not_found" } } } ```
### Troubleshooting: Invalid API Key
**When you receive an "Invalid API key" error, ALWAYS follow these steps before concluding there is an issue:**
1. Check that the `MATON_API_KEY` environment variable is set:
```bash echo $MATON_API_KEY ```
2. Verify the API key is valid by listing connections:
```bash 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 ```
## Resources
- [Dropbox HTTP API Overview](https://www.dropbox.com/developers/documentation/http/overview) - [Dropbox Developer Portal](https://www.dropbox.com/developers) - [Dropbox API Explorer](https://dropbox.github.io/dropbox-api-v2-explorer/) - [DBX File Access Guide](https://developers.dropbox.com/dbx-file-access-guide)