Files API
Upload, retrieve, update, and delete files via the Emberly REST API.
Endpoints Overview
Upload
| Method | Path | Description |
|---|---|---|
POST | /api/files | Single file upload |
POST | /api/files/chunks | Initialize chunked upload |
GET | /api/files/chunks/[id]/part/[n] | Get presigned S3 URL for a chunk |
POST | /api/files/chunks/[id]/complete | Finalize chunked upload |
File Management
| Method | Path | Description |
|---|---|---|
GET | /api/files/[id] | Get file metadata |
PATCH | /api/files/[id] | Update visibility, password, etc. |
DELETE | /api/files/[id] | Delete a file |
GET | /api/files/[id]/download | Download a file |
POST | /api/files/[id]/expiry | Set file expiration |
DELETE | /api/files/[id]/expiry | Cancel file expiration |
GET | /api/files/shared | List files shared with you |
Single File Upload
POST /api/files
Content-Type: multipart/form-data
Auth: Bearer token
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | The file to upload |
visibility | PUBLIC | PRIVATE | No | Default: PUBLIC |
password | string | No | Password-protect the file |
domain | string | No | Custom domain for the URL |
expiresAt | ISO 8601 | No | Auto-delete date (must be future) |
allowSuggestions | "true" | "false" | No | Allow edit suggestions |
Response (200):
cURL:
JavaScript:
Plan Limits
| Plan | Max file size |
|---|---|
| Spark (Free) | 500 MB |
| Paid plans | Based on subscription |
Security Validation
Every upload runs:
- Extension + MIME type checks (50+ blocked types)
- Zip bomb detection (max 100:1 ratio)
- VirusTotal hash scan (71+ AV engines)
Blocked extensions: .exe, .bat, .sh, .py, .rb, .php, .dll, .jar, .msi, and others.
Chunked Upload
Use chunked upload for large files or unreliable connections. If you lose your connection mid-upload, the session is preserved (via Redis or the filesystem fallback) and can be resumed.
Auth: Bearer token or session cookie
Step 1 — Initialize
POST /api/files/chunks
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | Yes | Original file name |
mimeType | string | Yes | MIME type of the file |
size | number | Yes | Total file size in bytes |
domain | string | No | Custom domain for the resulting URL |
Response (200):
partSize is the recommended chunk size in bytes (5 MB by default). Split your file into chunks of this size.
Step 2 — Get a Presigned URL for Each Part
GET /api/files/chunks/{uploadId}/part/{partNumber}
partNumberis 1-based (first chunk =1)
Returns a short-lived presigned S3 URL.
Step 3 — Upload Each Chunk
PUT the chunk binary directly to the presigned URL:
Save the ETag header from the response — you'll need it in step 4.
Step 4 — Finalize
POST /api/files/chunks/{uploadId}/complete
| Field | Type | Required | Description |
|---|---|---|---|
parts | array | Yes | List of { PartNumber, ETag } objects in order |
expiresAt | ISO 8601 | No | Optional auto-delete date |
Returns the same response shape as single file upload upon success. The file undergoes the same VirusTotal and MIME security checks.
Chunked uploads are created as PUBLIC by default. Use PATCH /api/files/{id} after completion to change visibility or add a password.
JavaScript Example
Update a File
PATCH /api/files/[id]
Auth: Session or owner token
Returns updated file metadata.
Delete a File
DELETE /api/files/[id]
Auth: Session or owner token
Returns 204 No Content on success.
Set Expiration
POST /api/files/[id]/expiry
DELETE /api/files/[id]/expiry
Cancels the scheduled deletion.
Files Shared With You
GET /api/files/shared
Returns a paginated list of files other users have shared with you as a collaborator.