Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Files

File CRUD plus versioning, copy, move, and restore. Every file lives inside a share and (optionally) inside a folder.

Base path: /api/v1/files/

File metadata shape#

json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "id": "fil_01J3K",
  "name": "spec.pdf",
  "share_id": "shr_01J3H",
  "folder_id": "fld_01J3I",
  "path": "/Engineering/spec.pdf",
  "mime_type": "application/pdf",
  "size": 48293,
  "checksum_sha256": "a9f2...",
  "version": 4,
  "owner_id": "usr_01J3N",
  "created_by": "usr_01J3N",
  "created_at": "2026-04-20T10:00:00Z",
  "modified_at": "2026-04-23T10:15:00Z",
  "modified_by": "usr_01J3N"
}

Get file metadata#

bash
1
2
curl -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
     $SCAIDRIVE_URL/api/v1/files/fil_01J3K
python
1
2
3
4
5
resp = httpx.get(
    f"{url}/api/v1/files/fil_01J3K",
    headers={"Authorization": f"Bearer {token}"},
)
meta = resp.json()
typescript
1
2
3
4
const resp = await fetch(`${url}/api/v1/files/fil_01J3K`, {
  headers: { Authorization: `Bearer ${token}` },
});
const meta = await resp.json();

Requires READ on the file.

Download file content#

bash
1
2
3
curl -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
     -o spec.pdf \
     $SCAIDRIVE_URL/api/v1/files/fil_01J3K/content
python
1
2
3
4
5
with httpx.stream("GET", f"{url}/api/v1/files/fil_01J3K/content",
                  headers={"Authorization": f"Bearer {token}"}) as r:
    with open("spec.pdf", "wb") as out:
        for chunk in r.iter_bytes():
            out.write(chunk)
typescript
1
2
3
4
5
const resp = await fetch(`${url}/api/v1/files/fil_01J3K/content`, {
  headers: { Authorization: `Bearer ${token}` },
});
const buf = Buffer.from(await resp.arrayBuffer());
writeFileSync("spec.pdf", buf);

Query parameter ?version=N downloads a specific version. Without it, you get the current version.

Response headers:

  • Content-Length — full file size
  • Content-Disposition: attachment; filename="..." — original filename
  • Accept-Ranges: bytes — range requests supported

For large files, use Range: bytes=0-999 to fetch a byte range. The server responds with 206 Partial Content.

Upload a file#

bash
1
2
3
4
5
curl -X POST $SCAIDRIVE_URL/api/v1/files \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
  -F "share_id=shr_01J3H" \
  -F "folder_id=fld_01J3I" \
  -F "file=@./spec.pdf"
python
1
2
3
4
5
6
7
with open("spec.pdf", "rb") as f:
    resp = httpx.post(
        f"{url}/api/v1/files",
        headers={"Authorization": f"Bearer {token}"},
        data={"share_id": "shr_01J3H", "folder_id": "fld_01J3I"},
        files={"file": ("spec.pdf", f, "application/pdf")},
    )
typescript
1
2
3
4
5
6
7
8
9
const form = new FormData();
form.append("share_id", "shr_01J3H");
form.append("folder_id", "fld_01J3I");
form.append("file", new Blob([readFileSync("spec.pdf")]), "spec.pdf");
const resp = await fetch(`${url}/api/v1/files`, {
  method: "POST",
  headers: { Authorization: `Bearer ${token}` },
  body: form,
});

Multipart fields:

Field Required Notes
share_id Yes Destination share
folder_id No Destination folder; omit for share root
name No Override the filename
file Yes File content

Requires CREATE on the destination folder (or on the share, if uploading to the root).

If a file with the same name exists at the destination, the server returns 409 NAME_CONFLICT. To update instead, use the update flow (upload to an existing file via the resumable upload protocol with replace_file_id — see Resumable Uploads) or rename first.

For files over 100 MB, use the resumable upload protocol. The multipart endpoint has a hard limit (default 5 GB, tenant-configurable).

Update file metadata#

Rename, move, or update attributes:

bash
1
2
3
4
curl -X PATCH $SCAIDRIVE_URL/api/v1/files/fil_01J3K \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "spec-final.pdf"}'

Requires WRITE on the file. Renaming a file records a renamed change in the change log.

Delete a file#

Soft delete (default):

bash
1
2
curl -X DELETE $SCAIDRIVE_URL/api/v1/files/fil_01J3K \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN"

Permanent delete:

bash
1
2
curl -X DELETE "$SCAIDRIVE_URL/api/v1/files/fil_01J3K?permanent=true" \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN"

Requires DELETE on the file. Soft-deleted files can be restored (via the same PATCH endpoint with a restore flag) for as long as the tenant's trash retention allows.

Legal Hold and Retention policies may block deletion — see Enterprise Compliance.

Copy a file#

bash
1
2
3
4
5
6
7
curl -X POST $SCAIDRIVE_URL/api/v1/files/fil_01J3K/copy \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "target_folder_id": "fld_01J4A",
    "new_name": "spec-copy.pdf"
  }'

Either target_folder_id (same share) or target_share_id (across shares) must be set.

Requires READ on the source and CREATE on the target. Cross-share copies respect deduplication — the copied file's chunks are shared with the original, not duplicated.

Move a file#

bash
1
2
3
4
curl -X POST $SCAIDRIVE_URL/api/v1/files/fil_01J3K/move \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"target_folder_id": "fld_01J4B"}'

Requires DELETE on the source and CREATE on the target. The file keeps its ID; version history is preserved.

List file versions#

bash
1
2
curl -H "Authorization: Bearer $SCAIDRIVE_TOKEN" \
     $SCAIDRIVE_URL/api/v1/files/fil_01J3K/versions

See Versioning and Deduplication for the versions response shape.

Restore a previous version#

bash
1
2
curl -X POST $SCAIDRIVE_URL/api/v1/files/fil_01J3K/versions/2/restore \
  -H "Authorization: Bearer $SCAIDRIVE_TOKEN"

Creates a new version (e.g., version 5) with the content of version 2. Requires WRITE.

Error cases#

Code When
NOT_FOUND File doesn't exist or caller can't see it
AUTHZ_PERMISSION_DENIED Missing required permission
NAME_CONFLICT Destination already has a file with this name
PAYLOAD_TOO_LARGE Upload exceeds tenant's max file size
QUOTA_EXCEEDED Share, user, or tenant quota would be exceeded
RESOURCE_DELETED File was soft-deleted; restore before reuse

See Errors for the full error vocabulary.

What's next#

  • Folders — folder CRUD and hierarchical queries.
  • Uploads and Downloads — resumable uploads and range downloads.
  • Sync — pulling file changes across devices.
Updated 2026-05-18 15:04:13 View source (.md) rev 2