API Documentation

Upload and Edit APIs

Upload and Edit APIs

Shared Concepts

  • hname: host/domain where link is allocated (file.ax, file.wf, file.yt, kt.ci, gatto.me with 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 folderId as “use scope root”
    • provided folderId must be the scoped folder or one of its descendants
    • edit/move/replace operations are rejected for files outside that subtree
  • 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

  1. Initialize with filename + full size.
  2. Split file client-side into numbered chunks (chunk=1, chunk=2, …).
  3. Upload each chunk with upload id.
  4. Retry failed chunks only.
  5. Optionally poll status.
  6. Finalize after all chunks are uploaded.
  7. 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> or X-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:

  • 302 redirect to https://<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.