File Upload Chunked upload flow, web upload (URL import), status polling, and upload management.

Base URL: https://api.fast.io/current/ Auth: Bearer {jwt_token} Format: multipart/form-data (file data) · application/x-www-form-urlencoded (non-file)

Overview

Fast.io supports three upload flows:

  1. Small files (< 4 MB) — Single-request upload. Send the file as a multipart chunk in the session creation request. Optionally auto-add to storage in the same call.
  2. Large files (≥ 4 MB) — Chunked upload. Create a session, upload chunks (up to 3 in parallel), trigger assembly, poll until stored.
  3. Web upload (URL import) — Import files from any HTTP/HTTPS URL. The server downloads and uploads the file asynchronously.

Both direct upload flows produce an upload session with a unique id (OpaqueId). Once the upload reaches stored status, the file is ready to use.

Upload Constraints

ConstraintValue
Single-call upload max size4 MB (4,194,304 bytes)
Chunk sizePlan-dependent (query /upload/limits/ for exact values)
Last chunkMay be smaller than the plan chunk size
Max parallel chunk uploads per session3
Max undersized chunks per session1 (the final chunk only)
Chunk ordering1-based (first chunk is order=1)
Supported hash algorithmsmd5, sha1, sha256, sha384
relative_path max length8192 characters
relative_pathOmit entirely if empty — do NOT send as empty string
creator format1–150 chars, alphanumeric and hyphens only (/^[a-zA-Z0-9\-]+$/)
Max file sizePlan-dependent (up to 40 GB)
Max concurrent sessionsPlan-dependent (150 for Free, 7500 for Pro/Business)
Long-poll max wait590 seconds

Upload Status Values

StatusMeaningAction
readySession created, awaiting chunksUpload chunks
uploadingChunks being receivedContinue uploading
assembleAssembly queuedKeep polling
assemblingAssembly in progressKeep polling
completeAssembly done, awaiting storage importKeep polling (or use addfile if not auto-adding)
storeStorage import queuedKeep polling
storingBeing imported to storageKeep polling
storedFully complete — file assembled and in storageDone. new_file_id available.
assembly_failedAssembly failedHandle error
store_failedStorage import failedHandle error

Terminal states: stored, assembly_failed, store_failed. Stop polling when you reach one of these.

Workflow: Small File Upload (< 4 MB)

A single request creates the session and uploads the file. Optionally auto-adds to storage.

Step 1: Upload in one request

POST /current/upload/

Create upload session and send file data in a single request.

Content-Type: multipart/form-data

Parameters

ParameterTypeRequiredDescription
namestringYesFile name including extension (1–255 chars)
sizeintegerYesFile size in bytes (must match actual file)
chunkfileYesThe file binary data (multipart field)
actionstringNo"create" for new file, "update" for file replacement
instance_idstringRequired if action=createWorkspace or share profile ID (20-digit numeric)
file_idstringRequired if action=updateOpaqueId of the existing file to replace
folder_idstringNoTarget folder OpaqueId or "root" for storage root
hashstringNoHash of the full file. Must be provided with hash_algo.
hash_algostringNoHash algorithm: "md5", "sha1", "sha256", or "sha384"
relative_pathstringNoFor folder uploads, relative path for auto folder creation (max 8192 chars). Omit entirely if not applicable.
orgstringNoOrganization ID for billing limit resolution (only used when no action is specified)
creatorstringNoClient identifier string (1–150 chars, alphanumeric and hyphens only)

Example (small file with auto-add to workspace)

curl -X POST "https://api.fast.io/current/upload/" \
  -H "Authorization: Bearer {jwt_token}" \
  -F "name=notes.txt" \
  -F "size=1024" \
  -F "action=create" \
  -F "instance_id=12345678901234567890" \
  -F "folder_id=root" \
  -F "chunk=@notes.txt"

Response (201 Created)

{
  "result": "yes",
  "response": {
    "id": "u1abc-defgh-ijklm-nopqr-stuvw-xyz123",
    "creator": "my-web-client",
    "new_file_id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4"
  },
  "current_api_version": "1.0"
}

Response fields

FieldTypeDescription
resultstring"yes" on success
response.idstringUpload session OpaqueId
response.creatorstringEchoed back only if creator was provided in the request
response.new_file_idstringOpaqueId of the created storage node. Only present for single-call uploads with an upload target (instance_id).

When instance_id and folder_id are provided, the file is automatically added to storage. No separate polling or addfile step is needed.

Response (without instance_id, 201 Created)

{
  "result": "yes",
  "response": {
    "id": "u1abc-defgh-ijklm-nopqr-stuvw-xyz123"
  },
  "current_api_version": "1.0"
}

Without a target, only the upload session id is returned. Use addfile to place the file in storage after the upload completes.

Error responses

Error CodeHTTP StatusMessage
APP_ERROR_INPUT_INVALID400"The size was not supplied."
APP_ERROR_INPUT_INVALID400"The file name is not valid."
APP_ERROR_INPUT_INVALID400"Invalid share or workspace instance ID."
APP_NOT_ACCEPTABLE406"This file type is not allowed for upload on your plan."
APP_FEATURE_LIMIT403"The file size exceeds single call upload, use chunks."
APP_FEATURE_LIMIT403"You have created too many upload sessions..."
APP_FEATURE_LIMIT403"The size is too large for the account plan."
APP_FEATURE_LIMIT403"The total size of all active upload sessions exceeds the limit."
APP_ERROR_INPUT_INVALID400"The hash algorithm provided is not valid."
APP_ERROR_INPUT_INVALID400"The hash provided is not valid."
APP_ERROR_INPUT_INVALID400"The hash algorithm was provided but not the hash."
APP_NOT_ACCEPTED406"We were unable to create the upload session..."

Workflow: Large File Upload (Chunked)

Step 1: Create upload session

POST /current/upload/

Create a new upload session for a large file.

Content-Type: application/x-www-form-urlencoded

Parameters

ParameterTypeRequiredDescription
namestringYesFile name including extension (1–255 chars)
sizeintegerYesTotal file size in bytes
actionstringYes"create" for new file, "update" for file replacement
instance_idstringRequired if action=createWorkspace or share profile ID (20-digit numeric) for auto-add to storage after assembly
file_idstringRequired if action=updateOpaqueId of existing file to replace
folder_idstringNoTarget folder OpaqueId or "root" for storage root
hashstringNoSHA-256 hex hash of the full file for integrity verification. Must be provided with hash_algo.
hash_algostringNoHash algorithm: "md5", "sha1", "sha256", or "sha384"
relative_pathstringNoFor folder uploads, relative path for auto folder creation (max 8192 chars). Omit entirely if not applicable.
orgstringNoOrganization ID for billing limit resolution (only used when no action is specified)
creatorstringNoClient identifier string (1–150 chars, alphanumeric and hyphens only)

Example

curl -X POST "https://api.fast.io/current/upload/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d "name=annual-report.pdf" \
  -d "size=52428800" \
  -d "action=create" \
  -d "instance_id=12345678901234567890" \
  -d "hash_algo=sha256" \
  -d "hash=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

Response (201 Created)

{
  "result": "yes",
  "response": {
    "id": "u1abc-defgh-ijklm-nopqr-stuvw-xyz123"
  },
  "current_api_version": "1.0"
}

Step 2: Upload chunks

POST /current/upload/{upload_id}/chunk/?order={n}&size={bytes}

Upload a single chunk of file data.

Content-Type: multipart/form-data

Path parameters

ParameterTypeRequiredDescription
{upload_id}stringYesThe upload session ID from Step 1

Query parameters

ParameterTypeRequiredDescription
orderintegerYes1-based chunk number (first chunk = 1). Must not exceed plan's chunk limit.
sizeintegerYesSize of this chunk in bytes. Must match the actual uploaded file size.
hashstringNoHash of this chunk. Must be provided with hash_algo.
hash_algostringNoHash algorithm: "md5", "sha1", "sha256", or "sha384"

Request body (multipart/form-data)

FieldTypeRequiredDescription
chunkfileYesBinary chunk data

Upload up to 3 chunks in parallel. The last chunk may be smaller. Only 1 undersized chunk is allowed per session.

When all chunks have been uploaded (total bytes equal the declared file size), auto-finalization triggers automatically. You can still call the complete endpoint explicitly.

Example

curl -X POST "https://api.fast.io/current/upload/u1abc-defgh-ijklm-nopqr-stuvw-xyz123/chunk/?order=1&size=5242880&hash_algo=sha256&hash=abc123def456..." \
  -H "Authorization: Bearer {jwt_token}" \
  -F "chunk=@chunk_001.bin"

