Storage Operations File and folder operations, locking, previews, and transforms

Base URL: https://api.fast.io/current/ Auth: Bearer JWT

Storage endpoints are available on both workspaces and shares. The API patterns are identical — replace workspace/{workspace_id} with share/{share_id} in any path below unless noted as workspace-only or share-only.

All endpoints require JWT authentication unless otherwise noted. Include the header Authorization: Bearer {jwt_token} with every request.

Conventions

Node Object Schema

All endpoints that return node data use this format. Fields vary by node type.

FieldTypePresent OnDescription
idstringallOpaqueId of the node
namestringallFile, folder, or note name
typestringall"file", "folder", "note", or "link"
parentstringallParent folder OpaqueId or "root"
sizeintegerfileFile size in bytes
hashstringfileContent hash of the file
hash_algostringfileHash algorithm (e.g., "md5")
mimetypestringfileMIME type (e.g., "application/pdf")
mimecategorystringfileMIME category (e.g., "document", "image")
versionstringfile, noteCurrent version identifier (e.g., "v1")
createdstringallISO 8601 creation timestamp
modifiedstringallISO 8601 last-modified timestamp
restrictedbooleanallWhether the file has been restricted
dmcabooleanallWhether the file has a DMCA flag
lockedbooleanallWhether the node has an active lock
lock_infoobject/nullallLock details when locked; null otherwise
virusobjectfileVirus scan status: {"status": "scanned", "infected": false}
file_attributesobjectfileMedia metadata: width, height, duration (where applicable)
summaryobjectfileAI-generated summary: {"title": "...", "short": "...", "long": "..."}
metadataobject/nullfileUser-defined custom title and description overrides
previewsobjectfilePreview generation state per type (e.g., {"thumbnail": {"state": "ready"}})
aiobjectfileAI processing state: {"state": "...", "attach": true/false}
originobjectfileOrigin info: {"type": "upload", "creator": "{user_id}"}

AI States

ValueDescription
disabledAI processing is disabled for this file
pendingQueued for AI processing
inprogressAI processing is running
readyAI processing complete
failedAI processing failed
indexedFile has been indexed for search and RAG

Keyset Pagination (Storage List)

Storage listing endpoints (list and recent) use cursor-based pagination, not offset-based.

Request Parameters

ParameterTypeDefaultDescription
sort_bystringnameOne of: name, updated, created, type
sort_dirstringascOne of: asc, desc
page_sizeint100One of: 100, 250, 500 (snapped to nearest)
cursorstringOpaque cursor string from previous response

Response Pagination Fields

FieldTypeDescription
pagination.has_morebooleanWhether more pages exist
pagination.next_cursorstring/nullCursor for the next page; null if last page
pagination.page_sizeintegerEffective page size used

Notes:

List Folder Contents

GET /current/workspace/{workspace_id}/storage/{parent_id}/list/
GET /current/share/{share_id}/storage/{parent_id}/list/

List the contents of a folder. Uses keyset pagination.

Auth required. Permission: View (workspace), Guest+ (share). Share list on public shares may not require JWT.

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{parent_id}stringYesFolder OpaqueId, "root", or "trash"

Query parameters: See Keyset Pagination section above.

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/root/list/?sort_by=name&sort_dir=asc&page_size=100" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "nodes": {
      "items": [
        {
          "id": "d1abc-defgh-ijklm-nopqr-stuvw-xyz123",
          "type": "folder",
          "name": "Documents",
          "parent": "root",
          "created": "2025-01-01T00:00:00Z",
          "modified": "2025-01-20T14:45:00Z"
        },
        {
          "id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4",
          "type": "file",
          "name": "photo.jpg",
          "parent": "root",
          "size": 2048000,
          "mimetype": "image/jpeg",
          "created": "2025-01-10T09:00:00Z",
          "modified": "2025-01-10T09:00:00Z"
        }
      ],
      "path": "/",
      "parent": null
    },
    "pagination": {
      "has_more": true,
      "next_cursor": "eyJwIjoiMmFiYzEyMy4uLiIsInMi...",
      "page_size": 100
    }
  }
}

Response Fields

FieldTypeDescription
nodes.itemsarrayArray of node objects for current page
nodes.pathstringCurrent folder path
nodes.parentstring/nullParent folder ID or null for root
pagination.has_morebooleantrue if more pages exist
pagination.next_cursorstring/nullCursor for next page
pagination.page_sizeintegerActual page size used

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Folder not found
APP_ERROR_INPUT_INVALID400Node is not a folder
APP_ERROR_INPUT_INVALID400Invalid pagination cursor (tampered or mismatched)

Node Details

GET /current/workspace/{workspace_id}/storage/{node_id}/details/
GET /current/share/{share_id}/storage/{node_id}/details/

Get full details for a single node (file, folder, or note).

