Skip to main content
A comprehensive Dropbox API integration using OAuth 2.0 Authorization Code Grant flow for secure file storage, sharing, and management.

Features

OAuth 2.0 Flow

Secure authorization with automatic token refresh

File Operations

Upload, download, move, copy, delete files and folders

Sharing

Create and manage shared links

Pagination

Cursor-based pagination for large datasets

Configuration

Add your Dropbox app credentials to your .env file:
DROPBOX_CLIENT_ID=your_app_key
DROPBOX_CLIENT_SECRET=your_app_secret
DROPBOX_REDIRECT_URI=https://your-app.com/dropbox/callback

Getting Your Credentials

1

Create Dropbox App

Go to Dropbox App Console and click “Create app”
2

Configure App

  • Choose “Scoped access”
  • Choose “Full Dropbox” or “App folder” access
  • Name your app and create it
3

Get Credentials

  • Copy your App key (client ID)
  • Copy your App secret (client secret)
  • Add your redirect URI to “OAuth 2 Redirect URIs”
4

Add to Environment

Add credentials to your .env file
Keep your app secret secure and never commit it to version control.

Laravel Integration

Service Container Registration

Register Dropbox as a singleton in your AppServiceProvider:
use Inly\Core\Connectors\Dropbox\Dropbox;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(Dropbox::class, function ($app) {
            return new Dropbox();
        });
    }
}
The stub file at vendor/inly/core/stubs/laravel/app/Providers/AppServiceProvider.php contains a commented example for Dropbox registration.

OAuth 2.0 Authorization

Authorization Flow

1

Generate Authorization URL

public function connect(Dropbox $dropbox)
{
    $authUrl = $dropbox->getAuthorizationUrl();
    return redirect($authUrl);
}
2

Handle Callback

Route::get('/dropbox/callback', function (Request $request, Dropbox $dropbox) {
    $code = $request->get('code');
    $state = $request->get('state');
    
    // Exchange authorization code for access token
    $dropbox->handleCallback($code, $state);
    
    return redirect('/dashboard')->withSuccess(__('Dropbox connected!'));
});
3

Use the SDK

// Token is now stored and will be used automatically
$files = $dropbox->files()->listFolder('/Documents');

Token Storage

Tokens are automatically stored in a JSON file (default: dropbox-storage.json) and refreshed when expired. The SDK handles this automatically.

Check Configuration

if ($dropbox->isConfigured()) {
    // SDK has a valid access token
    $files = $dropbox->files()->listFolder('');
} else {
    // Redirect to authorization
    return redirect($dropbox->getAuthorizationUrl());
}

Files

Manage files and folders in Dropbox.

List Folder Contents

// List files in root folder
$files = $dropbox->files()->listFolder('');

// List files in a specific folder
$files = $dropbox->files()->listFolder('/Documents');

// List recursively (includes subfolders)
$files = $dropbox->files()->listFolder('/Documents', recursive: true);

foreach ($files as $file) {
    echo $file['.tag'];         // 'file' or 'folder'
    echo $file['name'];
    echo $file['path_display'];
}
[
  {
    ".tag": "file",
    "name": "document.pdf",
    "path_display": "/Documents/document.pdf",
    "client_modified": "2024-01-15T10:30:00Z",
    "server_modified": "2024-01-15T10:30:00Z",
    "size": 1024000,
    "content_hash": "abc123..."
  },
  {
    ".tag": "folder",
    "name": "Invoices",
    "path_display": "/Documents/Invoices"
  }
]

Manual Pagination

// For large folders, use manual pagination
$paginator = $dropbox->files()->paginateFolder('/Documents');

foreach ($paginator as $response) {
    $entries = $response->json('entries', []);
    
    foreach ($entries as $file) {
        // Process each file
        echo $file['name'];
    }
}

Get File/Folder Metadata

$metadata = $dropbox->files()->getMetadata('/Documents/report.pdf');

echo $metadata['.tag'];           // 'file' or 'folder'
echo $metadata['name'];           // 'report.pdf'
echo $metadata['path_display'];   // '/Documents/report.pdf'
echo $metadata['size'];           // File size in bytes
echo $metadata['content_hash'];   // Hash for change detection

Upload File

// Upload from file contents
$contents = file_get_contents('/path/to/local/file.pdf');

$result = $dropbox->files()->upload(
    path: '/Documents/report.pdf',
    contents: $contents,
    mode: 'add',        // 'add', 'overwrite', 'update'
    autorename: false   // Auto-rename if file exists
);

echo $result['id'];
echo $result['name'];
echo $result['path_display'];
Upload Modes:
  • add - Fail if file exists
  • overwrite - Replace existing file
  • update - Update specific revision

Download File

// Download file contents
$contents = $dropbox->files()->download('/Documents/report.pdf');

// Save to local file
file_put_contents('/path/to/local/report.pdf', $contents);

// Or return as download response
return response($contents, 200, [
    'Content-Type' => 'application/pdf',
    'Content-Disposition' => 'attachment; filename="report.pdf"',
]);

Create Folder

$result = $dropbox->files()->createFolder('/Documents/2024');

// With auto-rename if folder exists
$result = $dropbox->files()->createFolder(
    path: '/Documents/Archive',
    autorename: true
);

Move File or Folder

// Move file
$result = $dropbox->files()->move(
    fromPath: '/Documents/old-name.pdf',
    toPath: '/Archive/new-name.pdf'
);

// Move with auto-rename if destination exists
$result = $dropbox->files()->move(
    fromPath: '/Documents/report.pdf',
    toPath: '/Archive/report.pdf',
    autorename: true
);

Copy File or Folder

// Copy file
$result = $dropbox->files()->copy(
    fromPath: '/Documents/original.pdf',
    toPath: '/Backup/copy.pdf'
);

// Copy folder with all contents
$result = $dropbox->files()->copy(
    fromPath: '/Documents/Projects',
    toPath: '/Backup/Projects'
);

Delete File or Folder

// Delete file
$result = $dropbox->files()->delete('/Documents/old-file.pdf');

// Delete folder (deletes all contents)
$result = $dropbox->files()->delete('/Documents/OldProjects');
Deleting a folder will permanently delete all files and subfolders within it. This action cannot be undone.

Search Files

// Search in entire Dropbox
$results = $dropbox->files()->search('invoice');

// Search in specific folder
$results = $dropbox->files()->search(
    query: 'invoice',
    path: '/Documents'
);

// Search with max results
$results = $dropbox->files()->search(
    query: 'contract',
    path: '/Legal',
    maxResults: 50
);

foreach ($results as $file) {
    echo $file['name'];
    echo $file['path_display'];
    echo $file['.tag'];
}

Sharing

Create and manage shared links for files and folders.
// Create a shared link
$link = $dropbox->sharing()->createSharedLink('/Documents/presentation.pdf');

echo $link['url'];  // Share this URL
echo $link['name'];

// Create a short URL
$link = $dropbox->sharing()->createSharedLink(
    path: '/Documents/report.pdf',
    shortUrl: true
);
// List all shared links
$links = $dropbox->sharing()->listSharedLinks();

// List shared links for specific path
$links = $dropbox->sharing()->listSharedLinks('/Documents/report.pdf');

foreach ($links as $link) {
    echo $link['url'];
    echo $link['name'];
    echo $link['path_lower'];
}

Users

Get information about the authenticated user.

Get Current Account

$account = $dropbox->users()->getCurrentAccount();

echo $account['account_id'];
echo $account['name']['display_name'];
echo $account['email'];
echo $account['email_verified'];
echo $account['profile_photo_url'];
{
  "account_id": "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc",
  "name": {
    "given_name": "John",
    "surname": "Doe",
    "familiar_name": "John",
    "display_name": "John Doe"
  },
  "email": "john@example.com",
  "email_verified": true,
  "disabled": false,
  "country": "US",
  "profile_photo_url": "https://..."
}