Response (202 Accepted)

{
  "result": "yes",
  "current_api_version": "1.0"
}

Error responses

Error CodeHTTP StatusMessage
APP_ERROR_INPUT_INVALID400"The session id provided is not valid."
APP_NOT_ACCEPTABLE406"The session id provided is not in a valid state to accept a chunk."
APP_ERROR_INPUT_INVALID400"No order supplied"
APP_ERROR_INPUT_INVALID400"The order provided for this chunk is not valid..."
APP_ERROR_INPUT_INVALID400"The size was not supplied."
APP_FEATURE_LIMIT403"The size is too large for the account plan."
APP_FEATURE_LIMIT403"The size is too small for the account plan."
APP_FEATURE_LIMIT403"You have exceeded the maximum number of chunks..."
APP_FEATURE_LIMIT403"The combined chunk size exceeds the size for this session."
APP_ERROR_INPUT_INVALID400"The upload chunk failed or was the wrong size..."
APP_ERROR_INPUT_INVALID400"The chunk failed to hash properly..."
APP_INTERNAL_ERROR500"The chunk failed to be stored..."

Step 3: Trigger assembly

POST /current/upload/{upload_id}/complete/

Trigger asynchronous assembly of all uploaded chunks.

Path parameters

ParameterTypeRequiredDescription
{upload_id}stringYesThe upload session ID

Query parameters (optional)

ParameterTypeRequiredDescription
hashstringNoFinal file hash for validation. Can be provided/updated at completion time. Must be provided with hash_algo.
hash_algostringNoHash algorithm: "md5", "sha1", "sha256", or "sha384"

No body parameters required. If the session is already in a completed or processing state (complete, assemble, assembling, store, storing, stored), the endpoint returns 200 OK immediately without error.

Example

curl -X POST "https://api.fast.io/current/upload/u1abc-defgh-ijklm-nopqr-stuvw-xyz123/complete/" \
  -H "Authorization: Bearer {jwt_token}"

Response (202 Accepted)

{
  "result": "yes",
  "current_api_version": "1.0"
}

Error responses

Error CodeHTTP StatusMessage
APP_MISSING404"The id provided is not found..."
APP_NOT_ACCEPTABLE406"The session id provided is not in a valid state to assemble."
APP_NOT_ACCEPTABLE406"No chunks have been uploaded to this session."
APP_NOT_ACCEPTABLE406"The chunks provided do not match the size of the file."
APP_FEATURE_LIMIT403"You have created too many upload sessions..."
APP_ENQUEUE_FAILED500"Your request was valid but could not be processed."

Step 4: Poll for completion

GET /current/upload/{upload_id}/details/?wait=60

Get upload session status with optional long-poll.

Path parameters

ParameterTypeRequiredDescription
{upload_id}stringYesThe upload session ID

Query parameters

ParameterTypeRequiredDefaultDescription
waitintegerNoLong-poll wait time in seconds (1 to 590). Server holds the connection and returns immediately when the status changes.

The server uses Pub/Sub to detect status changes during long-poll. If Pub/Sub is unavailable, it falls back to polling every 0.5 seconds. Maximum wait is 590 seconds.

Example

curl -X GET "https://api.fast.io/current/upload/u1abc-defgh-ijklm-nopqr-stuvw-xyz123/details/?wait=60" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "session": {
      "id": "u1abc-defgh-ijklm-nopqr-stuvw-xyz123",
      "name": "annual-report.pdf",
      "size": 52428800,
      "status": "stored",
      "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
      "hash_algo": "sha256",
      "created": "2025-01-20 10:30:00",
      "updated": "2025-01-20 10:35:00",
      "chunks": {
        "1": 5242880,
        "2": 5242880,
        "3": 5242880,
        "4": 5242880,
        "5": 5242880
      }
    }
  },
  "current_api_version": "1.0"
}

Response fields

FieldTypeDescription
response.session.idstringUpload session OpaqueId
response.session.namestringFilename
response.session.sizeintegerDeclared file size in bytes
response.session.statusstringCurrent status (see status table above)
response.session.hashstringFile hash (if provided)
response.session.hash_algostringHash algorithm (if provided)
response.session.createdstringSession creation timestamp
response.session.updatedstringLast update timestamp
response.session.chunksobjectMap of chunk order (string key) to chunk size (integer value)
response.session.new_file_idstringOpaqueId of created storage node (only when stored with a target)

