diff --git a/docs/tutorials/python/download_file.md b/docs/tutorials/python/download_file.md
new file mode 100644
index 000000000..da796ada9
--- /dev/null
+++ b/docs/tutorials/python/download_file.md
@@ -0,0 +1,66 @@
+[](){ #tutorial-downloading-a-file }
+# Downloading files by Synapse ID
+
+This tutorial shows how to download any set of files from Synapse using their
+Synapse IDs. Rather than syncing an entire project or folder, this approach lets
+you target exactly the files you need and download them **concurrently** — even
+directing each file to a different local directory.
+
+
+## Tutorial Purpose
+In this tutorial you will:
+
+1. Build a mapping of Synapse IDs to local download directories
+1. Download all files concurrently using the async API
+
+
+## Prerequisites
+* Make sure that you have completed the following tutorials:
+ * [Folder](./folder.md)
+ * [File](./file.md)
+* The target directories (`~/temp/subdir1`, etc.) must exist before running the
+ script. Create them or replace them with directories of your choice.
+
+
+## 1. Build a mapping of Synapse IDs to download directories
+
+Create a dictionary that maps each Synapse ID to the local path where that file
+should be saved. Files can be directed to different directories as needed.
+
+```python
+{!docs/tutorials/python/tutorial_scripts/download_file.py!lines=13-30}
+```
+
+
+## 2. Download all files concurrently
+
+Use `File.get_async()` together with `asyncio.gather` to kick off every download
+at the same time and wait for them all to finish.
+
+```python
+{!docs/tutorials/python/tutorial_scripts/download_file.py!lines=33-42}
+```
+
+
+ After all downloads finish you'll see output like:
+```
+Retrieved 12 files
+```
+
+
+
+## Source code for this tutorial
+
+
+ Click to show me
+
+```python
+{!docs/tutorials/python/tutorial_scripts/download_file.py!}
+```
+
+
+## References used in this tutorial
+
+- [File][synapseclient.models.File]
+- [File.get_async][synapseclient.models.File.get_async]
+- [syn.login][synapseclient.Synapse.login]
diff --git a/docs/tutorials/python/tutorial_scripts/download_file.py b/docs/tutorials/python/tutorial_scripts/download_file.py
new file mode 100644
index 000000000..ce885443d
--- /dev/null
+++ b/docs/tutorials/python/tutorial_scripts/download_file.py
@@ -0,0 +1,43 @@
+"""
+Here is where you'll find the code for the downloading a file tutorial.
+"""
+
+import asyncio
+
+from synapseclient import Synapse
+from synapseclient.models import File
+
+syn = Synapse()
+syn.login()
+
+# A mapping of Synapse IDs to the local directory each file should be downloaded to.
+# Files can be directed to different directories as needed.
+SYN_IDS_AND_PATHS = {
+ "syn60584250": "~/temp/subdir1",
+ "syn60584256": "~/temp/subdir1",
+ "syn60584248": "~/temp/subdir1",
+ "syn60584252": "~/temp/subdir1",
+ "syn60584258": "~/temp/subdir1",
+ "syn60584260": "~/temp/subdir1",
+ "syn60584257": "~/temp/subdir1",
+ "syn60584251": "~/temp/subdir1",
+ "syn60584253": "~/temp/subdir1",
+ "syn60584390": "~/temp/subdir1",
+ "syn60584405": "~/temp/subdir2",
+ "syn60584400": "~/temp/subdir3",
+}
+
+
+async def main():
+ # Build a list of concurrent download tasks — one per Synapse ID
+ tasks = []
+ for syn_id, path in SYN_IDS_AND_PATHS.items():
+ tasks.append(File(id=syn_id, path=path).get_async())
+
+ # Download all files concurrently and wait for every one to finish
+ results = await asyncio.gather(*tasks)
+
+ print(f"Retrieved {len(results)} files")
+
+
+asyncio.run(main())
diff --git a/docs/tutorials/python_client.md b/docs/tutorials/python_client.md
index e1f912c44..ac6271e3f 100644
--- a/docs/tutorials/python_client.md
+++ b/docs/tutorials/python_client.md
@@ -30,6 +30,7 @@ By the end of these tutorials you'll have:
- A [Team](./python/team.md) created with one or more members
- Methods to [upload data in bulk](./python/upload_data_in_bulk.md)
- Methods to [download data in bulk](./python/download_data_in_bulk.md)
+- Methods to [download files by Synapse ID](./python/download_file.md)
- Methods to [move files and folders](./python/move_files_and_folders.md)
- Methods to [migrate data to other storage locations](./python/migrate_data_to_other_storage_locations.md)
diff --git a/mkdocs.yml b/mkdocs.yml
index eda90ac08..62aa876a8 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -45,6 +45,7 @@ nav:
# - Team: tutorials/python/team.md
- Upload data in bulk: tutorials/python/upload_data_in_bulk.md
- Download data in bulk: tutorials/python/download_data_in_bulk.md
+ - Download files by Synapse ID: tutorials/python/download_file.md
# - Creating JSON Schema: tutorials/python/schema_operations.md
- Working with JSON Schema: tutorials/python/json_schema.md
# - Move Files and Folders: tutorials/python/move_files_and_folders.md