Get Space Usage

$spaceUsage = $dropbox->users()->getSpaceUsage();

$usedBytes = $spaceUsage['used'];
$allocatedBytes = $spaceUsage['allocation']['allocated'];

// Convert to GB
$usedGB = round($usedBytes / 1024 / 1024 / 1024, 2);
$totalGB = round($allocatedBytes / 1024 / 1024 / 1024, 2);

echo "Using {$usedGB} GB of {$totalGB} GB";

Available Resources

ResourceMethodsDescription
files()listFolder(), getMetadata(), upload(), download(), delete(), createFolder(), move(), copy(), search(), paginateFolder()File and folder operations
sharing()createSharedLink(), listSharedLinks()Sharing management
users()getCurrentAccount(), getSpaceUsage()User information

Error Handling

The SDK automatically throws exceptions for API errors. Wrap API calls in try-catch blocks:
use Saloon\Exceptions\Request\RequestException;

try {
    $files = $dropbox->files()->listFolder('/Documents');
} catch (RequestException $e) {
    $statusCode = $e->getResponse()->status();
    $errorMessage = $e->getResponse()->json('error_summary');
    
    if ($statusCode === 409) {
        // Path not found or other conflict
        Log::warning("Dropbox path error: {$errorMessage}");
    } else {
        Log::error("Dropbox API error: {$errorMessage}");
    }
}

Common Use Cases

Backup User Files

use Inly\Core\Connectors\Dropbox\Dropbox;

class BackupUserFilesJob
{
    public function __construct(
        protected Dropbox $dropbox
    ) {}

    public function handle(User $user): void
    {
        // Create user backup folder
        $backupPath = "/Backups/{$user->id}";
        
        try {
            $this->dropbox->files()->createFolder($backupPath);
        } catch (RequestException $e) {
            // Folder might already exist
        }
        
        // Upload user documents
        foreach ($user->documents as $document) {
            $contents = file_get_contents($document->path);
            
            $this->dropbox->files()->upload(
                path: "{$backupPath}/{$document->filename}",
                contents: $contents,
                mode: 'overwrite'
            );
        }
    }
}
public function shareDocument(Document $document, Dropbox $dropbox)
{
    // Upload to Dropbox if not already there
    if (!$document->dropbox_path) {
        $contents = file_get_contents($document->local_path);
        
        $result = $dropbox->files()->upload(
            path: "/Shared/{$document->filename}",
            contents: $contents
        );
        
        $document->update([
            'dropbox_path' => $result['path_display']
        ]);
    }
    
    // Create shared link
    $link = $dropbox->sharing()->createSharedLink($document->dropbox_path);
    
    return $link['url'];
}

Sync Local Directory

public function syncDirectory(string $localPath, string $dropboxPath, Dropbox $dropbox): void
{
    // Create remote folder if needed
    try {
        $dropbox->files()->createFolder($dropboxPath);
    } catch (RequestException $e) {
        // Folder exists
    }
    
    // Get local files
    $files = glob($localPath . '/*');
    
    foreach ($files as $file) {
        if (is_file($file)) {
            $filename = basename($file);
            $contents = file_get_contents($file);
            
            $dropbox->files()->upload(
                path: "{$dropboxPath}/{$filename}",
                contents: $contents,
                mode: 'overwrite'
            );
        }
    }
}

Testing

Test your Dropbox integration:
php artisan test:dropbox
This will:
  • ✅ Check if SDK is configured
  • ✅ Display authorization URL if needed
  • ✅ Fetch account information
  • ✅ Show space usage
  • ✅ List files in root folder

Rate Limiting

Dropbox enforces rate limits per app:
  • Individual users: 600 requests per user per app
  • App-wide: varies by tier
The SDK will receive 429 Too Many Requests errors when limits are exceeded. Implement exponential backoff for retries.

Additional Resources