Exit condition: Stop polling when status is stored, assembly_failed, or store_failed.

Step 5 (if no instance_id): Add file to storage manually

POST /current/workspace/{workspace_id}/storage/{folder_id}/addfile/

Add a completed upload to workspace storage.

Or for shares:

POST /current/share/{share_id}/storage/{folder_id}/addfile/

Add a completed upload to share storage.

Path parameters

Body parameters

ParameterTypeRequiredDescription
fromstring (JSON)YesSource specification as JSON-encoded string

from format

from={"type":"upload","upload":{"id":"{upload_id}"}}

Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/root/addfile/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'from={"type":"upload","upload":{"id":"u1abc-defgh-ijklm-nopqr-stuvw-xyz123"}}'

Step 6 (optional): Clean up session

DELETE /current/upload/{upload_id}

Delete an upload session and clean up temporary files.

Complete Chunked Upload Example

1. Create session (25 MB file, 5 chunks)

curl -X POST "https://api.fast.io/current/upload/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d "name=presentation.pptx" \
  -d "size=26214400" \
  -d "action=create" \
  -d "instance_id=12345678901234567890" \
  -d "folder_id=root"

Response:

{"result": "yes", "response": {"id": "u1abc-defgh-ijklm-nopqr-stuvw-xyz123"}, "current_api_version": "1.0"}

2. Upload 5 chunks (3 in parallel, then 2 more)

# Chunks 1-3 in parallel
curl -X POST "https://api.fast.io/current/upload/u1abc-.../chunk/?order=1&size=5242880" \
  -H "Authorization: Bearer {jwt_token}" -F "chunk=@chunk1.bin" &

curl -X POST "https://api.fast.io/current/upload/u1abc-.../chunk/?order=2&size=5242880" \
  -H "Authorization: Bearer {jwt_token}" -F "chunk=@chunk2.bin" &

curl -X POST "https://api.fast.io/current/upload/u1abc-.../chunk/?order=3&size=5242880" \
  -H "Authorization: Bearer {jwt_token}" -F "chunk=@chunk3.bin" &
wait

# Chunks 4-5
curl -X POST ".../chunk/?order=4&size=5242880" \
  -H "Authorization: Bearer {jwt_token}" -F "chunk=@chunk4.bin" &
curl -X POST ".../chunk/?order=5&size=5242880" \
  -H "Authorization: Bearer {jwt_token}" -F "chunk=@chunk5.bin" &
wait

3. Trigger assembly

curl -X POST "https://api.fast.io/current/upload/u1abc-.../complete/" \
  -H "Authorization: Bearer {jwt_token}"

4. Poll until stored

curl -X GET "https://api.fast.io/current/upload/u1abc-.../details/?wait=60" \
  -H "Authorization: Bearer {jwt_token}"

Response: {"result": "yes", "response": {"session": {"status": "assembling", ...}}} — keep polling

curl -X GET "https://api.fast.io/current/upload/u1abc-.../details/?wait=60" \
  -H "Authorization: Bearer {jwt_token}"

Response: {"result": "yes", "response": {"session": {"status": "stored", "new_file_id": "f3jm5-...", ...}}} — done

5. Clean up session

curl -X DELETE "https://api.fast.io/current/upload/u1abc-defgh-ijklm-nopqr-stuvw-xyz123" \
  -H "Authorization: Bearer {jwt_token}"

Resume a Disconnected Upload

If an upload is interrupted (network failure, client crash), resume it without re-uploading completed chunks.

Steps

  1. Get session status:
    curl -X GET "https://api.fast.io/current/upload/{upload_id}/details/" \
      -H "Authorization: Bearer {jwt_token}"
  2. Read the chunks map in the response. Keys are chunk numbers already uploaded, values are byte sizes.
  3. Upload only missing chunks. Compare the chunks map against the expected chunk list. Upload any chunks not present.
  4. Trigger assembly:
    curl -X POST "https://api.fast.io/current/upload/{upload_id}/complete/" \
      -H "Authorization: Bearer {jwt_token}"
  5. Poll for completion as normal.

File Update (New Version)

To upload a new version of an existing file:

  1. Create session with action=update, instance_id, and file_id (OpaqueId of the file to replace).
  2. Upload chunks and complete as normal. The existing file receives a new version.
