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
Configure App
Choose “Scoped access”
Choose “Full Dropbox” or “App folder” access
Name your app and create it
Get Credentials
Copy your App key (client ID)
Copy your App secret (client secret)
Add your redirect URI to “OAuth 2 Redirect URIs”
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
Generate Authorization URL
public function connect ( Dropbox $dropbox )
{
$authUrl = $dropbox -> getAuthorizationUrl ();
return redirect ( $authUrl );
}
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!' ));
});
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"
}
]
// 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' ];
}
}
$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 Shared Link
// 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
);
Example Shared Link Response
{
".tag" : "file" ,
"url" : "https://www.dropbox.com/s/abc123/presentation.pdf?dl=0" ,
"name" : "presentation.pdf" ,
"path_lower" : "/documents/presentation.pdf" ,
"link_permissions" : {
"can_revoke" : true ,
"resolved_visibility" : "public"
}
}
List Shared Links
// 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
Resource Methods Description 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'
);
}
}
}
Generate Download Link
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:
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