# Download (https://v1.s3.dimah.dev/docs/react/custom-backend/download)

`download` returns a GET URL. The default is a short-lived S3 URL. When
the route uses `download.mode: "proxy"`, the URL is same-origin and the
server streams the body.

The payload is a single object: `route`, `key`, and optional `fileName`,
`disposition`, and `expiresIn`. `expiresIn` is a requested TTL in seconds.
Sign the shorter of that value and your route cap. Return the TTL you
actually signed.

<AutoTypeTable
  path="packages/core/src/types/requests.ts"
  name="DownloadPayload"
/>

<AutoTypeTable
  path="packages/core/src/types/responses.ts"
  name="DownloadPresignResponse"
/>

```ts
import type { DownloadPayload, DownloadPresignResponse } from "@dimah-s3/core";
```

## Example [#example]

Add this to the [`defineApi`](https://v1.s3.dimah.dev/docs/react/custom-backend) skeleton.
[`@dimah-s3/server`](https://v1.s3.dimah.dev/docs/server) uses
`GET /api/s3/presign/download?route=…&key=…`.

```ts
async download(payload) {
  const params = new URLSearchParams({
    route: payload.route,
    key: payload.key,
  });
  if (payload.fileName) params.set("fileName", payload.fileName);
  if (payload.disposition) params.set("disposition", payload.disposition);
  if (payload.expiresIn != null) {
    params.set("expiresIn", String(payload.expiresIn));
  }

  const res = await fetch(`/api/files/presign/download?${params}`);
  if (!res.ok) throw new Error(await res.text());
  return res.json();
}
```