curl -X POST "https://api.fast.io/current/upload/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d "name=report-v2.pdf" \
  -d "size=1024" \
  -d "action=update" \
  -d "instance_id=12345678901234567890" \
  -d "file_id=f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4" \
  -F "chunk=@report-v2.pdf"

Web Upload (URL Import)

Import files from any HTTP/HTTPS URL. Supports OAuth-protected URLs (Google Drive, OneDrive, Dropbox, Box, iCloud). The server downloads the file in the background and streams it through the standard upload pipeline.

Create web upload job

POST /current/web_upload/

Create a new web upload job to import a file from a URL.

Content-Type: application/json

Parameters

ParameterTypeRequiredDescription
source_urlstringYesURL to download the file from. Only HTTP/HTTPS supported. Max 2048 characters.
file_namestringYesFilename to save as (1–255 chars)
profile_idstringYesTarget workspace or share profile ID (20-digit numeric)
profile_typestringYes"workspace" or "share"
folder_idstringNoTarget folder OpaqueId or "root" for storage root
relative_pathstringNoRelative path for automatic folder creation (1–8192 chars)
optionsintegerNoBitfield options (default: 0). See options table.
creatorstringNoClient identifier string (1–150 chars, alphanumeric and hyphens only)

Options bitfield

BitValueDescription
00x1Overwrite if a file with the same name exists at the destination
10x2Skip virus scanning (admin only)
20x4Attempt to preserve source file metadata

Example

curl -X POST "https://api.fast.io/current/web_upload/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "source_url": "https://example.com/files/document.pdf",
    "file_name": "document.pdf",
    "profile_id": "12345678901234567890",
    "profile_type": "workspace",
    "folder_id": "root"
  }'

Response (201 Created)

{
  "result": "yes",
  "response": {
    "web_upload": {
      "id": "aBcDeFgHiJkLmNoPqRsT123456",
      "user_id": "12345678901234567890",
      "profile_id": "12345678901234567890",
      "profile_type": 1,
      "source_url": "https://example.com/files/document.pdf",
      "file_name": "document.pdf",
      "folder_id": null,
      "relative_path": null,
      "status": 2,
      "bytes_downloaded": 0,
      "expected_size": null,
      "upload_session_id": null,
      "async_job_id": null,
      "error_message": null,
      "options": 0,
      "properties": null,
      "created": "2025-01-26 15:00:00",
      "updated": "2025-01-26 15:00:00"
    }
  },
  "current_api_version": "1.0"
}

Response fields

FieldTypeDescription
response.web_upload.idstringWeb upload job OpaqueId
response.web_upload.user_idstringID of the user who created the job
response.web_upload.profile_idstringTarget workspace or share ID
response.web_upload.profile_typeinteger1 = workspace, 2 = share
response.web_upload.source_urlstringThe source URL
response.web_upload.file_namestringDestination filename
response.web_upload.folder_idstring/nullTarget folder OpaqueId
response.web_upload.relative_pathstring/nullRelative path for folder creation
response.web_upload.statusintegerStatus code (initially 2 = QUEUED)
response.web_upload.bytes_downloadedintegerBytes downloaded so far (0 initially)
response.web_upload.expected_sizeinteger/nullExpected file size (from HEAD request, if known)
response.web_upload.upload_session_idstring/nullLinked upload session ID (populated during uploading phase)
response.web_upload.error_messagestring/nullError details if failed
response.web_upload.optionsintegerOptions bitfield
response.web_upload.createdstringCreation timestamp
response.web_upload.updatedstringLast update timestamp

Error responses

Error CodeHTTP StatusMessage
APP_ERROR_INPUT_INVALID400"Invalid URL. Only HTTP and HTTPS URLs are supported."
APP_ERROR_INPUT_INVALID400"Invalid profile_type. Must be \"workspace\" or \"share\"."
APP_DENIED403"You do not have permission to upload to this workspace."
APP_DENIED403"You do not have permission to upload to this share."
APP_NOT_ACCEPTABLE406"You have too many active web uploads..."
APP_INTERNAL_ERROR500"Failed to create web upload job."

OAuth for protected URLs

For Google Drive, OneDrive, and other OAuth-protected files, include the access token as a query parameter in the source URL:

https://www.googleapis.com/drive/v3/files/{fileId}?alt=media&access_token={oauth_token}

The server extracts the token from the URL, removes it from the query string, and sends it as an Authorization: Bearer header on all HTTP requests. Tokens are never logged or returned in API responses.

List web upload jobs

GET /current/web_upload/

List all web upload jobs for the current user.

Query parameters

ParameterTypeRequiredDefaultDescription
limitintegerNo50Maximum number of results (1–100)
offsetintegerNo0Pagination offset
statusstringNoFilter by status: "pending", "queued", "downloading", "uploading", "complete", "failed", "canceled"

Example

curl -X GET "https://api.fast.io/current/web_upload/?status=downloading&limit=20" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "web_uploads": [
      {
        "id": "aBcDeFgHiJkLmNoPqRsT123456",
        "user_id": "12345678901234567890",
        "profile_id": "12345678901234567890",
        "profile_type": "workspace",
        "source_url": "https://example.com/files/document.pdf",
        "file_name": "document.pdf",
        "folder_id": null,
        "relative_path": null,
        "status": "downloading",
        "status_description": "Downloading file from URL",
        "bytes_downloaded": 5242880,
        "expected_size": 52428800,
        "progress_percent": 10,
        "upload_session_id": null,
        "error_message": null,
        "created": "2025-01-26 15:00:00",
        "updated": "2025-01-26 15:01:00"
      }
    ],
    "total": 1,
    "limit": 20,
    "offset": 0
  },
  "current_api_version": "1.0"
}

Response fields

FieldTypeDescription
response.web_uploadsarrayArray of web upload job objects
response.web_uploads[].idstringWeb upload job OpaqueId
response.web_uploads[].profile_typestring"workspace" or "share"
response.web_uploads[].statusstringStatus string (e.g., "downloading", "complete")
response.web_uploads[].status_descriptionstringHuman-readable status description
response.web_uploads[].bytes_downloadedintegerBytes downloaded so far
response.web_uploads[].expected_sizeinteger/nullExpected file size (null if unknown)
response.web_uploads[].progress_percentintegerDownload progress percentage (0–100)
response.web_uploads[].upload_session_idstring/nullLinked upload session ID
response.web_uploads[].error_messagestring/nullError details if failed
response.totalintegerTotal count of matching records
response.limitintegerApplied limit
response.offsetintegerApplied offset

Get web upload job details

GET /current/web_upload/{upload_id}/details/

Get details for a specific web upload job.

Path parameters

ParameterTypeRequiredDescription
{upload_id}stringYesThe web upload job OpaqueId

Example

curl -X GET "https://api.fast.io/current/web_upload/aBcDeFgHiJkLmNoPqRsT123456/details/" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "web_upload": {
      "id": "aBcDeFgHiJkLmNoPqRsT123456",
      "user_id": "12345678901234567890",
      "profile_id": "12345678901234567890",
      "profile_type": 1,
      "source_url": "https://example.com/files/document.pdf",
      "file_name": "document.pdf",
      "status": 5,
      "bytes_downloaded": 52428800,
      "expected_size": 52428800,
      "upload_session_id": "xYzAbCdEfGhIjKlMnOpQ123456",
      "error_message": null,
      "options": 0,
      "created": "2025-01-26 15:00:00",
      "updated": "2025-01-26 15:02:00"
    }
  },
  "current_api_version": "1.0"
}

Note: The details endpoint returns raw status integers (not the string names used in the list endpoint).

Error responses

Error CodeHTTP StatusMessage
APP_ERROR_NOT_FOUND404"Web upload job not found."
APP_DENIED403"You do not have permission to view this web upload job."

Cancel web upload job

DELETE /current/web_upload/?id={web_upload_id}

Cancel an active web upload job.

Query parameters

ParameterTypeRequiredDescription
idstringYesThe web upload job OpaqueId to cancel

Example

curl -X DELETE "https://api.fast.io/current/web_upload/?id=aBcDeFgHiJkLmNoPqRsT123456" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "canceled": true,
    "id": "aBcDeFgHiJkLmNoPqRsT123456"
  },
  "current_api_version": "1.0"
}

Error responses

Error CodeHTTP StatusMessage
APP_ERROR_NOT_FOUND404"Web upload job not found."
APP_DENIED403"You do not have permission to cancel this web upload job."
APP_NOT_ACCEPTABLE406"This web upload job cannot be canceled because it is already in a terminal state."
APP_INTERNAL_ERROR500"Failed to cancel web upload job."

