Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated Apr 29, 2024

Download files


Get a presigned URL of a stored file. You can specify some options: mainly file access level and whether to download the file:

await Storage.get(key: string, config: {
level?: private | protected | public, // defaults to `public`
identityId?: string, // id of another user, if `level: protected`
download?: boolean, // defaults to false
expires?: number, // validity of the URL, in seconds. defaults to 900 (15 minutes) and maxes at 3600 (1 hour)
contentType?: string, // set return content type, eg "text/html"
validateObjectExistence?: boolean, // defaults to false
cacheControl?: string, // Specifies caching behavior along the request/reply chain

Storage.get returns a signed URL string to your file if download is false, which is the default. You can use this to create a download link for users to click on. Note that this function does not check if the file exists by default. You can enable this check by setting validateObjectExistence to true.

Note: Currently, the expiration time of the presigned url is dependent on the session and will max out at 1 hour.

// get the signed URL string
const signedURL = await Storage.get(key); // get key from Storage.list
// inside your template or JSX code. Note <a download> doesn't work here because it is not same origin
<a href={signedURL} target="_blank" rel="noreferrer">

Check for existence of a file

You can check for the existence of a file in the storage category's get API using the validateObjectExistence option. When this flag is enabled a get call will return a pre-signed URL if the file exists and raise a 404 error if it does not. This allows you to check if an object exists during generating the presigned URL, which you can then use to download that object.

// To check for existence of a file
await Storage.get('filename.txt', { validateObjectExistence: true });

If download is true, Storage.get returns an object with a Body field of type Blob. It is up to you to programmatically save it to disk (we suggest a method below) or do whatever else you need with it.

File download option

The download option send you the object data for download or programmatic manipulation:

const result = await Storage.get(`filename.txt`, { download: true });
// data.Body is a Blob
result.Body.text().then((string) => {
// handle the String data return String

You can programmatically download Blobs using JavaScript:

export function downloadBlob(blob, filename) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url; = filename || 'download';
const clickHandler = () => {
setTimeout(() => {
a.removeEventListener('click', clickHandler);
}, 150);
a.addEventListener('click', clickHandler, false);;
return a;
// usage
async function download() {
const result = await Storage.get(fileKey, { download: true });
downloadBlob(result.Body, 'filename');

The full return signature of Storage.get(key, { download: true }) looks like this:

$metadata: {
attempts: 1
httpHeaders: {content-length: "388187", content-type: "audio/x-m4a", last-modified: "Fri, 09 Oct 2020 14:29:13 GMT", x-amz-id-2: "/rRqsX/c2h5V00tYMtDY994wEenyPm0SDw1lyWyncWepyg+T6YJJSjLHKIsz0dxMI3kN5KjA6GQ=",}
httpStatusCode: 200
requestId: undefined
totalRetryDelay: 0
Body: Blob {size: 388187, type: "audio/x-m4a"}, // this will vary
ContentLength: 388187,
ContentType: "audio/x-m4a",
ETag: ""c05e324f61613c2472d47a8ee6fbb628"",
LastModified: Fri Oct 09 2020 22:29:13 GMT+0800 (Singapore Standard Time) {},
Metadata: {},
__type: "GetObjectOutput",

Monitor progress of download

To track the progress of your download, you can use progressCallback:

Storage.get('filename.txt', {
download: true,
progressCallback(progress) {
console.log(`Downloaded: ${progress.loaded}/${}`);

File Access Levels

You can choose to configure access level ahead of time, or at the point of calling Storage.get:

// Option 1: configure access ahead of time
Storage.configure({ level: 'private' });
const result = await Storage.get('welcome.png'); // Gets the welcome.png belonging to current user
// Option 2: configure access inside the call
const result = await Storage.get('welcome.png', { level: 'private' }); // same effect

Here is a quick guide to the access levels - see the docs for more detail:

  • public: Accessible by all users of your app. Files are stored under the public/ path in your S3 bucket.
  • protected: Readable by all users, but writable only by the creating user. Files are stored under protected/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.
// To get current user's objects
const result = await Storage.get('filename.txt', { level: 'protected' });
// To get other users' objects
const result = await Storage.get('filename.txt', {
level: 'protected',
identityId: 'xxxxxxx' // the identityId of that user
  • private: Only accessible for the signed in user. Files are stored under private/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.

Download expiry

You can use expires option to limit the availability of your URLs. This configuration returns the pre-signed URL that expires in 60 seconds:

await Storage.get('filename.txt', { expires: 60 });

Frequently Asked Questions

Users can run into unexpected issues, so we are giving you advance notice in documentation with links to open issues - please vote for what you need, to help the team prioritize.