Learn how to make the most out of the Dropbox Community here 💙.
API
5792 TopicsSlow playback when streaming with AVPlayer
We’re building an iOS App that streams mp4 video files from DropBox. We use SDK’s getTemporaryLink method and feed the returned URL to AVPlayer(url: …). The streaming doesn’t start until after a few seconds/minutes depending on the size of the file. Same issue when opening this link in a regular Safari tab. When opening the file directly in Dropbox website the video plays fine.131Views1like13CommentsOTA update fails in CC3200
Hi All, We are using the Dropbox API to do an OTA upgrade. We have a webclient application running on the TI microcontroller CC3200. We are using the Drop Box API from 2017 onwards, and it is working fine. When we tested the OTA functionality yesterday, it was unable to receive the CDN file URL. It is able to receive the file information from Dropbox but is unable to get the temporary link from Dropbox. Do you know what is causing this issue? Is there any recent API upgrade that has failed to respond? Please help us to fix this issue ASAP. TI CC3200 logs: sl_extLib_OtaRun: call OtaClient_ConnectServer OTA server=api.dropbox.com OtaClient_ConnectServer: http_connect_server api.dropbox.com 0 OTA run = 0 sl_extLib_OtaRun: OtaClient_UpdateCheck, vendorStr=Vid01_Pid00_Ver0302100000 OtaClient_UpdateCheck: call http_build_request /1/metadata/auto/ CdnDropbox_SendReqDir: uri=/2/files/list_folder metadata file=/Vid01_Pid00_Ver0302100000/f80_sys_mcuimgA.bin, size=142888 sl_extLib_OtaRun: OtaClient_UpdateCheck, numUpdates=1 0 OTA run = 0 sl_extLib_OtaRun: OtaClient_GetNextUpdate: file=/Vid01_Pid00_Ver0302100000/f80_sys_mcuimgA.bin, size=142888 OtaClient_ResourceMetadata: call http_build_request /1/media/auto OtaClient_ResourceMetadata: file flags=80,metadata flags=80 CdnDropbox_SendReqFileUrl: uri=/2/files/get_temporary_link 0 OTA run = 0 sl_extLib_OtaRun: ResourceMetadata CDN file URL = f= CdnClient_ConnectByUrl: ERROR, http_extract_domain_by_url, status=-1 sl_extLib_OtaRun ERROR: Failed on CdnClient_ConnectByUrl 0 OTA run = -6 OTA run = -6 OTA: Error with OTA server Regards, Sundar11KViews0likes68CommentsI need to get all folders and nested folders within a team
Hi team! For an app we are making we need to access all folders and subfolders in a dropbox team. Just the folder names, however when calling. /2/team/team_folder/list Im only getting the top level folders, not getting the subfolders. And when calling 2/sharing/list_folders Im not getting any cursor as a response, just a list that includes around 5% of all my folders, even setting the limit to 1000 I dont get more than that. Do you know how to solve this? Thanks, Andres55Views0likes3CommentsRegarding the folder identifiers that are the same across users who share the folder
I need an identifier that will be the same across users who share the folder. After investigating "/2/files/list_folder" API, we were able to confirm the following: For folders for which a "shared_folder_id" can be obtained, the "id" values seen by each user are different but the "shared_folder_id" values are the same. For folders for which a "shared_folder_id" cannot be obtained (folders for which a "parent_shared_folder_id" can be obtained), the "id" values seen by each user are the same. Are the above findings guaranteed by the Dropbox API specification ? Thank you for your support.87Views0likes5CommentsWhat's the actual issue with Apple FileProviders API
I'm trying to reply to this post https://www.dropboxforum.com/discussions/101001016/dropbox-on-file-provider-support-for-macos-questions/781551/replies/783389 but in a dropbox fashion "Replies have been turned off for this discussion": billgdbx can you explain exactly what is the exact issue with the Apple FileProvider API for a software engineer? What exactly does "download-on-demand" mean compared to the download now button I see in macOS finder? When I briefly read the API docs, it seems like the API should be enough; however, I've read many blog posts mentioning that the problem lies with Apple and not with Dropbox/Google/Microsoft. All these posts are blanket statements without any technical details. I'm looking for the hardcore facts, not opinions. I want to know whether I should consider ditching apple? Or dropbox? If there is an issue at apple's side - I want to know what it actually is so I can make my own decisions rather than being treated like an idiot and a fool. In my experience, dropbox announces all breaking changes to customer as ultimatums without any true explanation. Now that I think about it... it is actually coming from disrespect and even contempt to your customers.30Views0likes2Commentslist_shared_links API inconsistency with team folders: Only showing edit OR view link, not both
I'm encountering an unexpected behavior with the list_shared_links API (https://api.dropboxapi.com/2/sharing/list_shared_links) when working with team folders. I hope someone can provide clarification. Issue: When listing shared links for a team folder that has both edit and view links: 1. If both edit and view links exist, only the edit link is returned in the API response. 2. If I remove the edit link manually, then only the view link is returned. But, if I pass the specific path it return both links Details: - I'm using a team access token. - I'm passing the 'Dropbox-API-Path-Root' header to list all team space shared links. Expected behavior: Based on the API documentation, I expected to see all shared links returned. The docs state: "If no path is given, returns a list of all shared links for the current user. For members of business teams using team space and member folders, returns all shared links in the team member's home folder unless the team space ID is specified in the request header." Steps to reproduce: 1. Create both an edit and a view link for a team folder in Dropbox. 2. Use the list_shared_links API with a team access token and the 'Dropbox-API-Path-Root' header, without specifying a path in the body. 3. Observe that only the edit link is returned. 4. Manually remove the edit link for the folder via the Dropbox dashboard. 5. Use the list_shared_links API again with the same parameters. 6. Observe that now only the view link is returned. Questions: 1. Is this the intended behavior of the API for team folders? 2. If so, is there a way to retrieve both edit and view links for team folders in a single API call without specifying the path? 3. If not, is this a known issue specific to team folders, and is there a workaround or fix planned? 4. Does this behavior differ between team folders and personal folders? Any clarification on this would be greatly appreciated, especially regarding how the API is supposed to handle multiple link types for team folders. Thank you!330Views0likes5CommentsUnable to Retrieve Dropbox "path_display" for Folders in Google Sheets Script
I'm developing a Google Sheets database that feeds an interactive map on My Maps. The script uses the Dropbox API to update folder names (in column A) and folder paths (in column F) based on metadata retrieved from Dropbox shared links. Although every folder is mounted on my account and I have full administrative rights on my Dropbox team, I'm not seeing the expected "path_display" value for my Dropbox folders. The script calls several API endpoints (such as sharing/get_shared_link_metadata, sharing/list_folders, sharing/list_mountable_folders, and sharing/get_folder_metadata) to try to obtain the complete folder path, but the path_display property remains empty in my sheet. I need to retrieve path_display because it lets me move folders in Dropbox while still keeping the most recent path in my map. The script is set to run weekly so that any folder moves are captured and my map stays up to date. Below is the complete script (with sensitive credentials, paths, and other details replaced): I tried this script in Google Apps Script: ``` // ===================================================== // CONFIGURATION & CONSTANTS // ===================================================== // Google Maps API Key (for geocoding) const API_KEY = "YOUR_GOOGLE_MAPS_API_KEY"; // OAuth2 Dropbox: Replace with your Dropbox credentials const DROPBOX_CLIENT_ID = 'YOUR_DROPBOX_CLIENT_ID'; const DROPBOX_CLIENT_SECRET = 'YOUR_DROPBOX_CLIENT_SECRET'; const DROPBOX_SCOPES = 'sharing.read files.metadata.read files.team_metadata.read team_data.member'; // Replace with your Dropbox team member ID (the member on which you want to operate) // Example: "dbmid:example_member_id" const DROPBOX_TEAM_MEMBER_ID = 'YOUR_DROPBOX_TEAM_MEMBER_ID'; const BATCH_SIZE = 100; const DELAY_BETWEEN_REQUESTS = 1000; // ===================================================== // OAUTH2 FOR DROPBOX (using the OAuth2 library) // ===================================================== function getDropboxService() { return OAuth2.createService('Dropbox') .setAuthorizationBaseUrl('https://www.dropbox.com/oauth2/authorize') .setTokenUrl('https://api.dropboxapi.com/oauth2/token') .setClientId(DROPBOX_CLIENT_ID) .setClientSecret(DROPBOX_CLIENT_SECRET) .setCallbackFunction('authCallback') .setPropertyStore(PropertiesService.getUserProperties()) .setScope(DROPBOX_SCOPES) // Request a refresh token .setParam('token_access_type', 'offline'); } function authCallback(request) { const service = getDropboxService(); const authorized = service.handleCallback(request); return HtmlService.createHtmlOutput(authorized ? 'Success! You can close this tab.' : 'Access denied.'); } function authorizeDropbox() { const service = getDropboxService(); if (!service.hasAccess()) { const authorizationUrl = service.getAuthorizationUrl(); Logger.log('Open the following URL and authorize the app, then re-run the script: %s', authorizationUrl); return authorizationUrl; } else { Logger.log('Already authorized with Dropbox.'); } } // ===================================================== // FUNCTIONS FOR UPDATING COORDINATES // ===================================================== function updateCoordinates() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const startRow = 4; const addresses = sheet.getRange(`B${startRow}:B${sheet.getLastRow()}`).getValues().flat(); const gpsData = sheet.getRange(`D${startRow}:D${sheet.getLastRow()}`).getValues().flat(); addresses.forEach((address, index) => { const gps = gpsData[index]; if (address && !gps) { const coordinates = getCoordinates(address); if (coordinates) { sheet.getRange(index + startRow, 4).setValue(coordinates); } } }); SpreadsheetApp.flush(); } function getCoordinates(address) { const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${API_KEY}`; try { const response = UrlFetchApp.fetch(url); const json = JSON.parse(response.getContentText()); if (json.status === "OK") { const latitude = json.results[0].geometry.location.lat; const longitude = json.results[0].geometry.location.lng; return `${latitude}, ${longitude}`; } else { console.error(`API error for address: ${address} - Status: ${json.status}`); return "API error"; } } catch (error) { console.error(`Error fetching coordinates: ${error.message}`); return "API error"; } } // ===================================================== // FUNCTIONS FOR UPDATING STATUS (column E) FROM PATHS (column F) // ===================================================== function updateStatusFromPaths() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const startRow = 4; const lastRow = sheet.getLastRow(); const paths = sheet.getRange(`F${startRow}:F${lastRow}`).getValues().flat(); const statuses = []; paths.forEach(path => { if (path) { if (path.includes("ActiveDeals/Active") || path.includes("C:\\Path\\To\\ActiveDeals\\Active")) { statuses.push(["Active"]); } else if (path.includes("ActiveDeals/ToWatch") || path.includes("C:\\Path\\To\\ActiveDeals\\ToWatch")) { statuses.push(["To watch"]); } else if (path.includes("Properties/Owned") || path.includes("C:\\Path\\To\\Properties\\Owned")) { statuses.push(["Owned"]); } else if (path.includes("Properties/Sold") || path.includes("C:\\Path\\To\\Properties\\Sold")) { statuses.push(["Sold"]); } else if (path.includes("DeadDeals") || path.includes("C:\\Path\\To\\DeadDeals")) { statuses.push(["Dead"]); } else { statuses.push(["Undefined"]); } } else { statuses.push([""]); } }); sheet.getRange(startRow, 5, statuses.length, 1).setValues(statuses); } // ===================================================== // FUNCTIONS FOR UPDATING DROPBOX INFORMATION // ===================================================== /** * This script updates both the folder name (column A) * and the folder path (column F) by comparing the path_display returned * by Dropbox. Any changes are logged in column H. */ function updateFolderNamesInBatches() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const startRow = 4; const lastRow = sheet.getLastRow(); const scriptProperties = PropertiesService.getScriptProperties(); let batchIndex = parseInt(scriptProperties.getProperty('batchIndexDropbox') || '0'); const totalBatches = Math.ceil((lastRow - startRow + 1) / BATCH_SIZE); // If all batches have been processed, reset and stop if (batchIndex >= totalBatches) { scriptProperties.deleteProperty('batchIndexDropbox'); Logger.log("All batches processed. Function stopped."); return; } const batchStart = startRow + (batchIndex * BATCH_SIZE); const batchEnd = Math.min(batchStart + BATCH_SIZE - 1, lastRow); // Check if the batch contains any sharing links (Column C) const linksRange = sheet.getRange(`C${batchStart}:C${batchEnd}`).getValues(); let hasLink = false; for (let i = 0; i < linksRange.length; i++) { if (linksRange[i][0].toString().trim() !== "") { hasLink = true; break; } } // If no links are found in the batch, stop processing if (!hasLink) { scriptProperties.deleteProperty('batchIndexDropbox'); Logger.log("No sharing links found in batch. Function stopped."); return; } // Clear previous statuses for the current batch (Column H) sheet.getRange(`H${batchStart}:H${batchEnd}`).clearContent(); // Process the current batch updateBatch(batchStart, batchEnd); // Update the batch index batchIndex++; scriptProperties.setProperty('batchIndexDropbox', batchIndex.toString()); // Schedule the next batch if there are more rows to process if (batchIndex < totalBatches) { ScriptApp.newTrigger('updateFolderNamesInBatches') .timeBased() .after(1000) .create(); } } /** * Processes the rows in the batch, * compares existing names/paths with those returned by Dropbox, and updates if necessary. */ function updateBatch(startRow, endRow) { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); // Read columns A (folderNames), C (sharingLinks) and F (folderPaths) const folderNames = sheet.getRange(`A${startRow}:A${endRow}`).getValues().flat(); const sharingLinks = sheet.getRange(`C${startRow}:C${endRow}`).getValues().flat(); const folderPaths = sheet.getRange(`F${startRow}:F${endRow}`).getValues().flat(); for (let index = 0; index < sharingLinks.length; index++) { const link = sharingLinks[index]; const currentRow = startRow + index; // Skip if the link is empty if (!link || link.trim() === "") { Logger.log(`Stopping at row ${currentRow}: No sharing link found.`); return; } try { const metadata = getDropboxMetadata(link); let statusMessages = []; if (metadata && metadata.name) { // Compare folder name if (folderNames[index] !== metadata.name) { sheet.getRange(currentRow, 1).setValue(metadata.name); statusMessages.push("Folder name updated"); } // Compare folder path if (metadata.path && folderPaths[index] !== metadata.path) { sheet.getRange(currentRow, 6).setValue(metadata.path); statusMessages.push("Path updated"); } if (statusMessages.length === 0) { statusMessages.push("No changes needed"); } sheet.getRange(currentRow, 8).setValue(statusMessages.join(" | ")); } else { sheet.getRange(currentRow, 8).setValue("Failed: No metadata/name"); } } catch (err) { sheet.getRange(currentRow, 8).setValue("Failed: " + err.message); } // Delay to respect rate limits Utilities.sleep(DELAY_BETWEEN_REQUESTS); } SpreadsheetApp.flush(); } /** * getDropboxMetadata retrieves the name and path_display * from the Dropbox sharing link. * * It uses multiple methods to try to obtain the full path, * handling various limitations of the Dropbox API. */ function getDropboxMetadata(sharingLink) { const service = getDropboxService(); if (!service.hasAccess()) { throw new Error("Authorization required. Run authorizeDropbox() first."); } const accessToken = service.getAccessToken(); // First call to sharing/get_shared_link_metadata let apiUrl = "https://api.dropboxapi.com/2/sharing/get_shared_link_metadata"; let payload = { url: sharingLink }; let options = { method: "post", contentType: "application/json", headers: { Authorization: "Bearer " + accessToken, "Dropbox-API-Select-User": DROPBOX_TEAM_MEMBER_ID }, payload: JSON.stringify(payload), muteHttpExceptions: true }; let response = UrlFetchApp.fetch(apiUrl, options); let responseText = response.getContentText(); Logger.log("API Response for " + sharingLink + ": " + responseText); let json; try { json = JSON.parse(responseText); } catch (e) { throw new Error("Invalid JSON response: " + responseText); } if (json.error_summary) { throw new Error("Dropbox API error: " + json.error_summary); } // For shared folders, try a different approach to get the path if (!json.path_display && json['.tag'] === 'folder' && json.id) { // Try with sharing/list_folders endpoint if it's a shared folder apiUrl = "https://api.dropboxapi.com/2/sharing/list_folders"; payload = { limit: 100 }; options.payload = JSON.stringify(payload); try { response = UrlFetchApp.fetch(apiUrl, options); responseText = response.getContentText(); Logger.log("List Folders API Response: " + responseText); const listFolders = JSON.parse(responseText); if (listFolders.entries && listFolders.entries.length > 0) { // Look for matching entry by shared_folder_id const matchingFolder = listFolders.entries.find(folder => folder.shared_folder_id === json.id.replace('id:', '') ); if (matchingFolder && matchingFolder.path_lower) { json.path_display = matchingFolder.path_lower; } } } catch (e) { Logger.log("Fallback list_folders method failed: " + e.message); } // If still no path_display, try with list_mountable_folders if (!json.path_display) { apiUrl = "https://api.dropboxapi.com/2/sharing/list_mountable_folders"; payload = { limit: 100 }; options.payload = JSON.stringify(payload); try { response = UrlFetchApp.fetch(apiUrl, options); responseText = response.getContentText(); Logger.log("List Mountable Folders API Response: " + responseText); const listFolders = JSON.parse(responseText); if (listFolders.entries && listFolders.entries.length > 0) { // Look for matching entry by shared_folder_id const matchingFolder = listFolders.entries.find(folder => folder.shared_folder_id === json.id.replace('id:', '') ); if (matchingFolder && matchingFolder.path_lower) { json.path_display = matchingFolder.path_lower; } } } catch (e) { Logger.log("Fallback list_mountable_folders method failed: " + e.message); } } // Try one more approach with sharing/get_folder_metadata if (!json.path_display) { apiUrl = "https://api.dropboxapi.com/2/sharing/get_folder_metadata"; payload = { shared_folder_id: json.id.replace('id:', '') }; options.payload = JSON.stringify(payload); try { response = UrlFetchApp.fetch(apiUrl, options); responseText = response.getContentText(); Logger.log("Get Folder Metadata API Response: " + responseText); const folderMetadata = JSON.parse(responseText); if (folderMetadata.path_lower) { json.path_display = folderMetadata.path_lower; } } catch (e) { Logger.log("Fallback get_folder_metadata method failed: " + e.message); } } } return { name: json.name || "", path: json.path_display || "" }; } function startFolderNameUpdate() { PropertiesService.getScriptProperties().setProperty("batchIndexDropbox", "0"); updateFolderNamesInBatches(); } // ===================================================== // SETUP TRIGGERS // ===================================================== function setupTriggers() { // Delete all existing triggers. ScriptApp.getProjectTriggers().forEach(function(trigger) { ScriptApp.deleteTrigger(trigger); }); // Trigger on change to update coordinates. ScriptApp.newTrigger("updateCoordinates") .forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()) .onChange() .create(); // Trigger on change to update statuses from paths. ScriptApp.newTrigger("updateStatusFromPaths") .forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()) .onChange() .create(); // Time-based trigger to update Dropbox folder names & paths in batches (every Monday at 15:00). ScriptApp.newTrigger("updateFolderNamesInBatches") .timeBased() .onWeekDay(ScriptApp.WeekDay.MONDAY) .atHour(15) .create(); Logger.log("Triggers set: onChange for updateCoordinates and updateStatusFromPaths; weekly for updateFolderNamesInBatches."); } // Function to manually reset the batch index. function resetBatchIndex() { PropertiesService.getScriptProperties().deleteProperty('batchIndexDropbox'); Logger.log("Batch index reset to start from the beginning (row 4)"); } // Function to reset old Dropbox credentials. function resetDropboxAuth() { PropertiesService.getUserProperties().deleteAllProperties(); Logger.log("Dropbox authorization reset. Re-run authorizeDropbox()."); } ``` Typical Log Output: Here are examples of the log messages I typically see when the script runs: API Response Log: `3 March 2025, 15:10:42 Info API Response for https://www.dropbox.com/scl/fo/REPLACE_URL?dl=0: {"tag": "folder", "url": "https://www.dropbox.com/scl/fo/REPLACE_URL?dl=0", "id": "id:REPLACE_ID", "name": "REPLACE_NAME", "link_permissions": { ... }, "team_member_info": { ... }}` Fallback Log: `3 March 2025, 15:10:42 Info Fallback API Response for https://www.dropbox.com/scl/fo/REPLACE_URL?dl=0: Error in call to API function "files/get_metadata": request body: unknown field 'shared_link'` In these logs, all sensitive details (such as URLs, IDs, names, and team names) have been replaced with placeholders. My question is: Why isn't the path_display property being returned by the Dropbox API, even though my account has the necessary permissions? Retrieving this property is crucial because it allows me to move folders in Dropbox and still maintain the most recent folder path in my interactive map. This is why I run weekly updates—to ensure that the map reflects any changes in folder structure. Any help or suggestions would be greatly appreciated!SolvedHow to filter events in dotnet SDK ?
I want to only query the team events of the event type file_download. I can't seem to figure out how I'm supposed to do it the way the developers intended. I can't find clear documentation on how to do this. GetTeamEventsResult events = await _dropbox.TeamLog.GetEventsAsync(eventType: WHAT DO I PUT HERE); I tried doing this: GetTeamEventsResult events = await _dropbox.TeamLog.GetEventsAsync(eventType: new EventTypeArg().AsFileDownload); But that just returns all events and doesn't filter them.46Views0likes2CommentsWhen logging in to Android SDK, the account is not registered and registration fails
Android uses SDK to log in, jump to the browser, enter the unregistered account, and jump to a new page. After filling in the Email, First name, Last name, Password as required, click "Agree And sign up", prompt: There was a problem completing this request. Please help solve this problem. (Login to a registered account works normally) Login SDK API: DbxRequestConfig config = DbxRequestConfig.newBuilder("gl-netdisc") .withHttpRequestor(new OkHttp3Requestor(OkHttp3Requestor.defaultOkHttpClient())).build(); Auth.startOAuth2PKCE(activity, appKey, config, Arrays.asList("account_info.write", "account_info.read", "files.metadata.write", "files.metadata.read", "files.content.write", "files.content.read", "file_requests.write", "file_requests.read")); Picture of the problem phenomenon:843Views0likes6Comments