Web Upload Status Values

StatusValueDescriptionTerminal
pending1Job created, waiting for async job pickupNo
queued2Async job has been queued for processingNo
downloading3Actively downloading from the source URLNo
uploading4Feeding downloaded chunks to upload systemNo
complete5Upload successfully completedYes
failed6Download or upload failedYes
canceled7User canceled the web uploadYes

Web Upload Limits

LimitValue
Max active per user50 (non-terminal jobs)
Max file sizeUp to 40 GB (subject to plan limits)
Max retries3 (automatic on transient failures)
Retry delay60 seconds between attempts

Upload Management Endpoints

List all upload sessions

GET /current/upload/details/

Returns all upload sessions for the current user in any state.

Example

curl -X GET "https://api.fast.io/current/upload/details/" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "results": 2,
    "sessions": [
      {
        "id": "aBcDeFgHiJkLmNoPqRsT123456",
        "name": "document.pdf",
        "size": 52428800,
        "status": "uploading",
        "hash": "e3b0c44298fc1c14...",
        "hash_algo": "sha256",
        "created": "2025-01-20 10:30:00",
        "updated": "2025-01-20 10:35:00"
      }
    ]
  },
  "current_api_version": "1.0"
}

Response fields

FieldTypeDescription
response.resultsintegerTotal number of sessions (only present when > 1)
response.sessionsarrayArray of upload session objects

Delete/cancel an upload session

DELETE /current/upload/{upload_id}

Cancel and delete an active upload session.

Path parameters

ParameterTypeRequiredDescription
{upload_id}stringYesThe upload session ID to delete (appended to URL path)

Cleans up temporary chunk files and releases session quota. If the session has an associated web upload job, that job is automatically canceled.

Sessions can be deleted in states: ready, uploading, assembly_failed, store_failed, complete. Sessions in assembling, storing, or stored states cannot be deleted.

Example

curl -X DELETE "https://api.fast.io/current/upload/aBcDeFgHiJkLmNoPqRsT123456" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "current_api_version": "1.0"
}

Error responses

Error CodeHTTP StatusMessage
APP_ERROR_INPUT_INVALID400"The id provided is not found or is not associated with your account."
APP_NOT_ACCEPTABLE406"The session id provided is not in a valid state to delete."
APP_INTERNAL_ERROR500"We were unable to delete the requested upload session."

Get upload limits

GET /current/upload/limits/

Returns upload limits based on the user's billing plan and target context.

Query parameters

ParameterTypeRequiredDefaultDescription
actionstringNo"create" or "update" to get limits in context of a target
orgstringNoOrganization ID for limit resolution (used when no action specified)
instance_idstringRequired if action=createTarget workspace or share ID
folder_idstringNoTarget folder OpaqueId or "root"
file_idstringRequired if action=updateFile ID for update context

Example

# General limits (with org context)
curl -X GET "https://api.fast.io/current/upload/limits/?org=12345678901234567890" \
  -H "Authorization: Bearer {jwt_token}"

# Limits for creating a file in a workspace
curl -X GET "https://api.fast.io/current/upload/limits/?action=create&instance_id=12345678901234567890" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "limits": {
      "chunk_size": 104857600,
      "size": 42949672960,
      "chunks": 500,
      "sessions": 7500,
      "sessions_size_max": 214748364800
    }
  },
  "current_api_version": "1.0"
}

Response fields

FieldTypeDescription
response.limits.chunk_sizeintegerMaximum size of a single chunk in bytes
response.limits.sizeintegerMaximum total file size in bytes
response.limits.chunksintegerMaximum number of chunks per upload session
response.limits.sessionsintegerMaximum concurrent active upload sessions
response.limits.sessions_size_maxintegerMaximum aggregate size of all active sessions in bytes

Get restricted file extensions

GET /current/upload/limits/extensions/

Returns restricted and archive file extensions. Authentication is optional.

Query parameters

ParameterTypeRequiredDefaultDescription
planstringNoUser's plan or "free"Override the billing plan to check restrictions for

Example

curl -X GET "https://api.fast.io/current/upload/limits/extensions/"

# With specific plan
curl -X GET "https://api.fast.io/current/upload/limits/extensions/?plan=pro"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "restricted_extensions": [".exe", ".apk", ".jar", ".php"],
    "archive_extensions": [".7z", ".zip", ".rar", ".tar.gz", ".bz2"],
    "enforcement_enabled": true,
    "plan": "free",
    "cache_ttl": 86400
  },
  "current_api_version": "1.0"
}

