// Drive · Apps Script

Build a direct download link for a Drive file with Apps Script.

Learn how to generate a direct download link for a Google Drive file in Apps Script. The /view URL opens a preview; the download endpoint is https://drive.google.com/uc?export=download&id=FILE_ID. This page shows you how to build that URL programmatically and share the file so the link works for others.

I'm sharing a Drive file from a script and the link I'm generating opens a preview instead of downloading the file.

The script

copy · paste · trigger
driveDownloadLink.gs
Apps Script
// Returns a direct-download URL for a Drive file.
// The file must be shared (anyone with link) for external recipients.
function getDownloadLink(fileId) {
  var file = DriveApp.getFileById(fileId);

  // Make readable to anyone who has the link
  file.setSharing(
    DriveApp.Access.ANYONE_WITH_LINK,
    DriveApp.Permission.VIEW
  );

  var downloadUrl = 'https://drive.google.com/uc?export=download&id=' + fileId;
  Logger.log('Download URL: ' + downloadUrl);
  return downloadUrl;
}

Need a variant? Gnaw writes a custom version from one sentence — fields, triggers, edge cases handled.

Walkthrough

Why the /view URL is the wrong link

When you call DriveApp.getFileById(id).getUrl() in Apps Script, you get back a URL that ends in /view. That URL opens Drive's file preview in a browser tab. For Docs, Sheets, and Slides that makes sense. For PDFs, CSVs, images, or any binary file, it is the wrong behavior: the recipient sees a preview pane with a download button, not an automatic download.

The actual download endpoint is https://drive.google.com/uc?export=download&id=FILE_ID. That URL tells Drive to serve the file as an attachment rather than render it. The first time I hit this, I spent longer than I'd like to admit trying to figure out why my emailed export links were opening a viewer instead of triggering a save dialog — the endpoint isn't surfaced in the DriveApp docs at all.

Constructing the URL and setting permissions

The URL itself is just string concatenation: 'https://drive.google.com/uc?export=download&id=' plus the file ID. You can get the file ID from DriveApp.getFileById() if you already have it, or from file.getId() on any File object returned by a Drive search or iterator.

The catch that breaks most implementations is permissions. If the file is restricted to specific people or your domain only, someone outside that scope who clicks the link will hit an access-denied page. The script needs to call file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW) before handing the URL to anyone external. VIEW permission is sufficient for download; EDIT is unnecessary and a security over-grant.

If the files are internal only (shared inside a Workspace domain), use DriveApp.Access.DOMAIN_WITH_LINK instead. That keeps the file off the public internet while still letting anyone at the org download it without a separate share step.

Large files and the virus-scan warning

Files larger than roughly 100 MB do not go through the /uc endpoint cleanly. Google intercepts the request with an intermediate page that warns the file is too large to scan for viruses and asks the user to confirm before downloading. This page breaks any automated pipeline that expects a direct byte stream.

For large files you have two options: export a smaller format where possible (a Sheets spreadsheet exported as CSV will be much smaller than the same data as XLSX), or use the Drive REST API with an access token and the alt=media parameter, which bypasses the warning page for authenticated requests. The Apps Script approach above is fine for files under that threshold, which covers most CSVs, PDFs, and images generated by typical automation.

Want a custom version?

Describe your sheet and the rule you want. Gnaw writes the Apps Script — fields, triggers, edge cases — in one shot.

FAQ

4 questions
What is the direct download URL format for a Google Drive file?
https://drive.google.com/uc?export=download&id=YOUR_FILE_ID — replace YOUR_FILE_ID with the alphanumeric string from the file's URL or from file.getId() in Apps Script.
Why does my download link show an access denied error for recipients outside my organization?
The file's sharing setting hasn't been opened. Call file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW) in your script before distributing the URL. Without that, Drive blocks anyone not already granted explicit access.
Can I get a direct download link without changing the file's sharing settings?
Not for unauthenticated recipients. The download endpoint respects the same ACL as the view endpoint. If you need to serve the file to people who aren't signed into a Google account, ANYONE_WITH_LINK is the minimum required setting.
Does this work for Google Docs, Sheets, and Slides, or only uploaded files?
For native Google formats (Docs, Sheets, Slides), you need the export endpoint with a MIME type parameter instead: https://docs.google.com/spreadsheets/d/FILE_ID/export?format=csv for a Sheet as CSV, for example. The /uc?export=download endpoint is for uploaded binary files (PDFs, images, Office files, etc.), not for native Google Workspace formats.
// one good script a week

Get a working Apps Script snippet in your inbox, weekly.