Auth required. Permission: View (workspace), View (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesNode OpaqueId

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/details/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "node": {
      "id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4",
      "type": "file",
      "name": "document.pdf",
      "parent": "d1abc-defgh-ijklm-nopqr-stuvw-xyz123",
      "size": 5242880,
      "hash": "d41d8cd98f00b204e9800998ecf8427e",
      "hash_algo": "md5",
      "mimetype": "application/pdf",
      "mimecategory": "document",
      "version": "v1",
      "created": "2025-01-15T10:30:00Z",
      "modified": "2025-01-20T14:45:00Z",
      "restricted": false,
      "dmca": false,
      "locked": false,
      "lock_info": null,
      "virus": { "status": "scanned", "infected": false },
      "file_attributes": { "width": null, "height": null, "duration": null },
      "summary": {
        "title": "Quarterly Report",
        "short": "Q4 financial summary",
        "long": "Comprehensive financial report covering revenue and expenses."
      },
      "metadata": null,
      "previews": {
        "thumbnail": { "state": "ready" },
        "pdf": { "state": "ready" }
      },
      "ai": { "state": "indexed", "attach": true },
      "origin": { "type": "upload", "creator": "98765432109876543210" }
    }
  }
}

Response fields: See Node Object Schema above for complete field reference.

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Node not found
APP_DENIED403No permission to view details (share only)

Add File from Upload

POST /current/workspace/{workspace_id}/storage/{parent_id}/addfile/
POST /current/share/{share_id}/storage/{parent_id}/addfile/

Add a previously uploaded file to storage.

Auth required. Permission: Guest (workspace), file creation permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{parent_id}stringYesParent folder OpaqueId or "root"

Request Body (form-encoded)

ParameterTypeRequiredDescription
namestringYesFilename for the new file
fromstringYesJSON-encoded source object (see below)

from format (workspace):

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

from format (share — also supports hash source):

{"from_type": "upload", "upload": {"upload_id": "{upload_id}"}}
{"from_type": "hash", "hash": {"hash": "{file_hash}", "hash_type": "sha256"}}

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/root/addfile/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'name=document.pdf' \
  -d 'from={"type":"upload","upload":{"id":"abc123opaqueid"}}'

Response