Response fields

FieldTypeDescription
response.restricted_extensionsstring[]Extensions blocked for the plan
response.archive_extensionsstring[]Archive extensions (only populated if the plan restricts archives)
response.enforcement_enabledbooleanWhether extension restriction enforcement is currently active
response.planstringThe plan used for this response
response.cache_ttlintegerSuggested client-side cache TTL in seconds (86400 = 24 hours)

Clients should call this once on startup and cache the results for 24 hours.

List supported hash algorithms

GET /current/upload/algos/

Returns the list of supported hash algorithms for upload integrity verification.

Example

curl -X GET "https://api.fast.io/current/upload/algos/" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "algos": ["md5", "sha1", "sha256", "sha384"]
  },
  "current_api_version": "1.0"
}

Get chunk information

GET /current/upload/{upload_id}/chunk/

Returns information about uploaded chunks for a session.

Query parameters

ParameterTypeRequiredDescription
orderintegerNoSpecific chunk number to retrieve. If omitted, returns all chunks.

Example (all chunks)

curl -X GET "https://api.fast.io/current/upload/aBcDeFgHiJkLmNoPqRsT123456/chunk/" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK, all chunks)

{
  "result": "yes",
  "response": {
    "chunks": {
      "1": 5242880,
      "2": 5242880,
      "3": 2097152
    }
  },
  "current_api_version": "1.0"
}

Response (200 OK, single chunk with ?order=1)

{
  "result": "yes",
  "response": {
    "chunk": {
      "1": 5242880
    }
  },
  "current_api_version": "1.0"
}

Error responses

Error CodeHTTP StatusMessage
APP_ERROR_NOT_FOUND404"The supplied chunk not valid or found."

Delete a chunk

DELETE /current/upload/{upload_id}/chunk/?order={n}

Delete a specific chunk from an upload session. Session must be in uploading state.

Query parameters

ParameterTypeRequiredDescription
orderintegerYesThe chunk number to delete

Example

curl -X DELETE "https://api.fast.io/current/upload/aBcDeFgHiJkLmNoPqRsT123456/chunk/?order=3" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "current_api_version": "1.0"
}

Error responses

Error CodeHTTP StatusMessage
APP_NOT_ACCEPTABLE406"The session id provided is not in a valid state to delete a chunk."
APP_INTERNAL_ERROR500"We were unable to delete the requested upload session chunk."

Quick Reference

Small file (one request, auto-add)

POST /current/upload/
  multipart: name, size, chunk, action=create, instance_id, folder_id
  -> 201: {id, new_file_id}

Large file (chunked)

POST /current/upload/                              # Create session
  form: name, size, action=create, instance_id, folder_id
  -> 201: {id}

POST /current/upload/{id}/chunk/?order=N&size=N    # Upload chunks (up to 3 parallel)
  multipart: chunk
  -> 202

POST /current/upload/{id}/complete/                # Trigger assembly
  -> 202

GET  /current/upload/{id}/details/?wait=60         # Poll until stored
  -> 200: {session: {status, new_file_id}}

DELETE /current/upload/{id}                        # Clean up session
  -> 200

Manual add to storage (if no instance_id)

POST /current/workspace/{id}/storage/{folder}/addfile/
  form: from={"type":"upload","upload":{"id":"{upload_id}"}}
  -> 200

Web upload (URL import)

POST /current/web_upload/                          # Create job
  json: source_url, file_name, profile_id, profile_type
  -> 201: {web_upload}

GET  /current/web_upload/                          # List jobs
  query: limit, offset, status
  -> 200: {web_uploads, total}

GET  /current/web_upload/{id}/details/             # Get job details
  -> 200: {web_upload}

DELETE /current/web_upload/?id={id}                # Cancel job
  -> 200: {canceled, id}

Upload management

GET  /current/upload/details/                      # List all sessions
GET  /current/upload/limits/                       # Get plan limits
GET  /current/upload/limits/extensions/            # Get restricted extensions
GET  /current/upload/algos/                        # List hash algorithms
GET  /current/upload/{id}/chunk/                   # Get chunk info
DELETE /current/upload/{id}/chunk/?order=N          # Delete a chunk

Best Practices

↑ Back to top