As you build your Dropbox application, it’s important to remember that users may edit, move, and delete content at any time on Dropbox. As a result, your app may wish to poll for or be notified of these changes as they occur.
Many of these techniques are accomplished via cursors on supported API calls. A cursor is a pointer to a record within a result set, which can be updated to point to the next record - thus enabling traversal of result sets. In some cases, these result sets can have records continuously added.
User File Changes
Dropbox provides tools for developers to poll, wait for, or be notified of changes to users files.
The /files/list_folder API call is used to list content with a Dropbox folder.
This call also returns the has_more boolean, indicating if more results are available, as well as a cursor. Successfully enumerating all files in a folder requires calling /files/list_folder_continue with each successive cursor string until has_more is false.
However, these cursors are not only for useful pagination. Folder cursors are pointers to the folder at a particular time - and thus you may use a cursor to fetch changes that occurred after the time the cursor value was issued. Your list /files/list_folder_continue with a given cursor may return 0 results with has_more:false now, but calling it after modifying content in the folder will return those changes.
The ListFolderResult returned in the call includes indication of file change (add/modify), folder change, or deletion.
As a result of this property of folder cursors, storing the cursor value allows you to poll for changes to the target directory.
Folder cursors are long-lived, but may expire if unused for an extend time. Thus, while polling, be sure to always update to the latest returned cursor - even if no results are returned. A call to continue with an expired cursor will return a 409 reset error. This indicates you should issue a new call to /files/list_folder and iterate to obtain a new cursor. If the folder itself that the cursor refers to is deleted, the call will return a 409 path error.
If your application is only interested in changes going forward, the /files/list_folder/get_latest_cursor will return the most recent cursor, without needing to iterate through list and continue calls.
Waiting for User Change
For interactive applications that need real-time notification of a change in Dropbox, rapid polling is inefficient. These client-side applications should instead leverage /files/list_folder/longpoll for these cases.
Passing your cursor to the call will simply block until a change is detected (or its timeout occurs). Once long poll signals change, you can use /files/list_folder_continue to list the updates. This methodology will let you respond quickly and efficiently to changes.
For server-side applications that need background notifications in realtime, Dropbox also provides webhooks for user file changes. Instead of rapidly polling - which would be very inefficient if done 24/7 - Dropbox can instead notify applications when users’ filesystems change.
With webhooks configured, Dropbox sends an HTTP POST with the user IDs when changes occur. By saving the cursor for users, your application can then call /files/list_folder_continue to read the associated change when it receives the hook. Read more about using Dropbox webhooks here.
Note that webhooks will trigger for any changes to files the application has access to - so if your cursor is to a specific sub folder, not all notifications may be relevant to your app.
Sharing and Metadata
Note that the methodologies described above will allow you detect changes to files themselves, but will not indicate changes to sharing settings or other metadata.
Some endpoints, such as /sharing/list_file_members,may employ optional cursor and continue patterns for fetching large result sets, but may not support polling for change via cursors.
In general, most applications should look up these attributes as-needed, rather than poll for them specifically.
Team-linked applications have mechanisms to poll for these and other types of changes, as described below.
Changes in Dropbox Teams
Team-linked applications using the Business API are able to poll for a variety of changes to the team - including changes to team content, membership, sharing, and more.
Polling for File Changes
Team-linked applications with team member file access permissions may use the file methodologies described above for file changes to look for file changes, per user, using the Dropbox-API-Select-User header described here.
Polling for Events
The Dropbox Business API gives team-linked applications with team auditing permissions the ability to call the /team_log/get_events API. This activity log enables callers to view all changes to team files, sharing, team membership, settings changes, logins and devices, and more.
The advantages of this API are that it allows you to look for any type of change, and to do so efficiently team-wide - rather than look for changes per team member.
The API can be queried based on a start_time and end_time range to get events that occurred during a specific time period. It can also be polled using cursors to get updates in near real time, using a polling methodology similar to files, described above.
To do so:
- Issue a request to /team_log/get_events with a start_time but do not specify an end_time
- Using the the cursor, issue calls to /team_log/get_events_continue until has_more is false
- Save the returned cursor, and poll at /team_log/get_events_continue later for updates
- If the calls return error due to cursor expiration, issue a new call to /team_log/get_events with a new start_time
For best results with /team_log/get_events, remember:
- File events (edits, moves, deletes) are not available on the standard SKU. Use /features/get_values to inspect for logging of these events if your application depends on them.
- To continually poll for new events, use cursors & continue - not fixed start_time and end_time ranges. Cursors are more efficient, and will ensure you do not miss events. Excessive calls to /team_log/get_events may be rate limited more than /team_log/get_events_continue.
- For large teams, the volume of events can be high in some categories. If your application is only concerned with specific events, use the category parameter to filter results.
- Teams that have existed for some time may have a long event history. To get a complete picture of current state of a team, it’s more efficient to to call list methods. Then, to look for changes, call /team_log/get_events with a start_time set to the current time and poll.
- The API allows specifying an account_id to to filter events relevant to a particular member - but if your application is concerned with all events across the team, it will be more efficient to poll the whole team with one call (with account_id unspecified) than to poll per member.
Some types of team applications - such as identity and provisioning tools - may only be concerned with detecting changes to team membership.
For these applications, periodically checking /team/members/list or polling /team_log/get_events on the member category will work - but for apps needing to detect this in near-realtime, this mechanism is inefficient.
Dropbox Business API webhooks can instead deliver HTTP POST to your application on membership changes - see here for more information.
The Dropbox API offers a variety of tools to enable your application to quickly and efficiently detect changes. Which approach is best for you will depend on your application. In general: