Files API
The Files API enables file upload, download, and management for data analysis workflows. Files can be used as data sources, exported as analysis outputs, or shared via share links.
Base URL
Section titled “Base URL”https://api.querri.com/apiAuthentication
Section titled “Authentication”All Files API endpoints require JWT authentication, except when accessing via share tokens. See Authentication for details.
Storage Backends
Section titled “Storage Backends”Querri supports multiple storage backends:
| Backend | Description | Configuration |
|---|---|---|
LOCAL | Local filesystem storage | Default for development |
S3 | Amazon S3 or S3-compatible | Production recommended |
GCS | Google Cloud Storage | Enterprise option |
AZURE | Azure Blob Storage | Enterprise option |
Storage backend is configured via environment variables and is transparent to API users.
Endpoints
Section titled “Endpoints”Upload File
Section titled “Upload File”Upload a file using multipart form data.
POST /api/files/uploadHeaders:
Authorization: Bearer {JWT_TOKEN}Content-Type: multipart/form-dataForm Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | File to upload |
name | string | No | Custom filename (defaults to original) |
project_uuid | string | No | Associate with specific project |
description | string | No | File description |
tags | array | No | Tags for organization |
visibility | string | No | private (default) or shared |
Example Request (cURL):
curl -X POST "https://api.querri.com/api/files/upload" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -F "file=@/path/to/data.csv" \ -F "name=customer_data.csv" \ -F "project_uuid=proj_01ABCDEF" \ -F "description=Customer data export from CRM" \ -F "tags[]=customers" \ -F "tags[]=export"Example Request (JavaScript):
const formData = new FormData();formData.append('file', fileInput.files[0]);formData.append('name', 'customer_data.csv');formData.append('project_uuid', 'proj_01ABCDEF');formData.append('description', 'Customer data export from CRM');formData.append('tags', JSON.stringify(['customers', 'export']));
fetch('https://api.querri.com/api/files/upload', { method: 'POST', headers: { 'Authorization': `Bearer ${token}` }, body: formData}).then(response => response.json()).then(data => console.log(data));Response: 201 Created
{ "file_id": "file_01ABCDEF", "name": "customer_data.csv", "original_name": "data.csv", "path": "users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv", "size_bytes": 1048576, "mime_type": "text/csv", "checksum": "sha256:a1b2c3d4...", "project_uuid": "proj_01ABCDEF", "description": "Customer data export from CRM", "tags": ["customers", "export"], "visibility": "private", "storage_backend": "s3", "metadata": { "encoding": "utf-8", "delimiter": ",", "row_count": 15000, "column_count": 12 }, "uploaded_by": "user_01ABCDEF", "uploaded_at": "2025-01-15T10:00:00Z", "download_url": "/api/files/stream/users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv", "expires_at": null}File Size Limits:
| Plan | Max File Size | Max Storage |
|---|---|---|
| Free | 100 MB | 1 GB |
| Pro | 1 GB | 100 GB |
| Enterprise | 10 GB | Unlimited |
Error Responses:
// 400 Bad Request - File too large{ "error": "file_too_large", "message": "File size exceeds limit of 100 MB", "size_bytes": 209715200, "limit_bytes": 104857600}
// 400 Bad Request - Unsupported file type{ "error": "unsupported_file_type", "message": "File type 'application/x-executable' is not allowed", "mime_type": "application/x-executable"}
// 507 Insufficient Storage{ "error": "storage_quota_exceeded", "message": "Storage quota exceeded", "used_bytes": 1073741824, "quota_bytes": 1073741824}Download File (Streaming)
Section titled “Download File (Streaming)”Download a file with streaming support for large files.
GET /api/files/stream/{path}Path Parameters:
| Parameter | Type | Description |
|---|---|---|
path | string | Full file path (URL-encoded) |
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
download | boolean | false | Force download vs. inline display |
share_token | string | - | Share token for public access |
Example Request:
# Direct downloadcurl "https://api.querri.com/api/files/stream/users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -o customer_data.csv
# Force download (adds Content-Disposition header)curl "https://api.querri.com/api/files/stream/users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv?download=true" \ -H "Authorization: Bearer ${JWT_TOKEN}" \ -o customer_data.csvResponse: 200 OK
File content streamed as binary data.
Response Headers:
Content-Type: text/csvContent-Length: 1048576Content-Disposition: attachment; filename="customer_data.csv"ETag: "a1b2c3d4..."Last-Modified: Wed, 15 Jan 2025 10:00:00 GMTAccept-Ranges: bytesRange Requests:
The API supports partial content requests for resumable downloads:
curl "https://api.querri.com/api/files/stream/path/to/file.csv" \ -H "Authorization: Bearer ${JWT_TOKEN}" \ -H "Range: bytes=0-1023" \ -o partial.csvResponse: 206 Partial Content
Content-Range: bytes 0-1023/1048576Content-Length: 1024Permission Required: file:read on the file, or valid share token.
Error Responses:
// 404 Not Found{ "error": "not_found", "message": "File not found or access denied"}
// 410 Gone - File expired{ "error": "file_expired", "message": "This file has expired and is no longer available", "expired_at": "2025-01-10T00:00:00Z"}List Files
Section titled “List Files”Retrieve files uploaded by the user or accessible via project permissions.
GET /api/filesQuery Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page (max 100) |
project_uuid | string | - | Filter by project |
tags | string | - | Filter by tags (comma-separated) |
mime_type | string | - | Filter by MIME type |
search | string | - | Search in filename and description |
sort | string | uploaded_at | Sort field |
order | string | desc | Sort order: asc or desc |
Example Request:
curl "https://api.querri.com/api/files?project_uuid=proj_01ABCDEF&tags=export&limit=50" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response: 200 OK
{ "data": [ { "file_id": "file_01ABCDEF", "name": "customer_data.csv", "path": "users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv", "size_bytes": 1048576, "mime_type": "text/csv", "project_uuid": "proj_01ABCDEF", "description": "Customer data export from CRM", "tags": ["customers", "export"], "visibility": "private", "uploaded_by": "user_01ABCDEF", "uploaded_at": "2025-01-15T10:00:00Z", "download_url": "/api/files/stream/users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv", "permissions": { "can_read": true, "can_delete": true, "can_share": true } } ], "pagination": { "page": 1, "limit": 50, "total": 142, "total_pages": 3, "has_next": true, "has_prev": false }, "storage_summary": { "total_files": 142, "total_size_bytes": 52428800, "quota_bytes": 107374182400, "used_percentage": 0.049 }}Get File Metadata
Section titled “Get File Metadata”Retrieve metadata for a specific file without downloading content.
GET /api/files/{file_id}Example Request:
curl "https://api.querri.com/api/files/file_01ABCDEF" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response: 200 OK
{ "file_id": "file_01ABCDEF", "name": "customer_data.csv", "original_name": "data.csv", "path": "users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv", "size_bytes": 1048576, "mime_type": "text/csv", "checksum": "sha256:a1b2c3d4...", "project_uuid": "proj_01ABCDEF", "description": "Customer data export from CRM", "tags": ["customers", "export"], "visibility": "private", "storage_backend": "s3", "metadata": { "encoding": "utf-8", "delimiter": ",", "row_count": 15000, "column_count": 12, "columns": [ {"name": "customer_id", "type": "integer"}, {"name": "name", "type": "string"}, {"name": "email", "type": "string"} ] }, "uploaded_by": "user_01ABCDEF", "uploaded_at": "2025-01-15T10:00:00Z", "last_accessed_at": "2025-01-15T14:30:00Z", "access_count": 42, "download_url": "/api/files/stream/users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv", "share_links": [], "expires_at": null}Update File Metadata
Section titled “Update File Metadata”Update file properties like name, description, or tags.
PATCH /api/files/{file_id}Request Body:
{ "name": "q4_customer_data.csv", "description": "Q4 2024 customer data export", "tags": ["customers", "export", "q4", "2024"], "visibility": "shared"}Response: 200 OK
Returns updated file metadata object.
Permission Required: file:edit (file owner or project editor).
Delete File
Section titled “Delete File”Permanently delete a file.
DELETE /api/files/{file_id}Example Request:
curl -X DELETE "https://api.querri.com/api/files/file_01ABCDEF" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response: 204 No Content
Permission Required: file:delete (file owner only).
Error Responses:
// 409 Conflict - File in use{ "error": "conflict", "message": "Cannot delete file: currently in use by 2 active steps", "usage": [ {"step_id": "step_01ABCDEF", "project_uuid": "proj_01ABCDEF"}, {"step_id": "step_02GHIJKL", "project_uuid": "proj_01ABCDEF"} ]}File Sharing
Section titled “File Sharing”Create Share Link
Section titled “Create Share Link”Generate a public share link for a file.
POST /api/files/{file_id}/shareRequest Body:
{ "expires_at": "2025-02-15T00:00:00Z", "password_protected": false, "max_downloads": 100}Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
expires_at | string | No | Expiration timestamp (ISO 8601) |
password_protected | boolean | No | Require password for access |
password | string | Conditional | Password (if password_protected is true) |
max_downloads | integer | No | Maximum download count |
Response: 201 Created
{ "share_link": "https://api.querri.com/api/files/stream/users/user_01ABCDEF/projects/proj_01ABCDEF/customer_data.csv?share_token=share_abc123", "share_token": "share_abc123", "file_id": "file_01ABCDEF", "expires_at": "2025-02-15T00:00:00Z", "password_protected": false, "max_downloads": 100, "download_count": 0, "created_at": "2025-01-15T10:00:00Z"}Access Shared File
Section titled “Access Shared File”# Via share tokencurl "https://api.querri.com/api/files/stream/path/to/file.csv?share_token=share_abc123" \ -o file.csv
# With password (if required)curl "https://api.querri.com/api/files/stream/path/to/file.csv?share_token=share_abc123" \ -H "X-Share-Password: secret123" \ -o file.csvSupported File Types
Section titled “Supported File Types”Data Files
Section titled “Data Files”| Extension | MIME Type | Auto-Detection |
|---|---|---|
.csv | text/csv | Delimiter, encoding, schema |
.json | application/json | Schema validation |
.jsonl | application/jsonlines | Line count |
.parquet | application/octet-stream | Schema, row count |
.xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | Sheets, schema |
.xls | application/vnd.ms-excel | Sheets, schema |
Document Files
Section titled “Document Files”| Extension | MIME Type |
|---|---|
.pdf | application/pdf |
.txt | text/plain |
.md | text/markdown |
Image Files
Section titled “Image Files”| Extension | MIME Type |
|---|---|
.png | image/png |
.jpg, .jpeg | image/jpeg |
.gif | image/gif |
.svg | image/svg+xml |
Blocked Types
Section titled “Blocked Types”Executable files and scripts are blocked for security:
.exe,.dll,.bat,.sh,.app.js,.py,.rb(unless explicitly allowed)
File Processing
Section titled “File Processing”Automatic Processing
Section titled “Automatic Processing”Uploaded files are automatically processed based on type:
CSV/Excel:
- Schema detection
- Row/column count
- Data type inference
- Sample data extraction
JSON:
- Schema validation
- Flattening nested structures
- Array detection
Parquet:
- Metadata extraction
- Schema reading
- Statistics collection
Manual Processing
Section titled “Manual Processing”Trigger manual processing for updated files:
curl -X POST "https://api.querri.com/api/files/file_01ABCDEF/process" \ -H "Authorization: Bearer ${JWT_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "operations": ["detect_schema", "generate_preview"], "options": { "sample_size": 1000 } }'Response:
{ "processing_id": "proc_01ABCDEF", "file_id": "file_01ABCDEF", "status": "processing", "operations": ["detect_schema", "generate_preview"], "started_at": "2025-01-15T10:00:00Z"}Storage Management
Section titled “Storage Management”Get Storage Quota
Section titled “Get Storage Quota”curl "https://api.querri.com/api/files/storage/quota" \ -H "Authorization: Bearer ${JWT_TOKEN}"Response:
{ "quota_bytes": 107374182400, "used_bytes": 52428800, "available_bytes": 107321753600, "used_percentage": 0.049, "file_count": 142, "breakdown": { "projects": 45000000, "uploads": 7000000, "exports": 428800 }}Cleanup Old Files
Section titled “Cleanup Old Files”Delete files older than specified date:
curl -X POST "https://api.querri.com/api/files/cleanup" \ -H "Authorization: Bearer ${JWT_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "older_than": "2024-01-01T00:00:00Z", "exclude_tags": ["important", "archive"], "dry_run": true }'Response:
{ "files_to_delete": 23, "space_to_free_bytes": 12582912, "files": [ { "file_id": "file_01ABCDEF", "name": "old_data.csv", "size_bytes": 524288, "uploaded_at": "2023-06-15T10:00:00Z" } ]}File Versioning
Section titled “File Versioning”Files support versioning when updated:
curl -X POST "https://api.querri.com/api/files/file_01ABCDEF/versions" \ -H "Authorization: Bearer ${JWT_TOKEN}" \ -F "file=@/path/to/updated_data.csv" \ -F "change_message=Updated with Q4 data"Response:
{ "version_id": "ver_01ABCDEF", "file_id": "file_01ABCDEF", "version": 2, "size_bytes": 1150000, "change_message": "Updated with Q4 data", "created_at": "2025-01-15T15:00:00Z", "download_url": "/api/files/stream/path/to/file.csv?version=2"}List versions:
curl "https://api.querri.com/api/files/file_01ABCDEF/versions" \ -H "Authorization: Bearer ${JWT_TOKEN}"Best Practices
Section titled “Best Practices”- Use descriptive filenames - Include dates, data sources, or purposes
- Tag files appropriately - Use consistent tagging for easier filtering
- Set expiration dates - For temporary uploads or exports
- Monitor storage quota - Regularly cleanup unused files
- Use streaming for large files - Avoid loading entire files into memory
- Validate file integrity - Check checksums after upload
- Compress large files - Use gzip or parquet compression
HTTP Status Codes
Section titled “HTTP Status Codes”| Code | Description |
|---|---|
| 200 | Success (GET, PATCH) |
| 201 | Created (POST upload) |
| 204 | No Content (DELETE) |
| 206 | Partial Content (range request) |
| 400 | Bad Request (validation error) |
| 401 | Unauthorized |
| 403 | Forbidden (insufficient permissions) |
| 404 | Not Found |
| 409 | Conflict (file in use) |
| 410 | Gone (file expired) |
| 413 | Payload Too Large (file size limit) |
| 416 | Range Not Satisfiable |
| 429 | Too Many Requests |
| 507 | Insufficient Storage |
| 500 | Internal Server Error |