# 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 A private image that only cool people can see ``` 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.