> ## Documentation Index
> Fetch the complete documentation index at: https://docs.urbackend.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Storage

> Upload files and get back public CDN URLs using the SDK storage module.

Access storage methods via `client.storage`. Uploaded files are served from a public CDN — no extra configuration required.

<Warning>
  Storage operations require your **secret key** (`sk_live_...`). These operations should only be performed server-side.
</Warning>

***

## upload

Upload a file to storage.

```typescript theme={null}
upload(file: File | Blob | Buffer, filename?: string): Promise<UploadResponse>
```

**Parameters**

| Name       | Type                     | Required | Description                   |
| ---------- | ------------------------ | -------- | ----------------------------- |
| `file`     | `File \| Blob \| Buffer` | Yes      | The file to upload.           |
| `filename` | `string`                 | No       | Override the stored filename. |

**Returns (`UploadResponse`)**

| Field      | Type                       | Description                                                   |
| ---------- | -------------------------- | ------------------------------------------------------------- |
| `url`      | `string`                   | Public CDN URL for the uploaded file.                         |
| `path`     | `string`                   | Storage path — required to delete the file later.             |
| `provider` | `'internal' \| 'external'` | Whether the file is stored on urBackend or your own Supabase. |

<Note>
  Store the `path` alongside the `url` in your database. You need it to delete the file.
</Note>

**Example — Node.js upload**

```typescript theme={null}
const fs = require('fs');
const file = fs.readFileSync('./abc123.jpg');

const { url, path, provider } = await client.storage.upload(file, 'abc123.jpg');
console.log(url);  // 'https://cdn.example.com/uploads/abc123.jpg'
console.log(provider); // 'internal'
```

***

## Presigned URLs (Direct Client Uploads)

To allow frontend users to upload files directly without passing them through your server, use the presigned URL flow.

### 1. requestUploadUrl (Server)

Generates a temporary upload URL. Requires your **secret key**.

```typescript theme={null}
requestUploadUrl(filename: string, contentType: string, size: number): Promise<{ signedUrl: string, filePath: string }>
```

### 2. uploadToPresignedUrl (Client)

A static helper to push the file to the generated URL from the frontend.

```typescript theme={null}
import { StorageModule } from '@urbackend/sdk';

StorageModule.uploadToPresignedUrl(file: File | Blob | Buffer, signedUrl: string): Promise<void>
```

### 3. confirmUpload (Server)

Confirms the upload is complete and registers it in your storage quota.

```typescript theme={null}
confirmUpload(filePath: string, size: number): Promise<UploadResponse>
```

**Full Example (React + Node.js):**

```typescript theme={null}
// 1. Server: Generate link
app.post('/api/upload-link', async (req, res) => {
  const link = await urbackend.storage.requestUploadUrl('cat.png', 'image/png', 500000);
  res.json(link);
});

// 2. Client (React): Upload directly
const { signedUrl, filePath } = await fetch('/api/upload-link').then(r => r.json());
await StorageModule.uploadToPresignedUrl(file, signedUrl);

// 3. Server: Confirm
app.post('/api/upload-confirm', async (req, res) => {
  const result = await urbackend.storage.confirmUpload(req.body.filePath, 500000);
  res.json(result);
});
```

***

## deleteFile

Delete a previously uploaded file by its storage path.

```typescript theme={null}
deleteFile(path: string): Promise<{ deleted: boolean }>
```

**Parameters**

| Name   | Type     | Required | Description                        |
| ------ | -------- | -------- | ---------------------------------- |
| `path` | `string` | Yes      | The `path` returned by `upload()`. |

***

## Limits

| Limit                     | Value                                          |
| ------------------------- | ---------------------------------------------- |
| Max file size             | 10 MB per file (urBackend-hosted storage only) |
| Total storage per project | 20 MB (Free Tier)                              |

<Note>
  Uploads that exceed 10 MB are rejected with a `StorageError`. Projects connected to external (bring-your-own) storage are not subject to the 10 MB per-file limit.
</Note>


## Related topics

- [Storage](/guides/storage.md)
- [Upload File](/api-reference/storage/upload.md)
- [Limits & Quotas](/limits-and-quotas.md)
- [Delete File](/api-reference/storage/delete.md)
