Upload and Edit APIs
Shared Concepts
hname: host/domain where link is allocated (file.ax,file.wf,file.yt,kt.ci,gatto.mewith permission rules).manager/ deletion hash: owner token used for ownership checks.folderId: optional folder assignment field supported by upload/creation endpoints.- Secondary sessions can upload/create; list/edit behavior is controlled by per-secondary flags (
can_list_files,can_edit_files), plus upload-token and folder-scope checks.
Authentication Requirements (As Implemented)
| Endpoint | Auth Required (as implemented) |
|---|---|
GET /api |
None |
POST /api/initChunkedUpload |
Cookie session or API key auth |
POST /api/uploadChunk |
No explicit auth middleware; valid upload id required |
GET /api/chunkedUploadStatus |
No explicit auth middleware; valid upload id required |
POST /api/finishChunkedUpload |
No explicit auth middleware; handler requires valid chunk session plus body fields (id, filename, manager value source) |
POST /api/replaceFile |
Cookie session or API key auth + ownership checks; secondary session must have edit permission and match upload/file token and folder scope |
PATCH /api/files/:id/folder |
Cookie session or API key auth + application/json; secondary restricted by token + folder scope |
POST /api/files/move |
Cookie session or API key auth + application/json; secondary restricted by token + folder scope |
POST /api/edit/:hname/:path |
Owner proof via body manager token or owner cookie session; secondary session must have edit permission and match file token + folder scope |
POST /api/shorten |
No explicit auth middleware; requires token + manager values (body or session sources); secondary scope applied |
POST /api/html/paste |
Session pasteCSRF match + manager token (session or body); secondary scope applied |
GET /api/editPaste/:hname/:path |
Owner cookie session required (otherwise redirect); secondary must have edit permission and pass scope checks |
Credential-body script endpoints are documented in Plain Endpoints (Scripts).
Secondary Folder Scope Behavior
- If secondary password has no folder scope: default token-based restrictions apply.
- If secondary password has a folder scope:
- create/upload endpoints treat missing
folderIdas “use scope root” - provided
folderIdmust be the scoped folder or one of its descendants - edit/move/replace operations are rejected for files outside that subtree
- create/upload endpoints treat missing
- If secondary credential has
can_edit_files = false, edit/replace/move operations are denied even inside scope.
Chunked Uploads: Resumable + High Performance
Chunked uploads are the recommended path for large files.
- Resumable: retry only failed chunks.
- Network-tolerant: upload continues chunk by chunk on unstable links.
- Idempotent finalize: repeated finalize calls return the same completed result.
- High-performance finalize: reassembly is streamed with backpressure, so large files are processed without loading full payloads into RAM.
Chunked Flow
- Initialize with filename + full size.
- Split file client-side into numbered chunks (
chunk=1,chunk=2, …). - Upload each chunk with upload
id. - Retry failed chunks only.
- Optionally poll status.
- Finalize after all chunks are uploaded.
- If finalize returns processing, retry shortly.
Request and Response Examples
GET /api
Success response (200, plain text):
Hello World
POST /api/initChunkedUpload
Auth requirement:
- Active authenticated session is required.
- You can satisfy this with either:
- normal browser/session cookie auth, or
- API key headers (
Authorization: Bearer <api_key>orX-API-Key) when API-key middleware is enabled.
Request body (application/json or urlencoded):
{
"filename": "video.mp4",
"size": 104857600
}
Success response (200):
{
"id": "3fa1c7409df3a2d4bbf7d33d5e6f7c18",
"storageInfo": {
"usage": 123456,
"limit": 53687091200,
"remaining": 53686967744
}
}
Storage failure (413):
{
"error": "Storage limit exceeded",
"details": "...",
"usage": 53687000000,
"limit": 53687091200,
"remaining": 91200
}
POST /api/uploadChunk
Request format:
- Query:
id=<upload-id>&chunk=<number> - Multipart field:
file
Example:
curl -X POST \
-F "file=@chunk-1.bin" \
"https://file.ax/api/uploadChunk?id=3fa1c7409df3a2d4bbf7d33d5e6f7c18&chunk=1"
Success response (200):
{ "success": true }
GET /api/chunkedUploadStatus
Request query:
id=<upload-id>
Possible responses:
{ "status": "pending" }
{ "status": "processing" }
{
"status": "completed",
"success": true,
"link": "abcde",
"hname": "file.ax"
}
{ "error": "Upload not found", "status": "not_found" }
POST /api/finishChunkedUpload
Request body (application/json or urlencoded):
{
"id": "3fa1c7409df3a2d4bbf7d33d5e6f7c18",
"filename": "video.mp4",
"_manager": "manager_token",
"folderId": 123,
"keepExtensionInURL": true,
"linkSize": 6,
"hname": "file.ax",
"forceDownload": false,
"skipEmbeddedPage": false
}
Success response (200):
{
"success": true,
"link": "abcde.mp4",
"hname": "file.ax"
}
Processing response (202):
{
"status": "processing",
"message": "Upload is currently being finalized. Please retry shortly.",
"retryAfter": 5
}
POST /api/replaceFile
Request body (application/json or urlencoded):
{
"id": "3fa1c7409df3a2d4bbf7d33d5e6f7c18",
"replaceHname": "file.ax",
"replacePath": "old-link",
"newFilename": "new-name.mp4",
"reinferContentType": true
}
Success response (200):
{
"success": true,
"link": "old-link",
"hname": "file.ax",
"oldLink": "old-link_old",
"newFilename": "new-name.mp4"
}
POST /api/edit/:hname/:path
Request headers:
Content-Type: application/json(required)
Request body example (metadata update):
{
"manager": "manager_token",
"filename": "renamed.mp4",
"contentType": "video/mp4",
"password": "optional-file-password",
"expiry": "2030-01-01T00:00:00.000Z",
"forceDownload": true,
"skipEmbeddedPage": false,
"path": "custom-link",
"hname": "file.ax"
}
Delete example:
{ "manager": "manager_token", "delete": true }
Success response (200):
- Update: full updated file metadata object.
- Delete:
{ "success": true }
PATCH /api/files/:id/folder
Request headers:
Content-Type: application/json(required)
Request body:
{ "folderId": 123 }
Success response (200):
{ "success": true, "id": 987, "folderId": 123 }
POST /api/files/move
Request headers:
Content-Type: application/json(required)
Request body:
{ "fileIds": [987, 988], "folderId": 123 }
Success response (200):
{ "success": true, "moved": 2, "ids": [987, 988] }
POST /api/shorten
Request body (application/json or urlencoded):
{
"_token": "access_or_upload_token",
"_manager": "manager_token",
"folderId": 123,
"dest": "https://example.com/docs",
"expiry": "2030-01-01T00:00:00.000Z",
"path": "docs",
"hname": "file.ax"
}
Success response (200):
{
"success": true,
"link": "docs",
"hname": "file.ax",
"dest": "https://example.com/docs"
}
POST /api/html/paste
Request format:
- Multipart form (no file)
- Required fields:
text,pasteCSRF
Example:
curl -X POST https://file.ax/api/html/paste \
-F "text=hello world" \
-F "pasteCSRF=<session_csrf>" \
-F "expiry=7d" \
-F "folderId=123" \
-F "extension=txt" \
-F "manager=<manager_token>"
Success response:
302redirect tohttps://<hname>/<path>
Failure example (403):
{ "error": "Invalid CSRF token" }
GET /api/editPaste/:hname/:path
Behavior:
- If session owns the file, returns paste editor HTML.
- If not owner or invalid file, redirects to public file URL or
https://file.ax.