Storage
DYPAI provides file storage powered by Cloudflare R2 (S3-compatible). Each project can create multiple buckets to organize files, with public or private access. Uploads go directly to R2 using presigned URLs, and private files are served through signed URLs via a Cloudflare Worker.
Key Concepts
- Buckets β top-level containers for organizing files. Each bucket is either public (served via CDN, no auth required) or private (requires a signed URL).
- Presigned Uploads β the SDK gets a presigned URL from the engine, then uploads the file directly to R2. No file data passes through your server.
- Signed URLs β time-limited URLs for downloading private files, verified by a Cloudflare Worker.
- File paths β files are organized by entity ID and folder, e.g.
{entity_id}/image/avatars/photo.jpg.
Buckets
Buckets are stored in the storage.buckets table. Each bucket has:
| Field | Description |
|---|---|
name | Unique bucket identifier (e.g. "avatars", "documents") |
public | true for public access, false for private (signed URLs required) |
provider | Storage provider (always "r2") |
You can create buckets from the Storage section in your project dashboard.
Public bucket files are served directly via CDN with no authentication. Private bucket files always require a signed URL.
Upload Flow
DYPAI uses a 3-phase upload that sends files directly to Cloudflare R2, keeping your server lightweight:
1. SIGN β Client requests a presigned upload URL from the engine
2. UPLOAD β Client uploads the file directly to R2 using the presigned URL
3. VERIFY β Client confirms the upload, engine records metadata in the database
Using the SDK
All file operations go through your endpoints, which use the dypai_storage node in the backend:
const { data, error } = await dypai.api.upload('storage_files', file, {
params: {
operation: 'upload',
file_path: `invoices/${file.name}`,
},
onProgress: (pct) => console.log(`Upload: ${pct}%`),
});
if (data) {
console.log('Storage path:', data.storage_path);
}
The SDK handles the entire 3-phase flow automatically. The onProgress callback provides real-time upload progress since the file goes directly from the browser to R2.
Using the React Hook
import { useUpload } from '@dypai-ai/client-sdk/react';
function FileUploader() {
const { upload, progress, isUploading } = useUpload('storage_files');
const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
const { data, error } = await upload(file, {
operation: 'upload',
file_path: `avatars/${file.name}`,
});
};
return (
<div>
<input type="file" onChange={handleFile} disabled={isUploading} />
{isUploading && <p>Uploading: {progress}%</p>}
</div>
);
}
Important: use storage_path
During upload the backend may append a UUID or normalize the filename. Save storage_path in your database, not the original file_path.
Downloading Files
Signed URL Download
For secure downloads, call a backend endpoint that validates ownership and returns the signed URL:
const { data } = await dypai.api.post('download_file', {
entity_id: invoice.id,
});
const signedUrl = data?.signedUrl || data?.signed_url;
Direct Download
await dypai.api.download('download_file', { entity_id: invoice.id }, {
fileName: 'invoice.pdf',
});
Listing Files
const { data } = await dypai.api.post('storage_files', {
operation: 'list',
prefix: 'invoices/2024',
});
Deleting Files
const { error } = await dypai.api.delete('storage_delete_files', {
params: { file_path: storedPath },
});
Deleted files are permanently removed from R2. This action cannot be undone.
File Size Limits
Maximum file size depends on the file type:
| File Type | Max Size |
|---|---|
| Image (png, jpg, webp, etc.) | 25 MB |
| Document (pdf, docx, etc.) | 50 MB |
| Spreadsheet (xlsx, csv, etc.) | 25 MB |
| Presentation (pptx, etc.) | 100 MB |
| Audio (mp3, wav, etc.) | 250 MB |
| Video (mp4, mov, etc.) | 1 GB |
| Archive (zip, tar, etc.) | 500 MB |
| Other | 10 MB |
Blocked File Types
For security, the following file extensions are blocked from upload:
- Executables:
.exe,.msi,.dmg,.pkg,.deb,.rpm - Scripts:
.bat,.cmd,.sh,.ps1,.vbs,.scr - Office with macros:
.xlsm,.pptm,.docm - Java:
.jar,.class - Apps:
.app,.ipa,.apk
Next Steps
- SDK Storage Reference β upload, download, and file management from the SDK.
- API Builder β create custom file upload/download workflows.