API Overview

The CloudSync API is organized around REST. It accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Base URL for all API requests:

https://api.cloudsync.io/v2

All API requests must be made over HTTPS. Requests made over HTTP will be redirected to HTTPS. API requests without authentication will fail with a 401 Unauthorized response.

Authentication

The CloudSync API uses OAuth 2.0 Bearer tokens for authentication. Include your access token in the Authorization header:

GET /v2/files HTTP/1.1
Host: api.cloudsync.io
Authorization: Bearer cs_live_a1b2c3d4e5f6...
Content-Type: application/json

Access tokens can be generated from your Dashboard → Settings → API Keys. Two types are available:

Token TypePrefixScope
Livecs_live_Full access to production data
Testcs_test_Sandbox environment only

Rate Limits

The API enforces rate limits per access token to ensure fair usage:

PlanRequests/minBurst
Free6010
Pro600100
Business3,000500
EnterpriseCustomCustom

Rate limit headers are included in every response:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 594
X-RateLimit-Reset: 1783465200

Error Handling

CloudSync uses conventional HTTP status codes. Codes in the 2xx range indicate success, 4xx indicate client errors, and 5xx indicate server errors.

{
  "error": {
    "code": "file_not_found",
    "message": "The requested file does not exist or has been deleted.",
    "request_id": "req_7f3a8b2c"
  }
}

List Files

GET /v2/files

Returns a paginated list of files in the authenticated user's cloud storage. Supports filtering by folder, type, and modification date.

ParameterTypeDescription
folder_idstringFilter by parent folder. Default: root folder.
limitintegerMax results per page (1–100). Default: 50.
cursorstringPagination cursor from previous response.
modified_afterISO 8601Filter files modified after this timestamp.
# Example: list files in root folder
curl -H "Authorization: Bearer cs_live_..." \
  https://api.cloudsync.io/v2/files?limit=10

Response:

{
  "data": [
    {
      "id": "file_9x8y7z",
      "name": "report_Q2.xlsx",
      "size": 284672,
      "mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      "modified_at": "2026-07-05T14:22:00Z",
      "checksum_sha256": "a3f2b8c1...",
      "version": 12
    }
  ],
  "has_more": true,
  "cursor": "eyJsYXN0X2lkIjoiZmlsZV85eDh5N3oifQ=="
}

Upload File

POST /v2/files/upload

Upload a new file or update an existing one. Files up to 5 GB are supported via multipart upload. For files over 150 MB, use the chunked upload endpoint (set X-Upload-Mode: chunked).

# Upload a file to a specific folder
curl -X POST \
  -H "Authorization: Bearer cs_live_..." \
  -F "file=@report_Q2.xlsx" \
  -F "folder_id=folder_abc123" \
  -F "conflict_mode=auto_rename" \
  https://api.cloudsync.io/v2/files/upload

Download File

GET /v2/files/{file_id}/content

Download the decrypted content of a file. The response is the raw file bytes with appropriate Content-Type and Content-Disposition headers. For encrypted downloads (zero-knowledge mode), pass ?encrypted=true to receive the AES-256-GCM ciphertext.

# Download a file
curl -H "Authorization: Bearer cs_live_..." \
  -o report.xlsx \
  https://api.cloudsync.io/v2/files/file_9x8y7z/content

Delete File

DELETE /v2/files/{file_id}

Move a file to trash. Trashed files are permanently deleted after 30 days (configurable for Business/Enterprise). Pass ?permanent=true to skip trash (irreversible).

{
  "id": "file_9x8y7z",
  "deleted": true,
  "permanent_deletion_at": "2026-08-06T14:22:00Z"
}

File Versions

GET /v2/files/{file_id}/versions

List all stored versions of a file. Free plans retain 30 days of history, Pro 180 days, Business/Enterprise unlimited. Each version includes a delta size and the actor who made the change.

{
  "data": [
    {
      "version": 12,
      "size": 284672,
      "delta_size": 12288,
      "modified_at": "2026-07-05T14:22:00Z",
      "actor": "user_jane",
      "checksum_sha256": "a3f2b8c1d0e9..."
    },
    {
      "version": 11,
      "size": 272384,
      "delta_size": 2150,
      "modified_at": "2026-07-05T11:05:00Z",
      "actor": "user_marcus",
      "checksum_sha256": "f7e6d5c4b3a2..."
    }
  ],
  "has_more": true,
  "cursor": "dmVyXzEx"
}

To restore a previous version:

POST /v2/files/{file_id}/versions/{version}/restore


Sync Status

GET /v2/sync/status

Returns the current sync status for the authenticated device. The desktop agent calls this endpoint every 60 seconds to check for pending changes.

{
  "status": "up_to_date",
  "pending_uploads": 0,
  "pending_downloads": 2,
  "last_sync": "2026-07-05T14:22:00Z",
  "device_id": "dev_m1pro_work",
  "storage_used": 45846528000,
  "storage_limit": 107374182400
}

Sync Events (Long Polling)

GET /v2/sync/events

Subscribe to real-time file change events. The connection is held open for up to 90 seconds. When a change is detected, the server responds immediately with the event data. This is how the desktop agent maintains real-time sync without constant polling.