{
  "result": "yes",
  "response": {
    "node": {
      "id": "f4kn6-arybw-qxes3-ey9z6-cwoc4-sglhn5",
      "type": "file",
      "name": "document.pdf",
      "parent": "root",
      "size": 5242880,
      "hash": "d41d8cd98f00b204e9800998ecf8427e",
      "hash_algo": "md5",
      "mimetype": "application/pdf",
      "mimecategory": "document",
      "version": "v1",
      "created": "2025-01-15T10:30:00Z",
      "modified": "2025-01-15T10:30:00Z",
      "restricted": false,
      "dmca": false,
      "locked": false
    }
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_INPUT_INVALID400Duplicate filename in parent folder
APP_ERROR_INPUT_INVALID400Upload session not found or not associated with your account
APP_ERROR_INPUT_INVALID400Upload is not complete
APP_ERROR_NOT_FOUND404Parent folder not found
APP_ERROR_INPUT_INVALID400Parent node is not a folder
APP_ERROR_NOT_FOUND404Parent folder is in trash

Notes:

POST /current/workspace/{workspace_id}/storage/{parent_id}/addlink/

Add a share link node to workspace storage. Link nodes represent references to shares within the workspace tree.

Auth required. Permission: Guest.

Path Parameters

ParameterTypeRequiredDescription
{workspace_id}stringYes20-digit workspace profile ID
{parent_id}stringYesParent folder OpaqueId or "root"

Request Body (form-encoded)

ParameterTypeRequiredDescription
link_target_typestringYesMust be "share"
sharestringYesShare identifier to link

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/root/addlink/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'link_target_type=share' \
  -d 'share=my-share-name'

Response

{"result": "yes"}

Error Responses

Error CodeHTTP StatusDescription
APP_MISSING404Share not found or not accessible
APP_ERROR_INPUT_INVALID400Share does not belong to this workspace
APP_ERROR_INPUT_INVALID400A link to this share already exists (only one per share)

Create Folder

POST /current/workspace/{workspace_id}/storage/{parent_id}/createfolder/
POST /current/share/{share_id}/storage/{parent_id}/createfolder/

Create a new folder.

Auth required. Permission: Guest (workspace), folder creation permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{parent_id}stringYesParent folder OpaqueId or "root"

Request Body (form-encoded)

ParameterTypeRequiredDescription
namestringYesFolder name

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/root/createfolder/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'name=Documents'

Response

{
  "result": "yes",
  "response": {
    "node": {
      "id": "d2bcd-efghi-jklmn-opqrs-tuvwx-yz1234",
      "type": "folder",
      "name": "Documents",
      "parent": "root",
      "created": "2025-01-15T10:30:00Z",
      "modified": "2025-01-15T10:30:00Z",
      "restricted": false,
      "dmca": false,
      "locked": false
    }
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_INPUT_INVALID400Duplicate name in parent folder
APP_ERROR_NOT_FOUND404Parent folder not found
APP_ERROR_INPUT_INVALID400Parent node is not a folder
APP_ERROR_NOT_FOUND404Parent folder is in trash
APP_DENIED403No folder creation permission (share only)

Create Note (Workspace Only)

POST /current/workspace/{workspace_id}/storage/{parent_id}/createnote/

Create a markdown note. Notes are auto-indexed for AI when workspace intelligence is enabled.

Auth required. Permission: Guest.

Path Parameters

ParameterTypeRequiredDescription
{workspace_id}stringYes20-digit workspace profile ID
{parent_id}stringYesParent folder OpaqueId or "root"

Request Body (form-encoded)

ParameterTypeRequiredConstraintsDescription
namestringYesMust end in .mdNote name
contentstringYesMax 100 KBMarkdown content

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/root/createnote/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'name=meeting-notes.md' \
  -d 'content=# Meeting Notes\n\nDiscussed project timeline.'

Response

{
  "result": "yes",
  "response": {
    "note": {
      "id": "n5mno-pqrst-uvwxy-z1234-abcde-fghij6",
      "type": "note",
      "name": "meeting-notes.md",
      "parent": "root",
      "mimetype": "text/markdown",
      "created": "2025-01-15T10:30:00Z",
      "modified": "2025-01-15T10:30:00Z"
    }
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_INPUT_INVALID400Filename must end with .md
APP_ERROR_INPUT_INVALID400Duplicate name in parent folder
APP_ERROR_NOT_FOUND404Parent folder not found

Update Note (Workspace Only)

POST /current/workspace/{workspace_id}/storage/{node_id}/updatenote/

Update an existing note's name and/or content. Updating content creates a new version.

Auth required. Permission: Guest.

Path Parameters

ParameterTypeRequiredDescription
{workspace_id}stringYes20-digit workspace profile ID
{node_id}stringYesNote OpaqueId

Request Body (form-encoded)

ParameterTypeRequiredConstraintsDescription
namestringNoMust end in .mdNew note name
contentstringNoMax 100 KBNew markdown content

At least one of name or content is required.

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/n5mno-pqrst-uvwxy-z1234-abcde-fghij6/updatenote/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'content=# Updated Notes\n\nRevised content here.'

Response

{
  "result": "yes",
  "response": {
    "note": {
      "id": "n5mno-pqrst-uvwxy-z1234-abcde-fghij6",
      "type": "note",
      "name": "meeting-notes.md",
      "parent": "root",
      "mimetype": "text/markdown",
      "created": "2025-01-15T10:30:00Z",
      "modified": "2025-01-20T14:45:00Z"
    }
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Note not found
APP_ERROR_INPUT_INVALID400Node is not a note
APP_ERROR_NOT_FOUND404Note is in trash
APP_ERROR_INPUT_INVALID400No content or name provided
APP_ERROR_INPUT_INVALID400Duplicate name in parent folder

Update Node

POST /current/workspace/{workspace_id}/storage/{node_id}/update/
POST /current/share/{share_id}/storage/{node_id}/update/

Update a node: rename, replace content with a new upload, and/or update custom metadata. Cannot be used on Note nodes (use updatenote instead).

Auth required. Permission: Guest (workspace), file modification permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesNode OpaqueId

Request Body (form-encoded)

ParameterTypeRequiredConstraintsDescription
namestringNoNew node name
fromstringNoJSON-encodedNew file content source (same format as addfile)
metadata_titlestringNoMax 50 charsCustom title override
metadata_shortstringNoMax 2048 charsCustom short description override

At least one field should be provided.

curl Example (rename)

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/update/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'name=new-document-name.pdf'

curl Example (replace content and update metadata)

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/update/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'from={"type":"upload","upload":{"id":"upload_opaque_id"}}' \
  -d 'metadata_title=Updated Report' \
  -d 'metadata_short=Q1 2025 revision'

Response

{
  "result": "yes",
  "response": {
    "node": {
      "id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4",
      "type": "file",
      "name": "new-document-name.pdf",
      "parent": "root",
      "size": 5242880,
      "version": "v2",
      "modified": "2025-01-22T11:00:00Z"
    }
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Node not found
APP_ERROR_INPUT_INVALID400Cannot update a Note with this endpoint
APP_ERROR_NOT_FOUND404Node is in trash

Notes:

Move Node

POST /current/workspace/{workspace_id}/storage/{node_id}/move/
POST /current/share/{share_id}/storage/{node_id}/move/

Move a node to a different folder within the same storage instance.

Auth required. Permission: Guest (workspace), file modification permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesNode OpaqueId to move

Request Body (form-encoded)

ParameterTypeRequiredDescription
parentstringYesDestination folder OpaqueId or "root"

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/move/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'parent=d1abc-defgh-ijklm-nopqr-stuvw-xyz123'

Response

{"result": "yes"}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Source or destination node not found
APP_ERROR_NOT_FOUND404Source or destination is in trash
APP_ERROR_INPUT_INVALID400Cannot move a folder into itself or its subfolders
APP_DENIED403No move permission (share only)

Copy Node

POST /current/workspace/{workspace_id}/storage/{node_id}/copy/
POST /current/share/{share_id}/storage/{node_id}/copy/

Copy a node to another folder within the same storage instance. Folder copies are recursive.

Auth required. Permission: Guest (workspace), file/folder creation permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesNode OpaqueId to copy

Request Body (form-encoded)

ParameterTypeRequiredDescription
parentstringYesDestination folder OpaqueId or "root"

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/copy/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'parent=d1abc-defgh-ijklm-nopqr-stuvw-xyz123'

Response

{
  "result": "yes",
  "response": {
    "node": {
      "id": "f6qrs-tuvwx-yz123-abcde-fghij-klmno7",
      "type": "file",
      "name": "document.pdf",
      "parent": "d1abc-defgh-ijklm-nopqr-stuvw-xyz123"
    },
    "job": null
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Source or destination not found
APP_ERROR_INPUT_INVALID400Destination is not a folder
APP_ERROR_NOT_FOUND404Source or destination is in trash

Notes:

Transfer Node

POST /current/workspace/{workspace_id}/storage/{node_id}/transfer/
POST /current/share/{share_id}/storage/{node_id}/transfer/

Copy a node to a different storage instance (e.g., from workspace to share, share to workspace, or share to share). The original node remains in place.

Auth required. Permission: Guest on source + write access on destination.

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYesSource profile ID
{node_id}stringYesNode OpaqueId to transfer, or "root" for all

Request Body (form-encoded)

ParameterTypeRequiredDescription
instancestringYes20-digit destination workspace or share profile ID
parentstringYesDestination parent folder OpaqueId or "root"

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/transfer/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'instance=98765432109876543210' \
  -d 'parent=root'

Response

{
  "result": "yes",
  "response": {
    "node": {
      "id": "f7stu-vwxyz-12345-abcde-fghij-klmno8",
      "type": "file",
      "name": "document.pdf",
      "parent": "root"
    },
    "job": null
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Source node not found or outside scope
APP_DENIED403No write access to destination

Notes:

Delete Node (Move to Trash)

DELETE /current/workspace/{workspace_id}/storage/{node_id}/delete/
DELETE /current/share/{share_id}/storage/{node_id}/delete/

Move a node to trash. Pass "trash" as the {node_id} to empty the entire trash bin.

Auth required. Permission: Guest (workspace), file modification permission (share). Emptying trash on shares requires admin permission.

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesNode OpaqueId, or "trash" to empty the entire trash

curl Examples

# Delete a specific node
curl -X DELETE "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/delete/" \
  -H "Authorization: Bearer {jwt_token}"

# Empty the trash
curl -X DELETE "https://api.fast.io/current/workspace/12345678901234567890/storage/trash/delete/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "job": null
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Node not found
APP_ERROR_NOT_FOUND404Node already in trash
APP_DENIED403No delete permission (share only)
APP_DENIED403No permission to empty trash (share, non-admin)

Notes:

Purge Node (Permanent Delete)

DELETE /current/workspace/{workspace_id}/storage/{node_id}/purge/
DELETE /current/share/{share_id}/storage/{node_id}/purge/

Permanently delete a node that is already in trash. Irreversible.

Auth required. Permission: Member (workspace), admin (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesOpaqueId of the trashed node

curl Example

curl -X DELETE "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/purge/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "job": null
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Node not found
APP_ERROR_INPUT_INVALID400Node is not in trash
APP_DENIED403Insufficient permission (share, non-admin)

Restore from Trash

POST /current/workspace/{workspace_id}/storage/{node_id}/restore/
POST /current/share/{share_id}/storage/{node_id}/restore/

Restore a trashed node to its original location.

Auth required. Permission: Guest (workspace), file modification + admin (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesOpaqueId of the trashed node

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/restore/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "job": null
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Node not found
APP_ERROR_INPUT_INVALID400Node is not in trash
APP_DENIED403No restore permission (share only)

List Versions

GET /current/workspace/{workspace_id}/storage/{node_id}/versions/
GET /current/share/{share_id}/storage/{node_id}/versions/

List all versions of a file or note.

Auth required. Permission: View (workspace), file view permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesNode OpaqueId

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/versions/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "versions": [
      {
        "id": "v8abc-defgh-ijklm-nopqr-stuvw-xyz901",
        "version_number": 2,
        "created": "2025-01-20T14:45:00Z",
        "operation": "update",
        "size": 5242880,
        "hash": "abc123def456789..."
      },
      {
        "id": "v9bcd-efghi-jklmn-opqrs-tuvwx-yz0123",
        "version_number": 1,
        "created": "2025-01-15T10:30:00Z",
        "operation": "create",
        "size": 4194304,
        "hash": "def456abc789012..."
      }
    ]
  }
}

Response Fields (per version)

FieldTypeDescription
idstringVersion OpaqueId
version_numberintegerIncrementing version number
createdstringISO 8601 timestamp of this version
operationstringHow this version was created: "create", "update", "restore"
sizeintegerFile size in bytes for this version
hashstringContent hash for this version

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Node not found
APP_ERROR_INPUT_INVALID400Unsupported node type
APP_ERROR_OBJECT_INIT500Node data is corrupted

Restore Version

POST /current/workspace/{workspace_id}/storage/{node_id}/restore-version/
POST /current/share/{share_id}/storage/{node_id}/restore-version/

Restore a file to a previous version. Creates a new version pointing to the historical version's content. Both filename and content are restored.

Auth required. Permission: Guest (workspace), file modification permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesFile OpaqueId

Request Body (form-encoded)

ParameterTypeRequiredDescription
version_idstringYesOpaqueId of the version to restore

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/restore-version/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'version_id=v9bcd-efghi-jklmn-opqrs-tuvwx-yz0123'

Response

{
  "result": "yes",
  "response": {
    "new_version": {
      "id": "v0cde-fghij-klmno-pqrst-uvwxy-z12345",
      "version_number": 3,
      "created": "2025-01-25T09:00:00Z",
      "operation": "restore"
    },
    "node": {
      "id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4",
      "type": "file",
      "name": "original-name.pdf",
      "version": "v3"
    }
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Node not found
APP_ERROR_INPUT_INVALID400Can only restore file versions (not folders)
APP_ERROR_INPUT_INVALID400Cannot restore version of trashed file
APP_ERROR_NOT_FOUND404Version not found
APP_ERROR_INPUT_INVALID400Version does not belong to this file
APP_ERROR_NOT_FOUND404Version data no longer available
APP_DENIED403No permission to restore versions (share only)

Notes:

Download File (Read)

GET /current/workspace/{workspace_id}/storage/{node_id}/read/
GET /current/share/{share_id}/storage/{node_id}/read/

Download file content as binary. For notes, returns raw markdown. Supports byte-range requests for partial downloads and video streaming.

Auth: JWT or download token. Permission: View (workspace), download permission (share). With a valid token query parameter, no JWT is required.

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesFile or note OpaqueId

Query Parameters

ParameterTypeRequiredDescription
tokenstringNoDownload token from requestread (bypasses JWT auth)
version_idstringNoSpecific version OpaqueId to download

curl Examples

# Download with JWT auth
curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/read/" \
  -H "Authorization: Bearer {jwt_token}" \
  -o output.pdf

# Download with token (no JWT needed)
curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/read/?token={download_token}" \
  -o output.pdf

# Download specific version
curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/read/?version_id=v9bcd-efghi-jklmn-opqrs-tuvwx-yz0123" \
  -H "Authorization: Bearer {jwt_token}" \
  -o output_v1.pdf

# Byte-range request (streaming)
curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/read/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Range: bytes=0-1023"

Response: Binary file content streamed directly.

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404File not found
APP_ERROR_INPUT_INVALID400Can only read file or note (not folder)
APP_ERROR_NOT_FOUND404File is in trash
APP_ERROR_NOT_FOUND404Version not found
APP_ERROR_INPUT_INVALID400Version does not belong to this file
APP_ERROR_NOT_FOUND404Version data no longer available
APP_DENIED403File flagged as virus-infected (share only)

Request Download Token

GET /current/workspace/{workspace_id}/storage/{node_id}/requestread/
GET /current/share/{share_id}/storage/{node_id}/requestread/

Generate a temporary auth-free download token.

Auth required. Permission: View (workspace), download permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{node_id}stringYesFile or note OpaqueId

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/requestread/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

Usage: Append ?token={token} to the read endpoint to download without an Authorization header. Useful for opening files in browser tabs.

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404File not found
APP_ERROR_INPUT_INVALID400Can only read file or note
APP_ERROR_NOT_FOUND404File is in trash
APP_DENIED403No download permission (share only)

Download Folder as ZIP

GET /current/workspace/{workspace_id}/storage/{folder_id}/zip/
GET /current/share/{share_id}/storage/{folder_id}/zip/

Download an entire folder as a streaming ZIP archive.

Auth required. Permission: View (workspace), download permission (share).

Path Parameters

ParameterTypeRequiredDescription
{workspace_id} or {share_id}stringYes20-digit profile ID
{folder_id}stringYesFolder OpaqueId, or "root" for entire storage

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/root/zip/" \
  -H "Authorization: Bearer {jwt_token}" \
  -o workspace.zip

Response: Binary ZIP archive streamed directly with Content-Type and Content-Disposition headers.

Notes:

Recent Files

GET /current/workspace/{workspace_id}/storage/recent/
GET /current/share/{share_id}/storage/recent/

List recently modified nodes across all folders, sorted by updated descending. Unlike list which is scoped to a single folder, this endpoint returns nodes from the entire storage tree.

Auth required. Permission: View (workspace), Guest+ (share). Public shares may allow password-only access.

Query Parameters

ParameterTypeDefaultDescription
page_sizeint100One of: 100, 250, 500 (snapped to nearest)
cursorstringOpaque cursor string from previous response
typestringFilter by node type: file, folder, link, note

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/recent/?type=file&page_size=250" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "nodes": {
    "count": 3,
    "items": [
      {
        "id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4",
        "name": "report.pdf",
        "type": "file",
        "parent": "d1abc-defgh-ijklm-nopqr-stuvw-xyz123",
        "size": 2048576,
        "updated": "2025-02-18T14:30:00Z",
        "created": "2025-02-17T10:00:00Z"
      }
    ]
  },
  "pagination": {
    "has_more": true,
    "next_cursor": "eyJsYXN0X3VwZGF0ZWQiOiIyMDI1LTAyLTE4...",
    "page_size": 100
  }
}

Response Fields

FieldTypeDescription
nodes.countintegerNumber of nodes in this page
nodes.itemsarrayArray of node resources
pagination.has_morebooleanWhether more pages exist
pagination.next_cursorstring/nullCursor for the next page
pagination.page_sizeintegerEffective page size used

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_INPUT_INVALID406Invalid pagination cursor
APP_DENIED401Insufficient permissions to view files (share only)
APP_ERROR_NOT_FOUND404Orphaned workspace folder share

Notes:

GET /current/workspace/{workspace_id}/storage/search/
GET /current/share/{share_id}/storage/search/

Search files by keyword. Uses keyword and semantic search.

Auth required. Permission: View (workspace), search + file view permissions (share).

Query Parameters

ParameterTypeRequiredDescription
searchstringYesSearch query string

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/search/?search=quarterly+report" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "files": {
      "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4": {
        "name": "Q4 Report.pdf",
        "parent_id": "d1abc-defgh-ijklm-nopqr-stuvw-xyz123",
        "type": "file"
      },
      "f6qrs-tuvwx-yz123-abcde-fghij-klmno7": {
        "name": "Quarterly Summary.docx",
        "parent_id": "root",
        "type": "file"
      }
    }
  }
}

Response Fields

FieldTypeDescription
filesobjectMap of node OpaqueIds to file info
files.{id}.namestringFile name
files.{id}.parent_idstringParent folder node ID
files.{id}.typestringNode type

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Search not available for workspace folder shares (share only)
APP_DENIED403No search permission (share only)

Notes:

QuickShare (Workspace Only)

POST /current/workspace/{workspace_id}/storage/{node_id}/quickshare/
GET /current/workspace/{workspace_id}/storage/{node_id}/quickshare/
DELETE /current/workspace/{workspace_id}/storage/{node_id}/quickshare/

Create, retrieve, or delete a temporary public link for a single file.

Auth required. Permission: Member.

Path Parameters

ParameterTypeRequiredDescription
{workspace_id}stringYes20-digit workspace profile ID
{node_id}stringYesFile OpaqueId

POST — Create or Update QuickShare

Request Body (form-encoded)

ParameterTypeRequiredDefaultDescription
expiresstring (digits)NoPlatform defaultExpiration in seconds from now

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/quickshare/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'expires=604800'

Response

{
  "result": "yes",
  "response": {
    "quickshare": {
      "id": "qs_abc123def456",
      "node": {
        "id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4",
        "type": "file",
        "name": "presentation.pdf",
        "size": 5242880,
        "mimetype": "application/pdf"
      },
      "creator_uid": {
        "id": "12345678901234567890",
        "email_address": "john@example.com",
        "first_name": "John",
        "last_name": "Doe"
      },
      "limit_exceeded": false,
      "expires": "2025-01-22 10:30:00",
      "created": "2025-01-15 10:30:00"
    }
  }
}

Error Responses (POST)

Error CodeHTTP StatusDescription
APP_DENIED403File too large for quickshare
APP_ERROR_INPUT_INVALID400Expiration too far in the future

GET — Get QuickShare Details

Returns the same format as POST. Returns APP_ERROR_NOT_FOUND (404) if no quickshare exists.

DELETE — Delete QuickShare

Returns {"result": "yes"}. Returns APP_ERROR_NOT_FOUND (404) if no quickshare exists.

Public Access Endpoints (No Auth Required)

Once a quickshare is created, these endpoints are accessible without authentication:

GET /current/quickshare/{quickshare_id}/details/                                    -- metadata and file info
GET /current/quickshare/{quickshare_id}/storage/read/                               -- download the file
GET /current/quickshare/{quickshare_id}/storage/preview/{preview_type}/read/        -- preview
GET /current/quickshare/{quickshare_id}/storage/preview/{preview_type}/read/file/{filename}  -- preview sub-file

List QuickShares in Workspace

GET /current/workspace/{workspace_id}/storage/quickshares/list/

Returns an array of all active quickshares in the workspace.

Auth required. Permission: Member.

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/quickshares/list/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "quickshares": [
      {
        "id": "qs_abc123def456",
        "node": { "id": "...", "type": "file", "name": "presentation.pdf" },
        "creator_uid": { "id": "...", "email_address": "john@example.com" },
        "limit_exceeded": false,
        "expires": "2025-01-22 10:30:00",
        "created": "2025-01-15 10:30:00"
      }
    ]
  }
}

File Locking

Lock a file to prevent concurrent edits. Locks expire automatically if not renewed via heartbeat. Available on both workspace and share storage.

Acquire Lock

POST /current/workspace/{workspace_id}/storage/{node_id}/lock/
POST /current/share/{share_id}/storage/{node_id}/lock/

Acquire a lock on a file.

Auth required. Permission: Guest (workspace), file modification permission (share).

Request Body (form-encoded)

ParameterTypeRequiredConstraintsDescription
durationintegerNo60-3600 secondsLock duration (default varies)
client_infostringNoJSON objectClient metadata: device_name (max 255), client_version (max 50)

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/lock/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'duration=300' \
  -d 'client_info={"device_name":"My Laptop","client_version":"2.1.0"}'

Response

{
  "result": "yes",
  "response": {
    "lock_token": "unique_lock_token_string",
    "locked_at": "2025-01-28T10:00:00+00:00",
    "expires_at": "2025-01-28T10:05:00+00:00",
    "node_id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4"
  }
}

Response Fields

FieldTypeDescription
lock_tokenstringToken required for heartbeat and release operations
locked_atstringISO 8601 lock acquisition time
expires_atstringISO 8601 lock expiration time
node_idstringOpaqueId of the locked node

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Node does not exist
APP_ERROR_NOT_FOUND404Cannot lock a deleted node
APP_CONFLICT409Node already locked by another user

Heartbeat (Extend Lock)

POST /current/workspace/{workspace_id}/storage/{node_id}/lock/heartbeat/
POST /current/share/{share_id}/storage/{node_id}/lock/heartbeat/

Extend the lock duration.

Auth required.

Request Body (form-encoded)

ParameterTypeRequiredDescription
lock_tokenstringYesToken from acquire response

curl Example

curl -X POST "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/lock/heartbeat/" \
  -H "Authorization: Bearer {jwt_token}" \
  -d 'lock_token=unique_lock_token_string'

Response

{
  "result": "yes",
  "response": {
    "expires_at": "2025-01-28T10:10:00+00:00",
    "time_remaining": 300
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404No lock exists on this node
APP_ERROR_NOT_FOUND404Lock has expired
APP_DENIED403Lock token does not match

Notes:

Release Lock

DELETE /current/workspace/{workspace_id}/storage/{node_id}/lock/
DELETE /current/share/{share_id}/storage/{node_id}/lock/

Release a lock on a file.

Auth required.

Request Body/Query

ParameterTypeRequiredDescription
lock_tokenstringYesToken from acquire response

Response

{
  "result": "yes",
  "response": {
    "released": true
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404No lock exists on this node
APP_DENIED403Lock token does not match

Lock Status

GET /current/workspace/{workspace_id}/storage/{node_id}/lock/
GET /current/share/{share_id}/storage/{node_id}/lock/

Check the lock status of a node.

Auth required.

Response (locked)

{
  "result": "yes",
  "response": {
    "locked": true,
    "locked_at": "2025-01-28T10:00:00+00:00",
    "expires_at": "2025-01-28T10:05:00+00:00",
    "node_id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4",
    "time_remaining": 245,
    "locker_uid": "12345678901234567890"
  }
}

Response (unlocked)

{
  "result": "yes",
  "response": {
    "locked": false
  }
}

Previews

File previews provide rendered views of documents, images, video, and other content without downloading the original file.

Preview Types

ValueDescription
thumbnailSmall thumbnail image
imageFull-size image preview
hlsstreamHLS video/audio stream
pdfPDF document preview
spreadsheetSpreadsheet preview

Preview States

Returned in node details responses under previews.{type}.state:

StateDescription
unknownPreview status not yet determined
not possibleFile type cannot be previewed
not generatedPreview not yet generated
errorPreview generation failed
in progressPreview is being generated
readyPreview is available

Preauthorize Preview

GET /current/workspace/{workspace_id}/storage/{node_id}/preview/{preview_type}/preauthorize/
GET /current/share/{share_id}/storage/{node_id}/preview/{preview_type}/preauthorize/

Get a preview download URL with an embedded token.

Auth required. Permission: View (workspace), file view permission (share).

Path Parameters

ParameterTypeRequiredDescription
{preview_type}stringYesOne of: thumbnail, image, hlsstream, pdf, spreadsheet

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/preview/thumbnail/preauthorize/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "downloadToken": "eyJhbGciOiJIUzI1NiJ9...",
    "path": "/current/workspace/.../preview/thumbnail/read/eyJhbGci.../file/preview.png",
    "primaryFilename": "preview.png"
  }
}

Response Fields

FieldTypeDescription
downloadTokenstringJWT token for preview access
pathstringFull API path to read the preview file
primaryFilenamestringName of the primary preview file

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404File not found
APP_ERROR_INPUT_INVALID400Can only preview file or note
APP_ERROR_NOT_FOUND404File is in trash
APP_RESOURCE_NOT_FOUND404Preview not available

Read Preview

GET /current/workspace/{workspace_id}/storage/{node_id}/preview/{preview_type}/read/
GET /current/share/{share_id}/storage/{node_id}/preview/{preview_type}/read/

Read or redirect to a preview. For single-file previews, streams content directly. For multi-file previews, returns a 307 Temporary Redirect to the file-specific endpoint with a generated token.

Auth required.

Token-Based Preview Read

GET /current/workspace/{workspace_id}/storage/{node_id}/preview/{preview_type}/read/{token}/file/{filename}
GET /current/share/{share_id}/storage/{node_id}/preview/{preview_type}/read/{download_token}/file/{filename}

Read a specific preview file using a token (from preauthorize). Token-based auth — no Authorization header needed.

Path Parameters

ParameterTypeRequiredDescription
{token}stringYesDownload token from preauthorize
{filename}stringYesPreview filename

Transforms

Image transforms allow on-the-fly resizing, cropping, rotating, and format conversion.

Get Transform Status

GET /current/workspace/{workspace_id}/storage/{node_id}/transform/{transform_name}/
GET /current/share/{share_id}/storage/{node_id}/transform/{transform_name}/

Check if a transformation is available without triggering it.

Auth required. Currently the supported {transform_name} is image.

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/transform/image/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "state": "rendered"
  }
}

Transformation States

StateDescription
renderedTransform is ready
renderingTransform in progress
unrenderedTransform not yet requested
unable to renderTransform failed or unsupported

Request Transform

POST /current/workspace/{workspace_id}/storage/{node_id}/transform/{transform_name}/request/
POST /current/share/{share_id}/storage/{node_id}/transform/{transform_name}/request/

Request a transformation. If not yet rendered, triggers the transformation. If already rendered, returns immediately.

Auth required.

Response

{
  "result": "yes",
  "response": {
    "state": "rendered"
  }
}

Error Responses

Error CodeHTTP StatusDescription
APP_ERROR_NOT_FOUND404Unknown transformation name
APP_ERROR_NOT_FOUND404Unable to transform (failed or unsupported)

Read Transformed File

GET /current/workspace/{workspace_id}/storage/{node_id}/transform/{transform_name}/read/
GET /current/share/{share_id}/storage/{node_id}/transform/{transform_name}/read/

Download the transformed file. Supports byte-range requests and token auth.

Auth: JWT or download token.

Image Transform Parameters

Pass as query parameters on transform read endpoints:

ParameterTypeValues
output-formatstringpng, jpg
widthintTarget width in pixels
heightintTarget height in pixels
cropwidthintCrop region width
cropheightintCrop region height
cropxintCrop region X offset
cropyintCrop region Y offset
rotateint0, 90, 180, 270
sizestringPredefined: IconSmall, IconMedium, Preview

curl Example

curl -X GET "https://api.fast.io/current/workspace/12345678901234567890/storage/f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4/transform/image/read/?width=200&height=200&output-format=jpg" \
  -H "Authorization: Bearer {jwt_token}" \
  -o thumbnail.jpg

Request Transform Download Token (Workspace Only)

GET /current/workspace/{workspace_id}/storage/{node_id}/transform/{transform_name}/requestread/

Get a temporary download token for the transformed file.

Auth required.

Response

{
  "result": "yes",
  "response": {
    "token": "eyJhbGciOiJIUzI1NiJ9..."
  }
}

Download Tokens Pattern

The requestread endpoint generates temporary, auth-free download tokens for files, previews, and transforms.

Flow:

  1. GET .../storage/{node_id}/requestread/ — returns {"token": "..."}
  2. GET .../storage/{node_id}/read/?token={token} — download without Authorization header

Useful for opening files in browser tabs or embedding in pages without exposing auth headers.

Workspace-Only Features

These endpoints are only available on workspaces, not shares:

Share-Specific Notes

↑ Back to top