# Signed URLs
[View original](https://ittybit.com/docs/delivery/signed)
## How it works
A signed delivery URL includes a valid signature which will grant access to a private file for a limited time.
A signed URL looks like this:
```html
```
The `domain` is your project's delivery domain (see [Domains](/docs/domains) for info on setting up custom domains) e.g. `https://you.ittybit.net`.
The `path` is the full path to the file you want to access e.g. `private/image.png`.
The `expiry` is a unix timestamp for some time in the near future. The URL will stop working after this time e.g. `1765432100`.
The `signature` is a base64 encoded string. The string that is encoded is the `domain`, `path`, and `expiry` values, signed with your project's API key.
Once you have the signed URL, you can use it to make a `GET` request to view the file. For example, you could use it as the `src` for an `
` tag, or `fetch` it directly in your application.
***
## Generate signatures
If you have access to a server-side environment, you can generate signatures yourself.
```js
import crypto from 'crypto';
const DOMAIN = 'you.ittybit.net';
const ITTYBIT_API_KEY = process.env.ITTYBIT_API_KEY;
function generateSignature({ string }) {
const hmac = crypto.createHmac('sha256', ITTYBIT_API_KEY);
hmac.update(string);
const base64 = hmac.digest('base64url');
return base64;
}
async function createSignedUrl({ path }) {
try {
const expiry = Math.floor(Date.now() / 1000) + 60 * 60; // 1 hour from now
const string = `${path}?expiry=${expiry}&method=get`;
const signature = generateSignature({ string });
const signedUrl = `https://${DOMAIN}/${string}&signature=${signature}`;
return { signedUrl };
} catch (error) {
// handle the error
}
}
// Example usage
const { signedUrl } = await createSignedUrl({ path: 'private/image.png' });
// Outputs: https://you.ittybit.net/private/image.png?expiry=1735689600&method=get&signature=a1b2c3d4e5f6...
```
A JS/node backend example is given above. More language examples are coming soon but please [contact us](https://ittybit.com/support) and we'd be happy to help you write something that fits into your stack.
***
## Using signed URLs
Once you have the signed URL, you can use it to access the file.
For images, you can use the `signedUrl` directly in an `
` tag.
```html
```
The response to a `GET` request on a signed URL is the file itself, not a JSON object.
***
## Downloading files
You can download a file by creating a link with the `signedUrl` as the `href`.
```html
Download file
```
***
## Common Pitfalls
**The file will only be accessible for the duration of the signed URL.**
Because signed URLs are only designed for short-term access, they include an expiry timestamp.
This means you should not generate signed URLs as part of a build process, because they may stop working before the next build is deployed.
TLDR; If you need signed URLs inside a JS framework site (Next.js, SvelteKit, etc) then you should use server actions to generate them at runtime.