Guides

Managing Files

List, view, and delete your files

Learn how to list, view, and delete files in your datasets.

Overview

EasyRAG provides endpoints to:

  • List all files in a dataset
  • Get details about a specific file (including download URL)
  • Delete individual files
  • Delete all files in a dataset
  • Delete all files across all datasets

List Files in a Dataset

GET /v1/files

Get all files in a dataset.

bash
curl https://api.easyrag.com/v1/files?datasetId=my-dataset \ -H "Authorization: Bearer YOUR_API_KEY"

JavaScript

javascript
const response = await fetch( 'https://api.easyrag.com/v1/files?datasetId=my-dataset', { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { files } = await response.json(); console.log(`Found ${files.length} files`);

Response

json
{ "success": true, "files": [ { "fileId": "f7a3b2c1-4d5e-6f7g", "originalName": "manual.pdf", "datasetId": "my-dataset", "customerId": "user_abc123", "size": 245678, "mimeType": "application/pdf", "created": "2024-12-12T10:30:00.000Z", "extension": ".pdf", "extraMeta": { "department": "support", "version": "2.0" } } ] }

React Component

javascript
import { useState, useEffect } from 'react'; function FileList({ datasetId, apiKey }) { const [files, setFiles] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { async function loadFiles() { try { const response = await fetch( `https://api.easyrag.com/v1/files?datasetId=${datasetId}`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { files } = await response.json(); setFiles(files); } catch (error) { console.error('Failed to load files:', error); } finally { setLoading(false); } } loadFiles(); }, [datasetId, apiKey]); if (loading) return <div>Loading...</div>; return ( <div> <h2>Files ({files.length})</h2> <ul> {files.map(file => ( <li key={file.fileId}> {file.originalName} <small> ({(file.size / 1024).toFixed(1)} KB)</small> </li> ))} </ul> </div> ); }

Get File Details

GET /v1/files/:fileId

Get details about a specific file, including a signed download URL.

bash
curl https://api.easyrag.com/v1/files/f7a3b2c1-4d5e?datasetId=my-dataset \ -H "Authorization: Bearer YOUR_API_KEY"

JavaScript

javascript
const response = await fetch( `https://api.easyrag.com/v1/files/${fileId}?datasetId=my-dataset`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { file } = await response.json(); console.log('File:', file.originalName); console.log('Download:', file.permanentUrl);

Response

json
{ "success": true, "file": { "fileId": "f7a3b2c1-4d5e-6f7g", "originalName": "manual.pdf", "datasetId": "my-dataset", "size": 245678, "mimeType": "application/pdf", "created": "2024-12-12T10:30:00.000Z", "permanentUrl": "https://storage.googleapis.com/bucket/path?Expires=2491..." } }

Using the Download URL

The permanentUrl is a signed URL valid until 2491:

javascript
// Download file window.open(file.permanentUrl, '_blank'); // Or fetch it const blob = await fetch(file.permanentUrl).then(r => r.blob());

React Preview Component

javascript
function FilePreview({ fileId, datasetId, apiKey }) { const [file, setFile] = useState(null); useEffect(() => { async function loadFile() { const response = await fetch( `https://api.easyrag.com/v1/files/${fileId}?datasetId=${datasetId}`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { file } = await response.json(); setFile(file); } loadFile(); }, [fileId]); if (!file) return <div>Loading...</div>; return ( <div> <h3>{file.originalName}</h3> <p>Size: {(file.size / 1024).toFixed(1)} KB</p> <p>Uploaded: {new Date(file.created).toLocaleDateString()}</p> <a href={file.permanentUrl} target="_blank" rel="noopener noreferrer" > Download File </a> {/* Preview PDF in iframe */} {file.mimeType === 'application/pdf' && ( <iframe src={file.permanentUrl} style={{ width: '100%', height: '600px' }} title={file.originalName} /> )} </div> ); }

Delete a Single File

DELETE /v1/files/:fileId

Delete a specific file. This removes:

  • The file from storage
  • All vector embeddings
  • File metadata
bash
curl -X DELETE \ "https://api.easyrag.com/v1/files/f7a3b2c1-4d5e?datasetId=my-dataset" \ -H "Authorization: Bearer YOUR_API_KEY"

JavaScript

javascript
const response = await fetch( `https://api.easyrag.com/v1/files/${fileId}?datasetId=my-dataset`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${apiKey}` } } ); if (response.ok) { console.log('File deleted successfully'); }

Response

json
{ "success": true }

React Delete Button

javascript
function DeleteButton({ fileId, datasetId, apiKey, onDelete }) { const [deleting, setDeleting] = useState(false); const handleDelete = async () => { if (!confirm('Delete this file permanently?')) return; setDeleting(true); try { const response = await fetch( `https://api.easyrag.com/v1/files/${fileId}?datasetId=${datasetId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${apiKey}` } } ); if (response.ok) { onDelete?.(fileId); } else { alert('Failed to delete file'); } } catch (error) { console.error('Delete failed:', error); alert('Network error'); } finally { setDeleting(false); } }; return ( <button onClick={handleDelete} disabled={deleting} style={{ background: '#ef4444', color: 'white', padding: '8px 16px', border: 'none', borderRadius: '4px', cursor: deleting ? 'wait' : 'pointer' }} > {deleting ? 'Deleting...' : 'Delete'} </button> ); }

Delete All Files in Dataset

DELETE /v1/datasets/:datasetId/files

Delete all files in a specific dataset.

⚠️ Warning: This is irreversible!

bash
curl -X DELETE \ https://api.easyrag.com/v1/datasets/my-dataset/files \ -H "Authorization: Bearer YOUR_API_KEY"

JavaScript

javascript
const response = await fetch( `https://api.easyrag.com/v1/datasets/${datasetId}/files`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { deleted } = await response.json(); console.log(`Deleted ${deleted} files`);

Response

json
{ "success": true, "deleted": 15 }

React Clear Dataset Button

javascript
function ClearDatasetButton({ datasetId, apiKey, onClear }) { const [clearing, setClearing] = useState(false); const handleClear = async () => { const confirmed = confirm( 'Delete ALL files in this dataset? This cannot be undone!' ); if (!confirmed) return; setClearing(true); try { const response = await fetch( `https://api.easyrag.com/v1/datasets/${datasetId}/files`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { deleted } = await response.json(); alert(`Deleted ${deleted} files`); onClear?.(); } catch (error) { console.error('Clear failed:', error); alert('Failed to clear dataset'); } finally { setClearing(false); } }; return ( <button onClick={handleClear} disabled={clearing} style={{ background: '#dc2626', color: 'white', padding: '10px 20px', border: 'none', borderRadius: '4px', fontWeight: 'bold' }} > {clearing ? 'Clearing...' : 'Clear Entire Dataset'} </button> ); }

Delete All Customer Files

DELETE /v1/files

Delete all files across all datasets for the authenticated customer.

⚠️ Warning: This is a complete wipe and cannot be undone!

Note: Only API keys can use this endpoint (not frontend tokens).

bash
curl -X DELETE https://api.easyrag.com/v1/files \ -H "Authorization: Bearer YOUR_API_KEY"

JavaScript

javascript
const response = await fetch('https://api.easyrag.com/v1/files', { method: 'DELETE', headers: { 'Authorization': `Bearer ${apiKey}` } }); const { deleted } = await response.json(); console.log(`Deleted ${deleted} files total`);

Response

json
{ "success": true, "deleted": 127 }

Complete File Manager Component

Here's a full file management interface:

javascript
import { useState, useEffect } from 'react'; function FileManager({ datasetId, apiKey }) { const [files, setFiles] = useState([]); const [loading, setLoading] = useState(true); const [selectedFile, setSelectedFile] = useState(null); useEffect(() => { loadFiles(); }, [datasetId]); const loadFiles = async () => { setLoading(true); try { const response = await fetch( `https://api.easyrag.com/v1/files?datasetId=${datasetId}`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { files } = await response.json(); setFiles(files); } catch (error) { console.error('Failed to load files:', error); } finally { setLoading(false); } }; const deleteFile = async (fileId) => { if (!confirm('Delete this file?')) return; try { const response = await fetch( `https://api.easyrag.com/v1/files/${fileId}?datasetId=${datasetId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${apiKey}` } } ); if (response.ok) { setFiles(files.filter(f => f.fileId !== fileId)); if (selectedFile?.fileId === fileId) { setSelectedFile(null); } } } catch (error) { alert('Failed to delete file'); } }; const viewFile = async (fileId) => { try { const response = await fetch( `https://api.easyrag.com/v1/files/${fileId}?datasetId=${datasetId}`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { file } = await response.json(); setSelectedFile(file); } catch (error) { console.error('Failed to load file:', error); } }; if (loading) { return <div>Loading files...</div>; } return ( <div style={{ display: 'flex', gap: '20px' }}> {/* File List */} <div style={{ flex: 1 }}> <h2>Files ({files.length})</h2> {files.length === 0 ? ( <p>No files uploaded yet</p> ) : ( <ul style={{ listStyle: 'none', padding: 0 }}> {files.map(file => ( <li key={file.fileId} style={{ padding: '12px', border: '1px solid #ddd', marginBottom: '8px', borderRadius: '4px', cursor: 'pointer', background: selectedFile?.fileId === file.fileId ? '#e3f2fd' : 'white' }} onClick={() => viewFile(file.fileId)} > <div style={{ fontWeight: 'bold' }}> {file.originalName} </div> <div style={{ fontSize: '12px', color: '#666' }}> {(file.size / 1024).toFixed(1)} KB{' '} {new Date(file.created).toLocaleDateString()} </div> <button onClick={(e) => { e.stopPropagation(); deleteFile(file.fileId); }} style={{ marginTop: '8px', background: '#ef4444', color: 'white', border: 'none', padding: '4px 8px', borderRadius: '4px', cursor: 'pointer' }} > Delete </button> </li> ))} </ul> )} </div> {/* File Preview */} <div style={{ flex: 1 }}> {selectedFile ? ( <div> <h2>{selectedFile.originalName}</h2> <p> <strong>Size:</strong> {(selectedFile.size / 1024).toFixed(1)} KB </p> <p> <strong>Type:</strong> {selectedFile.mimeType} </p> <p> <strong>Uploaded:</strong>{' '} {new Date(selectedFile.created).toLocaleString()} </p> <a href={selectedFile.permanentUrl} target="_blank" rel="noopener noreferrer" style={{ display: 'inline-block', padding: '10px 20px', background: '#4f46e5', color: 'white', textDecoration: 'none', borderRadius: '4px', marginTop: '10px' }} > Download File </a> {selectedFile.mimeType === 'application/pdf' && ( <iframe src={selectedFile.permanentUrl} style={{ width: '100%', height: '600px', marginTop: '20px', border: '1px solid #ddd' }} title={selectedFile.originalName} /> )} </div> ) : ( <p>Select a file to view details</p> )} </div> </div> ); } export default FileManager;

Important Notes

Deletions are Permanent

  • Files cannot be recovered after deletion
  • Credits are not refunded for deleted files
  • Deleting a file removes it from storage, vectors, and metadata

File Operations are Concurrent

When deleting multiple files (e.g., clearing a dataset):

  • Operations happen in parallel for efficiency
  • Some may succeed while others fail
  • Partial failures are logged but don't stop the process

Frontend Token Limitations

Frontend tokens can only:

  • List/view/delete files in their authorized dataset
  • Cannot use the "delete all customer files" endpoint

Best Practices

1. Confirm Destructive Actions

javascript
// ✅ Good - Ask for confirmation if (confirm('Delete this file permanently?')) { await deleteFile(fileId); } // ❌ Bad - No confirmation await deleteFile(fileId);

2. Show Loading States

javascript
const [deleting, setDeleting] = useState(false); const handleDelete = async () => { setDeleting(true); try { await deleteFile(fileId); } finally { setDeleting(false); } };

3. Update UI After Deletion

javascript
const handleDelete = async (fileId) => { await deleteFile(fileId); // Remove from UI setFiles(files.filter(f => f.fileId !== fileId)); };

4. Handle Errors Gracefully

javascript
try { await deleteFile(fileId); } catch (error) { if (error.status === 404) { alert('File not found'); } else if (error.status === 403) { alert('Permission denied'); } else { alert('Failed to delete file'); } }

Troubleshooting

File Not Found (404)

Problem: File doesn't exist

Solutions:

  • Verify fileId is correct
  • Check if file was already deleted
  • Ensure correct datasetId

Permission Denied (403)

Problem: Token doesn't have access

Solutions:

  • Verify token is for the correct dataset
  • Use API key for cross-dataset operations
  • Check user permissions

Nothing Happens When Deleting

Problem: Delete request succeeds but file still appears

Solutions:

  • Refresh the file list after deletion
  • Check if error occurred silently
  • Verify the UI is updating correctly

Next Steps

Billing

File management operations are free:

  • Listing files: Free
  • Getting file details: Free
  • Deleting files: Free

Note: Credits spent on uploads are not refunded when files are deleted.