How to Delete Comparisons in Draftable API
When using the Draftable API, comparisons and their associated documents are stored on the server until they are deleted. Over time, this can result in significant storage usage, particularly in self-hosted deployments where documents accumulate in the /var directory.
This guide explains the three approaches to managing comparison lifecycle and deletion:
- Manual Deletion - Explicitly delete comparisons via API calls
- Comparison Expiry - Automatically delete comparisons after a specified time
- URL Expiry - Control viewer URL validity (does not delete documents)
URL Expiry vs Comparison Expiry: A common misconception is that setting a URL expiry will delete the comparison and its documents. This is not the case. URL expiry only controls how long the viewer link remains valid—the comparison and documents remain on disk until explicitly deleted or until the comparison expires.
Method 1: Manual Deletion
You can permanently delete a comparison at any time using the delete method. This immediately removes the comparison and all associated documents from storage.
using Draftable.CompareAPI.Client;
// Initialize the client
var client = new Comparisons(accountId, authToken);
// Delete a specific comparison by identifier
client.Delete("your-comparison-identifier");
// Async version
await client.DeleteAsync("your-comparison-identifier");
After deletion, the comparison identifier becomes available for reuse.import draftable
# Initialize the client
client = draftable.Client(account_id, auth_token)
comparisons = client.comparisons
# Delete a specific comparison by identifier
comparisons.delete("your-comparison-identifier")
const draftable = require('@draftable/compare-api');
// Initialize the client
const client = draftable.client(accountId, authToken);
const comparisons = client.comparisons;
// Delete a specific comparison by identifier
comparisons.destroy("your-comparison-identifier").then(() => {
console.log("Comparison deleted successfully");
});
Note: In the Node.js client, the delete method is called destroy().
Bulk Deletion Example
To delete multiple or all comparisons (e.g., for cleanup), you can retrieve and iterate through your comparisons:
// Get all comparisons and delete the oldest 10
var allComparisons = client.GetAll();
var oldestComparisons = allComparisons
.OrderBy(c => c.CreationTime)
.Take(10);
foreach (var comparison in oldestComparisons)
{
client.Delete(comparison.Identifier);
Console.WriteLine($"Deleted comparison: {comparison.Identifier}");
}
# Get all comparisons and delete them
all_comparisons = comparisons.all()
for comparison in all_comparisons:
comparisons.delete(comparison.identifier)
print(f"Deleted comparison: {comparison.identifier}")
// Get all comparisons and delete the oldest 10
comparisons.getAll().then((allComparisons) => {
const deleteStartIndex = Math.max(0, allComparisons.length - 10);
for (let i = deleteStartIndex; i < allComparisons.length; i++) {
const identifier = allComparisons[i].identifier;
comparisons.destroy(identifier).then(() => {
console.log(`Deleted comparison: ${identifier}`);
});
}
});
Method 2: Comparison Expiry (Automatic Deletion)
The recommended approach for managing storage is to set an expiry time when creating comparisons. When a comparison expires, the system automatically deletes the comparison and all associated documents from storage.
using Draftable.CompareAPI.Client;
// Create a comparison that expires in 24 hours
var comparison = client.Create(
left: Comparisons.Side.FromFile("left.docx"),
right: Comparisons.Side.FromFile("right.docx"),
expires: TimeSpan.FromHours(24)
);
// Or set expiry to 30 minutes
var shortLivedComparison = client.Create(
left: Comparisons.Side.FromFile("left.pdf"),
right: Comparisons.Side.FromFile("right.pdf"),
expires: TimeSpan.FromMinutes(30)
);
Console.WriteLine($"Comparison will expire at: {comparison.ExpiryTime}");
from datetime import timedelta, datetime
# Create a comparison that expires in 24 hours
comparison = comparisons.create(
left="left.docx",
right="right.docx",
expires=timedelta(hours=24)
)
# Or set a specific expiry datetime
comparison = comparisons.create(
left="left.pdf",
right="right.pdf",
expires=datetime.utcnow() + timedelta(days=7)
)
print(f"Comparison will expire at: {comparison.expiry_time}")
// Create a comparison that expires in 2 hours
comparisons.create({
left: {
source: 'https://example.com/left.pdf',
fileType: 'pdf',
},
right: {
source: 'https://example.com/right.docx',
fileType: 'docx',
},
// Expire in 2 hours (milliseconds)
expires: new Date(Date.now() + 1000 * 60 * 60 * 2),
}).then((comparison) => {
console.log(`Comparison will expire at: ${comparison.expiryTime}`);
});
// Or set expiry to a specific date
comparisons.create({
left: { source: buffer, fileType: 'pdf' },
right: { source: buffer, fileType: 'docx' },
expires: new Date('2025-12-31T23:59:59Z'),
});
When Does a Comparison Become “Expired”?
A comparison receives the “expired” status when the current time passes the expiry_time that was set during creation. Once expired:
- The comparison becomes inaccessible via the API
- The system automatically deletes the comparison data
- All associated documents are removed from storage (e.g., the
/var directory in self-hosted deployments)
Best Practice: Always set an appropriate expires value when creating comparisons. This ensures automatic cleanup and prevents storage from growing indefinitely. Common expiry periods include:
- 30 minutes to 2 hours for temporary/preview comparisons
- 24 hours to 7 days for standard document reviews
- 30 days for long-term reference comparisons
Method 3: URL Expiry (Does NOT Delete Documents)
When generating signed viewer URLs for private comparisons, you can set how long the URL remains valid. This is not the same as comparison expiry.
Important: URL expiry only controls the validity of the viewer link. When a URL expires:
- Users see an “expired link” error message
- The comparison and documents remain on disk
- Storage is not freed
To delete documents and free storage, you must use comparison expiry or manual deletion.
// Generate a signed URL valid for 30 minutes (default)
var viewerUrl = client.SignedViewerURL("comparison-identifier");
// Generate a signed URL valid for 1 hour
var viewerUrl = client.SignedViewerURL(
"comparison-identifier",
TimeSpan.FromHours(1)
);
// Generate a signed URL valid until a specific time
var viewerUrl = client.SignedViewerURL(
"comparison-identifier",
DateTime.UtcNow.AddDays(1)
);
After the URL expires, users cannot access the viewer via that link, but the comparison still exists and can be accessed with a new signed URL.from datetime import timedelta
# Generate a signed URL valid for 30 minutes (default)
viewer_url = comparisons.signed_viewer_url("comparison-identifier")
# Generate a signed URL valid for 1 hour
viewer_url = comparisons.signed_viewer_url(
"comparison-identifier",
valid_until=timedelta(hours=1)
)
print(f"Viewer URL: {viewer_url}")
// Generate a signed URL valid for 30 minutes (default)
const viewerUrl = comparisons.signedViewerURL("comparison-identifier");
// Generate a signed URL valid for 1 hour
const validUntil = new Date(Date.now() + 1000 * 60 * 60);
const viewerUrl = comparisons.signedViewerURL(
"comparison-identifier",
validUntil
);
console.log(`Viewer URL: ${viewerUrl}`);
Comparison: Expiry Methods
| Feature | Comparison Expiry | URL Expiry |
|---|
| Set when | Creating comparison | Generating viewer URL |
| Parameter | expires | valid_until / validFor |
| Deletes documents | ✅ Yes | ❌ No |
| Frees storage | ✅ Yes | ❌ No |
| Affects access | Comparison becomes inaccessible | Only that specific URL expires |
| Can generate new URLs | ❌ No (comparison deleted) | ✅ Yes |
Recommended Approach
For most use cases, we recommend combining comparison expiry with URL expiry:
// Create comparison with 7-day expiry (auto-deletes after 7 days)
var comparison = client.Create(
left: Comparisons.Side.FromURL("https://example.com/left.pdf", "pdf"),
right: Comparisons.Side.FromURL("https://example.com/right.pdf", "pdf"),
expires: TimeSpan.FromDays(7)
);
// Generate URL valid for 1 hour (can regenerate as needed)
var viewerUrl = client.SignedViewerURL(
comparison.Identifier,
TimeSpan.FromHours(1)
);
from datetime import timedelta
# Create comparison with 7-day expiry (auto-deletes after 7 days)
comparison = comparisons.create(
left=draftable.make_side("https://example.com/left.pdf", "pdf"),
right=draftable.make_side("https://example.com/right.pdf", "pdf"),
expires=timedelta(days=7)
)
# Generate URL valid for 1 hour (can regenerate as needed)
viewer_url = comparisons.signed_viewer_url(
comparison.identifier,
valid_until=timedelta(hours=1)
)
// Create comparison with 7-day expiry (auto-deletes after 7 days)
comparisons.create({
left: { source: 'https://example.com/left.pdf', fileType: 'pdf' },
right: { source: 'https://example.com/right.pdf', fileType: 'pdf' },
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7), // 7 days
}).then((comparison) => {
// Generate URL valid for 1 hour (can regenerate as needed)
const viewerUrl = comparisons.signedViewerURL(
comparison.identifier,
new Date(Date.now() + 1000 * 60 * 60) // 1 hour
);
console.log(`Viewer URL: ${viewerUrl}`);
});
This approach ensures:
- Documents are automatically cleaned up after a reasonable period
- URLs can be regenerated as needed while the comparison exists
- Storage usage remains under control
Need Help?
If you have questions about managing comparisons or storage in your Draftable deployment, please contact us at support@draftable.com.