{
  "events": [
    {
      "type": "file.modified",
      "file_id": "file_9x8y7z",
      "timestamp": "2026-07-05T14:22:01Z",
      "actor": "user_marcus",
      "delta_size": 12288
    }
  ],
  "cursor": "evt_a1b2c3"
}

Delta Sync

POST /v2/sync/delta

Request a delta manifest for efficient synchronization. Instead of downloading entire files, the agent receives a list of changed blocks (4 KB granularity) and fetches only those. Reduces bandwidth by up to 95% for large files with small edits.

curl -X POST \
  -H "Authorization: Bearer cs_live_..." \
  -H "Content-Type: application/json" \
  -d '{"file_id": "file_9x8y7z", "local_checksum": "a3f2b8c1...", "local_version": 11}' \
  https://api.cloudsync.io/v2/sync/delta
{
  "file_id": "file_9x8y7z",
  "remote_version": 12,
  "blocks_changed": 3,
  "blocks_total": 69,
  "delta_size": 12288,
  "full_size": 284672,
  "download_url": "/v2/sync/delta/file_9x8y7z/patch?v=12"
}

Share Folder

POST /v2/shares

Share a folder with other users. The invited user receives an email notification and can accept or decline. Folder sharing inherits to all subfolders and files.

curl -X POST \
  -H "Authorization: Bearer cs_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "folder_id": "folder_abc123",
    "invitee_email": "marcus@company.com",
    "role": "editor",
    "message": "Here are the Q2 reports"
  }' \
  https://api.cloudsync.io/v2/shares

Permissions

PATCH /v2/shares/{share_id}/permissions

Update permissions for an existing share. Available roles:

RoleViewEditDeleteShareManage
viewer
editor
manager
owner

POST /v2/links

Generate a shareable link for a file or folder. Links can be password-protected, set to expire, and limited to specific download counts.

curl -X POST \
  -H "Authorization: Bearer cs_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "file_id": "file_9x8y7z",
    "password": "optional-password",
    "expires_at": "2026-07-14T00:00:00Z",
    "max_downloads": 10
  }' \
  https://api.cloudsync.io/v2/links
{
  "id": "link_x7y8z9",
  "url": "https://share.cloudsync.io/s/x7y8z9",
  "password_protected": true,
  "expires_at": "2026-07-14T00:00:00Z",
  "downloads_remaining": 10
}

Webhooks

POST /v2/webhooks

Register a webhook endpoint to receive real-time notifications when files are created, modified, deleted, or shared.

curl -X POST \
  -H "Authorization: Bearer cs_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/cloudsync",
    "events": ["file.created", "file.modified", "file.deleted"],
    "secret": "whsec_your_signing_secret"
  }' \
  https://api.cloudsync.io/v2/webhooks

Webhook Event Types

EventDescription
file.createdNew file uploaded or synced
file.modifiedExisting file content changed
file.deletedFile moved to trash
file.restoredFile restored from version history
folder.createdNew folder created
share.createdFolder shared with another user
share.revokedSharing permissions removed
sync.conflictSync conflict detected between devices

Python SDK

Install the official Python SDK:

$ pip install cloudsync-sdk
import cloudsync

client = cloudsync.Client("cs_live_a1b2c3d4...")

# List files
files = client.files.list(folder_id="root", limit=20)
for f in files:
    print(f"{f.name} ({f.size} bytes)")

# Upload
result = client.files.upload(
    path="/home/user/report.pdf",
    folder_id="folder_abc123"
)

# Subscribe to events
for event in client.sync.stream():
    print(f"[{event.type}] {event.file_id}")

Node.js SDK

$ npm install @cloudsync/sdk
const { CloudSync } = require('@cloudsync/sdk');

const client = new CloudSync('cs_live_a1b2c3d4...');

// List files
const files = await client.files.list({ limit: 20 });
files.data.forEach(f => console.log(f.name));

// Watch for changes
client.sync.on('file.modified', (event) => {
  console.log(`File changed: ${event.file_id}`);
});

Go SDK

$ go get github.com/cloudsync/cloudsync-go
package main

import (
    "fmt"
    cs "github.com/cloudsync/cloudsync-go"
)

func main() {
    client := cs.NewClient("cs_live_a1b2c3d4...")

    // List files
    files, _ := client.Files.List(cs.ListParams{Limit: 20})
    for _, f := range files.Data {
        fmt.Printf("%s (%d bytes)\n", f.Name, f.Size)
    }

    // Upload
    result, _ := client.Files.Upload("./report.pdf", "folder_abc123")
    fmt.Println("Uploaded:", result.ID)
}

Java SDK

<!-- Maven -->
<dependency>
    <groupId>io.cloudsync</groupId>
    <artifactId>cloudsync-java</artifactId>
    <version>2.4.0</version>
</dependency>
import io.cloudsync.CloudSyncClient;
import io.cloudsync.model.FileList;

public class Example {
    public static void main(String[] args) {
        CloudSyncClient client = new CloudSyncClient("cs_live_a1b2c3d4...");

        // List files
        FileList files = client.files().list(20);
        files.forEach(f ->
            System.out.println(f.getName() + " (" + f.getSize() + " bytes)"));

        // Upload
        var result = client.files().upload(Path.of("report.pdf"), "folder_abc123");
        System.out.println("Uploaded: " + result.getId());
    }
}